RE: [PATCH net v2 1/1] tipc: avoid use-after-free in poll trace queue dumps
From: Tung Quang Nguyen <hidden>
Date: 2026-07-23 04:48:33
quoted hunk ↗ jump to hunk
Subject: [PATCH net v2 1/1] tipc: avoid use-after-free in poll trace queue dumps From: Zihan Xi <redacted> TIPC socket tracepoints dump queue state through tipc_sk_dump(). Most queue-dump callsites already serialize that walk under the socket lock or sk->sk_lock.slock, but tipc_poll() calls trace_tipc_sk_poll(..., TIPC_DUMP_ALL, ...) without holding either lock. That lets the poll trace path reach tipc_list_dump() and backlog head/tail dumping while another context dequeues and frees an skb, leaving the trace helper dereferencing a stale queue entry. Keep the existing trace output, but serialize the poll trace snapshot with the socket lock. Gate the locking on trace_tipc_sk_poll_enabled() so the hot poll path does not take the lock when the tracepoint is disabled. Fixes: b4b9771bcbbd ("tipc: enable tracepoints in tipc") Cc: stable@vger.kernel.org Reported-by: Vega <redacted> Assisted-by: Codex:gpt-5.4 Signed-off-by: Zihan Xi <redacted> Signed-off-by: Ren Wei <redacted> --- changes in v2: - Keep the existing queue and backlog trace output intact. - Serialize the poll trace snapshot under the socket lock. - Gate the new locking on trace_tipc_sk_poll_enabled(). - v1 Link: https://lore.kernel.org/all/24f7311aed0c9ff06b8ea982647b82bf543ec369.1784 454542.git.xizh2024@lzu.edu.cn/ net/tipc/socket.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)diff --git a/net/tipc/socket.c b/net/tipc/socket.c indexe564341e0216..51692c4a0e47 100644--- a/net/tipc/socket.c +++ b/net/tipc/socket.c@@ -794,8 +794,14 @@ static __poll_t tipc_poll(struct file *file, struct socket*sock, struct tipc_sock *tsk = tipc_sk(sk); __poll_t revents = 0; + bool slow; + sock_poll_wait(file, sock, wait); - trace_tipc_sk_poll(sk, NULL, TIPC_DUMP_ALL, " "); + if (trace_tipc_sk_poll_enabled()) { + slow = lock_sock_fast(sk); + trace_tipc_sk_poll(sk, NULL, TIPC_DUMP_ALL, " "); + unlock_sock_fast(sk, slow); + }
No lock should be held in tipc_poll() even only if trace event is enabled because it affects performance. See below throughput regression after applying your patch. trace event is enabled: node1 ~ # client_bench -c 50 -p tipc -t -n Before patch: +------------------------------------------------------------------------------------------------------------------------+ | Msg Size | # | # Msgs/ | Elapsed | Throughput | | [octets] | Conns | Conn | [ms] +---------------------------------------------------------------+ | | | | | Total [Msg/s] | Total [Mb/s] | Per Conn [Mb/s] | +-----------------------------------------------------------------------------------------------------------------------+ | 64 | 50 | 64000 | 5654 | 565899 | 289 | 5 | +-----------------------------------------------------------------------------------------------------------------------+ | 256 | 50 | 32000 | 3010 | 531423 | 1088 | 21 | +-----------------------------------------------------------------------------------------------------------------------+ | 1024 | 50 | 16000 | 1974 | 405193 | 3319 | 66 | +-----------------------------------------------------------------------------------------------------------------------+ | 4096 | 50 | 8000 | 1366 | 292728 | 9592 | 191 | +-----------------------------------------------------------------------------------------------------------------------+ | 16384 | 50 | 4000 | 2166 | 92321 | 12100 | 242 | +-----------------------------------------------------------------------------------------------------------------------+ | 65536 | 50 | 2000 | 4765 | 20984 | 11001 | 220 | +-----------------------------------------------------------------------------------------------------------------------+ After patch: +------------------------------------------------------------------------------------------------------------------------+ | Msg Size | # | # Msgs/ | Elapsed | Throughput | | [octets] | Conns | Conn | [ms] +---------------------------------------------------------------+ | | | | | Total [Msg/s] | Total [Mb/s] | Per Conn [Mb/s] | +------------------------------------------------------------------------------------------------------------------------+ | 64 | 50 | 64000 | 5711 | 560231 | 286 | 5 | +-----------------------------------------------------------------------------------------------------------------------+ | 256 | 50 | 32000 | 3046 | 525207 | 1075 | 21 | +-----------------------------------------------------------------------------------------------------------------------+ | 1024 | 50 | 16000 | 2209 | 362152 | 2966 | 59 | +-----------------------------------------------------------------------------------------------------------------------+ | 4096 | 50 | 8000 | 1544 | 258934 | 8484 | 169 | +-----------------------------------------------------------------------------------------------------------------------+ | 16384 | 50 | 4000 | 2549 | 78452 | 10282 | 205 | +-----------------------------------------------------------------------------------------------------------------------+ | 65536 | 50 | 2000 | 5449 | 18350 | 9620 | 192 | +-----------------------------------------------------------------------------------------------------------------------+
if (sk->sk_shutdown & RCV_SHUTDOWN) revents |= EPOLLRDHUP | EPOLLIN | EPOLLRDNORM; -- 2.43.0