[PATCH] nfc: rawsock: prevent TX work requeue after socket shutdown

From: Yaohan Li

Date: Wed Nov 04 2026 - 04:57:09 EST


rawsock_release() marks the socket for shutdown and cancels tx_work,
but a delayed data-exchange completion can still queue tx_work again
before the socket is finally freed. The new worker can then access
freed socket state.

Check SEND_SHUTDOWN under the write-queue lock before requeueing
transmit work in rawsock_data_exchange_complete(). Allow the completion
to clear the scheduling state without scheduling new work after the
release path has begun.

A KASAN test with a deferred NFC completion callback reproduced the
use-after-free on the unmodified kernel. The same injection-assisted
sequence completed without a report after the change.

Fixes: 23b7869c0fd08 ("NFC: add the NFC socket raw protocol")
Assisted-by: ZCode:GLM-4
Signed-off-by: Yaohan Li <shunsheng1218@xxxxxxxxx>
---
net/nfc/rawsock.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/net/nfc/rawsock.c b/net/nfc/rawsock.c
index f7d7a599fade7..efdbd512d4600 100644
--- a/net/nfc/rawsock.c
+++ b/net/nfc/rawsock.c
@@ -168,7 +168,13 @@ static void rawsock_data_exchange_complete(void *context, struct sk_buff *skb,
goto error_skb;

spin_lock_bh(&sk->sk_write_queue.lock);
- if (!skb_queue_empty(&sk->sk_write_queue))
+ /*
+ * The release path sets SEND_SHUTDOWN before cancel_work_sync():
+ * once it is set, do not requeue tx_work - the socket may be freed
+ * right after the cancel returns.
+ */
+ if (!skb_queue_empty(&sk->sk_write_queue) &&
+ !(sk->sk_shutdown & SEND_SHUTDOWN))
schedule_work(&nfc_rawsock(sk)->tx_work);
else
nfc_rawsock(sk)->tx_work_scheduled = false;
--
2.34.1