PT-2026-30145 · Linux · Linux
Published
2026-04-03
·
Updated
2026-04-03
·
CVE-2026-23450
None
No severity ratings or metrics are available. When they are, we'll update the corresponding info on the page.
In the Linux kernel, the following vulnerability has been resolved:
net/smc: fix NULL dereference and UAF in smc tcp syn recv sock()
Syzkaller reported a panic in smc tcp syn recv sock() [1].
smc tcp syn recv sock() is called in the TCP receive path
(softirq) via icsk af ops->syn recv sock on the clcsock (TCP
listening socket). It reads sk user data to get the smc sock
pointer. However, when the SMC listen socket is being closed
concurrently, smc close active() sets clcsock->sk user data
to NULL under sk callback lock, and then the smc sock itself
can be freed via sock put() in smc release().
This leads to two issues:
- NULL pointer dereference: sk user data is NULL when accessed.
- Use-after-free: sk user data is read as non-NULL, but the smc sock is freed before its fields (e.g., queued smc hs, ori af ops) are accessed.
The race window looks like this (the syzkaller crash [1]
triggers via the SYN cookie path: tcp get cookie sock() ->
smc tcp syn recv sock(), but the normal tcp check req() path
has the same race):
CPU A (softirq) CPU B (process ctx)
tcp v4 rcv()
TCP NEW SYN RECV:
sk = req->rsk listener
sock hold(sk)
/* No lock on listener */
smc close active():
write lock bh(cb lock)
sk user data = NULL
write unlock bh(cb lock)
...
smc clcsock release()
sock put(smc->sk) x2
-> smc sock freed!
tcp check req()
smc tcp syn recv sock():
smc = user data(sk)
-> NULL or dangling
smc->queued smc hs
-> crash!
Note that the clcsock and smc sock are two independent objects
with separate refcounts. TCP stack holds a reference on the
clcsock, which keeps it alive, but this does NOT prevent the
smc sock from being freed.
Fix this by using RCU and refcount inc not zero() to safely
access smc sock. Since smc tcp syn recv sock() is called in
the TCP three-way handshake path, taking read lock bh on
sk callback lock is too heavy and would not survive a SYN
flood attack. Using rcu read lock() is much more lightweight.
- Set SOCK RCU FREE on the SMC listen socket so that smc sock freeing is deferred until after the RCU grace period. This guarantees the memory is still valid when accessed inside rcu read lock().
- Use rcu read lock() to protect reading sk user data.
- Use refcount inc not zero(&smc->sk.sk refcnt) to pin the smc sock. If the refcount has already reached zero (close path completed), it returns false and we bail out safely.
Note: smc hs congested() has a similar lockless read of
sk user data without rcu read lock(), but it only checks for
NULL and accesses the global smc hs wq, never dereferencing
any smc sock field, so it is not affected.
Reproducer was verified with mdelay injection and smc run,
the issue no longer occurs with this patch applied.
Found an issue in the description? Have something to add? Feel free to write us 👾
Related Identifiers
Affected Products
Linux