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:
  1. NULL pointer dereference: sk user data is NULL when accessed.
  2. 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.

Related Identifiers

CVE-2026-23450

Affected Products

Linux