mirror of
https://github.com/torvalds/linux.git
synced 2026-03-08 01:24:47 +01:00
nfc: nci: free skb on nci_transceive early error paths
nci_transceive() takes ownership of the skb passed by the caller,
but the -EPROTO, -EINVAL, and -EBUSY error paths return without
freeing it.
Due to issues clearing NCI_DATA_EXCHANGE fixed by subsequent changes
the nci/nci_dev selftest hits the error path occasionally in NIPA,
and kmemleak detects leaks:
unreferenced object 0xff11000015ce6a40 (size 640):
comm "nci_dev", pid 3954, jiffies 4295441246
hex dump (first 32 bytes):
6b 6b 6b 6b 00 a4 00 0c 02 e1 03 6b 6b 6b 6b 6b kkkk.......kkkkk
6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
backtrace (crc 7c40cc2a):
kmem_cache_alloc_node_noprof+0x492/0x630
__alloc_skb+0x11e/0x5f0
alloc_skb_with_frags+0xc6/0x8f0
sock_alloc_send_pskb+0x326/0x3f0
nfc_alloc_send_skb+0x94/0x1d0
rawsock_sendmsg+0x162/0x4c0
do_syscall_64+0x117/0xfc0
Fixes: 6a2968aaf5 ("NFC: basic NCI protocol implementation")
Reviewed-by: Joe Damato <joe@dama.to>
Link: https://patch.msgid.link/20260303162346.2071888-2-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
40bf00ec2e
commit
7bd4b0c477
1 changed files with 7 additions and 2 deletions
|
|
@ -1035,18 +1035,23 @@ static int nci_transceive(struct nfc_dev *nfc_dev, struct nfc_target *target,
|
|||
struct nci_conn_info *conn_info;
|
||||
|
||||
conn_info = ndev->rf_conn_info;
|
||||
if (!conn_info)
|
||||
if (!conn_info) {
|
||||
kfree_skb(skb);
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
pr_debug("target_idx %d, len %d\n", target->idx, skb->len);
|
||||
|
||||
if (!ndev->target_active_prot) {
|
||||
pr_err("unable to exchange data, no active target\n");
|
||||
kfree_skb(skb);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (test_and_set_bit(NCI_DATA_EXCHANGE, &ndev->flags))
|
||||
if (test_and_set_bit(NCI_DATA_EXCHANGE, &ndev->flags)) {
|
||||
kfree_skb(skb);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
/* store cb and context to be used on receiving data */
|
||||
conn_info->data_exchange_cb = cb;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue