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.1784454542.git.xizh2024@lzu.edu.cn/ (local)
net/tipc/socket.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index e564341e0216..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);
+ }
if (sk->sk_shutdown & RCV_SHUTDOWN)
revents |= EPOLLRDHUP | EPOLLIN | EPOLLRDNORM;--
2.43.0