From: Steven Rostedt <[email protected]> The code that can read the user space parameters of a system call may enable preemption and migrate. The head of the per CPU perf events list may be pointing to the wrong CPU event if the code migrates.
Move the taking assignment of the head pointer to after the faulting code is called. Cc: [email protected] Reported-by: Sashiko <[email protected]> Link: https://sashiko.dev/#/patchset/20260717173252.3431565-1-usama.arif%40linux.dev Fixes: edca33a56297d ("tracing: Fix failure to read user space from system call trace events") Signed-off-by: Steven Rostedt <[email protected]> --- kernel/trace/trace_syscalls.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c index e98ee7e1e66f..e541e964d193 100644 --- a/kernel/trace/trace_syscalls.c +++ b/kernel/trace/trace_syscalls.c @@ -1440,19 +1440,20 @@ static void perf_syscall_enter(void *ignore, struct pt_regs *regs, long id) */ guard(preempt_notrace)(); - head = this_cpu_ptr(sys_data->enter_event->perf_events); - if (hlist_empty(head)) - return; - /* Check if this syscall event faults in user space memory */ mayfault = sys_data->user_mask != 0; if (mayfault) { + /* Enables preemption and may migrate */ if (syscall_get_data(sys_data, args, &user_ptr, &size, user_sizes, &uargs, buf_size) < 0) return; } + head = this_cpu_ptr(sys_data->enter_event->perf_events); + if (hlist_empty(head)) + return; + /* get the size after alignment with the u32 buffer size field */ size += sizeof(unsigned long) * sys_data->nb_args + sizeof(*rec); size = ALIGN(size + sizeof(u32), sizeof(u64)); -- 2.53.0
