linux/net/smc
Sidraya Jayagond 185a4caeec net/smc: fix TOCTOU race between smc_listen_out() and listener close
smc_listen_out() reads lsmc->sk.sk_state without the listener lock,
then acquires lock_sock_nested() only after the check passes. This
opens a window where smc_close_active() can transition the listener
to SMC_CLOSED, call smc_close_cleanup_listen() to drain the accept
queue, and release the lock, all between the lockless read and the
delayed lock acquisition:

  smc_listen_work (smc_hs_wq)          smc_close_active()
  -------------------------------      -------------------------
  release_sock(child)
  if (sk_state == SMC_LISTEN) TRUE
                                        lock_sock(listener)
                                        sk_state = SMC_CLOSED
                                        smc_close_cleanup_listen()
                                        release_sock(listener)
                                        flush_work(tcp_listen_work)
  lock_sock_nested(listener)
  smc_accept_enqueue(listener, child) /* child enqueued on dead listener */

smc_close_active() flushes only tcp_listen_work. Work items already
dispatched onto smc_hs_wq for the CLC handshake continue running
unguarded. smc_accept_enqueue() takes a sock_hold() on the child that
is never released, so the child smc_sock, its clcsock, and the
reference all leak. A remote peer that opens TCP connections while the
server calls close() can exhaust kernel memory.

Move lock_sock_nested() to before the sk_state check so that the test
and the enqueue are atomic under the listener lock.

Fixes: fd57770dd1 ("net/smc: wait for pending work before clcsock release_sock")
Reviewed-by: Mahanta Jambigi <mjambigi@linux.ibm.com>
Signed-off-by: Sidraya Jayagond <sidraya@linux.ibm.com>
Reviewed-by: Breno Leitao <leitao@debian.org>
Reviewed-by: Dust Li <dust.li@linux.alibaba.com>
Link: https://patch.msgid.link/20260803070701.126339-1-sidraya@linux.ibm.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-08-06 13:35:41 +02:00
..
af_smc.c net/smc: fix TOCTOU race between smc_listen_out() and listener close 2026-08-06 13:35:41 +02:00
Kconfig net: smc: SMC_HS_CTRL_BPF should depend on BPF_JIT 2025-12-04 11:07:18 -08:00
Makefile net/smc: bpf: Introduce generic hook for handshake flow 2025-11-10 11:19:41 -08:00
smc_cdc.c net/smc: fix UAF in smc_cdc_rx_handler() by pinning the socket 2026-07-06 12:58:12 +02:00
smc_cdc.h net/smc: fix kernel panic caused by race of smc_sock 2021-12-28 12:42:45 +00:00
smc_clc.c net/smc: avoid early lgr access in smc_clc_wait_msg 2026-04-23 11:00:57 -07:00
smc_clc.h net/smc: check smcd_v2_ext_offset when receiving proposal msg 2024-12-15 12:34:59 +00:00
smc_close.c net/smc: fix NULL dereference and UAF in smc_tcp_syn_recv_sock() 2026-03-16 19:31:28 -07:00
smc_close.h
smc_core.c net/smc: fix socket use-after-free during link group termination 2026-07-28 11:22:43 +02:00
smc_core.h net/smc: handle -ENOMEM from smc_wr_alloc_link_mem gracefully 2025-10-30 13:31:43 +01:00
smc_diag.c dibs: Local gid for dibs devices 2025-09-23 11:13:22 +02:00
smc_hs_bpf.c net/smc: bpf: Introduce generic hook for handshake flow 2025-11-10 11:19:41 -08:00
smc_hs_bpf.h net/smc: bpf: Introduce generic hook for handshake flow 2025-11-10 11:19:41 -08:00
smc_ib.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
smc_ib.h net/smc: fix smc clc failed issue when netdevice not in init_net 2023-10-13 16:52:02 -07:00
smc_inet.c net/smc: fix general protection fault in __smc_diag_dump 2025-10-20 17:46:06 -07:00
smc_inet.h net/smc: Introduce IPPROTO_SMC 2024-06-17 13:14:09 +01:00
smc_ism.c smc: Use flexible array for SMCD connections 2026-05-20 17:13:18 -07:00
smc_ism.h dibs: Move data path to dibs layer 2025-09-23 11:13:22 +02:00
smc_llc.c net/smc: fix qentry overwrite for CONFIRM_LINK and ADD_LINK_CONT in smc_llc_event_handler() 2026-07-31 16:29:17 -07:00
smc_llc.h net/smc: Introduce a specific sysctl for TEST_LINK time 2022-09-22 12:58:21 +02:00
smc_netlink.c genetlink: start to validate reserved header bytes 2022-08-29 12:47:15 +01:00
smc_netlink.h
smc_netns.h
smc_pnet.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
smc_pnet.h net/smc: Use a mutex for locking "struct smc_pnettable" 2022-02-24 09:09:33 -08:00
smc_rx.c net: smc: fix splice entry lifetime imbalance in smc_rx_splice 2026-08-03 18:27:51 -07:00
smc_rx.h net/smc: fix data error when recvmsg with MSG_PEEK flag 2025-01-13 18:59:00 -08:00
smc_stats.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
smc_stats.h net/smc: introduce statistics for ringbufs usage of net namespace 2024-08-20 11:38:23 +02:00
smc_sysctl.c net/smc: bpf: Introduce generic hook for handshake flow 2025-11-10 11:19:41 -08:00
smc_sysctl.h net/smc: make wr buffer count configurable 2025-10-30 13:31:43 +01:00
smc_tracepoint.c net/smc: Introduce tracepoint for smcr link down 2021-11-01 13:39:14 +00:00
smc_tracepoint.h net/smc: avoid NULL deref of conn->lnk in smc_msg_event tracepoint 2026-05-12 18:44:36 -07:00
smc_tx.c net/smc: Decouple sf and attached send_buf in smc_loopback 2025-09-23 11:13:21 +02:00
smc_tx.h smc: Drop smc_sendpage() in favour of smc_sendmsg() + MSG_SPLICE_PAGES 2023-06-24 15:50:12 -07:00
smc_wr.c Convert remaining multi-line kmalloc_obj/flex GFP_KERNEL uses 2026-02-22 08:26:33 -08:00
smc_wr.h net/smc: make wr buffer count configurable 2025-10-30 13:31:43 +01:00
smc.h net/smc: fix NULL dereference and UAF in smc_tcp_syn_recv_sock() 2026-03-16 19:31:28 -07:00