Skip to content

Commit d793458

Browse files
committed
nfc: rawsock: cancel tx_work before socket teardown
In rawsock_release(), cancel any pending tx_work and purge the write queue before orphaning the socket. rawsock_tx_work runs on the system workqueue and calls nfc_data_exchange which dereferences the NCI device. Without synchronization, tx_work can race with socket and device teardown when a process is killed (e.g. by SIGKILL), leading to use-after-free or leaked references. Set SEND_SHUTDOWN first so that if tx_work is already running it will see the flag and skip transmitting, then use cancel_work_sync to wait for any in-progress execution to finish, and finally purge any remaining queued skbs. Fixes: 23b7869 ("NFC: add the NFC socket raw protocol") Reviewed-by: Joe Damato <joe@dama.to> Link: https://patch.msgid.link/20260303162346.2071888-6-kuba@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 0efdc02 commit d793458

1 file changed

Lines changed: 11 additions & 0 deletions

File tree

net/nfc/rawsock.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,17 @@ static int rawsock_release(struct socket *sock)
6767
if (sock->type == SOCK_RAW)
6868
nfc_sock_unlink(&raw_sk_list, sk);
6969

70+
if (sk->sk_state == TCP_ESTABLISHED) {
71+
/* Prevent rawsock_tx_work from starting new transmits and
72+
* wait for any in-progress work to finish. This must happen
73+
* before the socket is orphaned to avoid a race where
74+
* rawsock_tx_work runs after the NCI device has been freed.
75+
*/
76+
sk->sk_shutdown |= SEND_SHUTDOWN;
77+
cancel_work_sync(&nfc_rawsock(sk)->tx_work);
78+
rawsock_write_queue_purge(sk);
79+
}
80+
7081
sock_orphan(sk);
7182
sock_put(sk);
7283

0 commit comments

Comments
 (0)