* [for-linus][PATCH 1/2] ftrace: Add global mutex to serialize trace_parser access
2026-07-26 2:35 [for-linus][PATCH 0/2] tracing: More fixes for 7.2 Steven Rostedt
@ 2026-07-26 2:35 ` Steven Rostedt
2026-07-26 2:35 ` [for-linus][PATCH 2/2] tracing: perf: Fix stale head for perf syscall tracing Steven Rostedt
1 sibling, 0 replies; 3+ messages in thread
From: Steven Rostedt @ 2026-07-26 2:35 UTC (permalink / raw)
To: linux-kernel
Cc: Masami Hiramatsu, Mark Rutland, Mathieu Desnoyers, Andrew Morton,
stable, Tengda Wu
From: Tengda Wu <wutengda@huaweicloud.com>
In ftrace, the trace_parser structure is allocated and initialized when
a trace file is opened, and is subsequently used across write and release
handlers to parse user input.
The affected handler paths and their specific functions are:
- Open paths: ftrace_regex_open(), ftrace_graph_open()
- Write paths: ftrace_regex_write(), ftrace_graph_write()
- Release paths: ftrace_regex_release(), ftrace_graph_release()
If userspace opens a trace file descriptor and shares it across multiple
threads, concurrent write calls will race on the parser's internal state,
specifically the 'idx', 'cont', and 'buffer' fields, leading to corrupted
input or undefined behavior.
Fix this by adding a global mutex, parser_lock, to serialize all access
to trace_parser across write and release paths, preventing concurrent
corruption of parser state.
Fixes: e704eff3ff51 ("ftrace: Have set_graph_function handle multiple functions in one write")
Fixes: 689fd8b65d66 ("tracing: trace parser support for function and graph")
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260725024721.1983675-1-wutengda@huaweicloud.com
Signed-off-by: Tengda Wu <wutengda@huaweicloud.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
kernel/trace/ftrace.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index f93e34dd2328..6c47a94f5924 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -1097,6 +1097,12 @@ struct ftrace_ops global_ops = {
FTRACE_OPS_FL_PID,
};
+/*
+ * parser_lock - Protects trace_parser state against concurrent operations.
+ * Held across trace_get_user() and subsequent buffer parsing to prevent races.
+ */
+static DEFINE_MUTEX(parser_lock);
+
/*
* Used by the stack unwinder to know about dynamic ftrace trampolines.
*/
@@ -5842,6 +5848,8 @@ ftrace_regex_write(struct file *file, const char __user *ubuf,
/* iter->hash is a local copy, so we don't need regex_lock */
parser = &iter->parser;
+
+ guard(mutex)(&parser_lock);
read = trace_get_user(parser, ubuf, cnt, ppos);
if (read >= 0 && trace_parser_loaded(parser) &&
@@ -6984,12 +6992,14 @@ int ftrace_regex_release(struct inode *inode, struct file *file)
iter = file->private_data;
parser = &iter->parser;
+ mutex_lock(&parser_lock);
if (trace_parser_loaded(parser)) {
int enable = !(iter->flags & FTRACE_ITER_NOTRACE);
ftrace_process_regex(iter, parser->buffer,
parser->idx, enable);
}
+ mutex_unlock(&parser_lock);
trace_parser_put(parser);
@@ -7321,10 +7331,12 @@ ftrace_graph_release(struct inode *inode, struct file *file)
parser = &fgd->parser;
+ mutex_lock(&parser_lock);
if (trace_parser_loaded((parser))) {
ret = ftrace_graph_set_hash(fgd->new_hash,
parser->buffer);
}
+ mutex_unlock(&parser_lock);
trace_parser_put(parser);
@@ -7437,6 +7449,7 @@ ftrace_graph_write(struct file *file, const char __user *ubuf,
parser = &fgd->parser;
+ guard(mutex)(&parser_lock);
read = trace_get_user(parser, ubuf, cnt, ppos);
if (read >= 0 && trace_parser_loaded(parser) &&
--
2.53.0
^ permalink raw reply related [flat|nested] 3+ messages in thread* [for-linus][PATCH 2/2] tracing: perf: Fix stale head for perf syscall tracing
2026-07-26 2:35 [for-linus][PATCH 0/2] tracing: More fixes for 7.2 Steven Rostedt
2026-07-26 2:35 ` [for-linus][PATCH 1/2] ftrace: Add global mutex to serialize trace_parser access Steven Rostedt
@ 2026-07-26 2:35 ` Steven Rostedt
1 sibling, 0 replies; 3+ messages in thread
From: Steven Rostedt @ 2026-07-26 2:35 UTC (permalink / raw)
To: linux-kernel
Cc: Masami Hiramatsu, Mark Rutland, Mathieu Desnoyers, Andrew Morton,
stable
From: Steven Rostedt <rostedt@goodmis.org>
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 the task.
Reassign the head pointer if the system call event called the code that
may have caused a migration.
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260724193210.03fae1d6@gandalf.local.home
Reported-by: Sashiko <>
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 <rostedt@goodmis.org>
---
kernel/trace/trace_syscalls.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c
index e98ee7e1e66f..8a4f3c75e39f 100644
--- a/kernel/trace/trace_syscalls.c
+++ b/kernel/trace/trace_syscalls.c
@@ -1451,6 +1451,11 @@ static void perf_syscall_enter(void *ignore, struct pt_regs *regs, long id)
if (syscall_get_data(sys_data, args, &user_ptr,
&size, user_sizes, &uargs, buf_size) < 0)
return;
+
+ /* The above may have caused a migration */
+ 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 */
--
2.53.0
^ permalink raw reply related [flat|nested] 3+ messages in thread