Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: sock: tracing: Fix sock_exceed_buf_limit not to dereference stale pointer

The trace event sock_exceed_buf_limit saves the prot->sysctl_mem pointer
and then dereferences it in the TP_printk() portion. This is unsafe as the
TP_printk() portion is executed at the time the buffer is read. That is,
it can be seconds, minutes, days, months, even years later. If the proto
is freed, then this dereference will can also lead to a kernel crash.

Instead, save the sysctl_mem array into the ring buffer and have the
TP_printk() reference that instead. This is the proper and safe way to
read pointers in trace events.

Link: https://lore.kernel.org/all/20220706052130.16368-12-kuniyu@amazon.com/

Cc: stable@vger.kernel.org
Fixes: 3847ce32aea9f ("core: add tracepoints for queueing skb to rcvbuf")
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Acked-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Steven Rostedt (Google) and committed by
David S. Miller
820b8963 f46fd3d7

+4 -2
+4 -2
include/trace/events/sock.h
··· 98 98 99 99 TP_STRUCT__entry( 100 100 __array(char, name, 32) 101 - __field(long *, sysctl_mem) 101 + __array(long, sysctl_mem, 3) 102 102 __field(long, allocated) 103 103 __field(int, sysctl_rmem) 104 104 __field(int, rmem_alloc) ··· 110 110 111 111 TP_fast_assign( 112 112 strncpy(__entry->name, prot->name, 32); 113 - __entry->sysctl_mem = prot->sysctl_mem; 113 + __entry->sysctl_mem[0] = READ_ONCE(prot->sysctl_mem[0]); 114 + __entry->sysctl_mem[1] = READ_ONCE(prot->sysctl_mem[1]); 115 + __entry->sysctl_mem[2] = READ_ONCE(prot->sysctl_mem[2]); 114 116 __entry->allocated = allocated; 115 117 __entry->sysctl_rmem = sk_get_rmem0(sk, prot); 116 118 __entry->rmem_alloc = atomic_read(&sk->sk_rmem_alloc);