* [for-linus][PATCH 1/9] tracing/remotes: Fix page_va[] access before counter update in trace_remote_alloc_buffer()
2026-07-24 23:18 [for-linus][PATCH 0/9] tracing: Fixes for 7.2 Steven Rostedt
@ 2026-07-24 23:18 ` Steven Rostedt
2026-07-24 23:18 ` [for-linus][PATCH 2/9] tracing: Propagate errors from remote event bulk updates Steven Rostedt
` (7 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Steven Rostedt @ 2026-07-24 23:18 UTC (permalink / raw)
To: linux-kernel
Cc: Masami Hiramatsu, Mark Rutland, Mathieu Desnoyers, Andrew Morton,
stable, Fuad Tabba, Vincent Donnefort
From: Fuad Tabba <fuad.tabba@linux.dev>
page_va[] is annotated __counted_by(nr_page_va), so nr_page_va must
cover an index before that element is accessed. The allocation loop
writes page_va[id] while nr_page_va is still id and increments it only
afterwards, so every write is one element past the declared count.
The store is out of bounds with respect to the annotation: a build with
CONFIG_UBSAN_BOUNDS on a toolchain that honours __counted_by
(clang >= 20.1, gcc >= 15.1) flags it as an array-index overflow.
Increment nr_page_va before writing the element it now covers. A failed
allocation then leaves the slot counted but NULL; the error path frees
it with free_page(0), which is a no-op.
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260713072823.2668323-1-fuad.tabba@linux.dev
Fixes: 96e43537af546 ("tracing: Introduce trace remotes")
Signed-off-by: Fuad Tabba <fuad.tabba@linux.dev>
Reviewed-by: Vincent Donnefort <vdonnefort@google.com>
Tested-by: Vincent Donnefort <vdonnefort@google.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
kernel/trace/trace_remote.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/kernel/trace/trace_remote.c b/kernel/trace/trace_remote.c
index 0f6ef5c36d84..ef42d9c38b37 100644
--- a/kernel/trace/trace_remote.c
+++ b/kernel/trace/trace_remote.c
@@ -1004,11 +1004,10 @@ int trace_remote_alloc_buffer(struct trace_buffer_desc *desc, size_t desc_size,
desc->nr_cpus++;
for (id = 0; id < nr_pages; id++) {
+ rb_desc->nr_page_va++;
rb_desc->page_va[id] = (unsigned long)__get_free_page(GFP_KERNEL);
if (!rb_desc->page_va[id])
goto err;
-
- rb_desc->nr_page_va++;
}
rb_desc = __next_ring_buffer_desc(rb_desc);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [for-linus][PATCH 2/9] tracing: Propagate errors from remote event bulk updates
2026-07-24 23:18 [for-linus][PATCH 0/9] tracing: Fixes for 7.2 Steven Rostedt
2026-07-24 23:18 ` [for-linus][PATCH 1/9] tracing/remotes: Fix page_va[] access before counter update in trace_remote_alloc_buffer() Steven Rostedt
@ 2026-07-24 23:18 ` Steven Rostedt
2026-07-24 23:18 ` [for-linus][PATCH 3/9] tracing: Fix resource leak on mmiotrace trace_pipe close Steven Rostedt
` (6 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Steven Rostedt @ 2026-07-24 23:18 UTC (permalink / raw)
To: linux-kernel
Cc: Masami Hiramatsu, Mark Rutland, Mathieu Desnoyers, Andrew Morton,
stable, Jackie Liu, Vincent Donnefort
From: Jackie Liu <liuyun01@kylinos.cn>
remote_events_dir_enable_write() ignores the return value from
trace_remote_enable_event(). If a remote rejects an event state change,
the write therefore reports success even though the affected event remains
in its previous state.
Keep trying all events, but retain and return the first error. This matches
__ftrace_set_clr_event_nolock(), which permits partial updates while
notifying userspace when an operation fails.
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260715074455.3897-1-liu.yun@linux.dev
Fixes: 775cb093bc50 ("tracing: Add events/ root files to trace remotes")
Assisted-by: Codex:gpt-5.6-sol
Signed-off-by: Jackie Liu <liuyun01@kylinos.cn>
Reviewed-by: Vincent Donnefort <vdonnefort@google.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
kernel/trace/trace_remote.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/kernel/trace/trace_remote.c b/kernel/trace/trace_remote.c
index ef42d9c38b37..e6724f947170 100644
--- a/kernel/trace/trace_remote.c
+++ b/kernel/trace/trace_remote.c
@@ -1149,10 +1149,21 @@ static ssize_t remote_events_dir_enable_write(struct file *filp, const char __us
for (i = 0; i < remote->nr_events; i++) {
struct remote_event *evt = &remote->events[i];
+ int eret;
- trace_remote_enable_event(remote, evt, enable);
+ eret = trace_remote_enable_event(remote, evt, enable);
+ /*
+ * Save the first error and return that. Some events
+ * may still have been enabled, but let the user
+ * know that something went wrong.
+ */
+ if (!ret && eret)
+ ret = eret;
}
+ if (ret)
+ return ret;
+
return count;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [for-linus][PATCH 3/9] tracing: Fix resource leak on mmiotrace trace_pipe close
2026-07-24 23:18 [for-linus][PATCH 0/9] tracing: Fixes for 7.2 Steven Rostedt
2026-07-24 23:18 ` [for-linus][PATCH 1/9] tracing/remotes: Fix page_va[] access before counter update in trace_remote_alloc_buffer() Steven Rostedt
2026-07-24 23:18 ` [for-linus][PATCH 2/9] tracing: Propagate errors from remote event bulk updates Steven Rostedt
@ 2026-07-24 23:18 ` Steven Rostedt
2026-07-24 23:18 ` [for-linus][PATCH 4/9] tracing: Fix mmiotrace possible NULL dereferencing of hiter->dev Steven Rostedt
` (5 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Steven Rostedt @ 2026-07-24 23:18 UTC (permalink / raw)
To: linux-kernel
Cc: Masami Hiramatsu, Mark Rutland, Mathieu Desnoyers, Andrew Morton,
stable, deepakraog
From: deepakraog <gaikwad.dcg@gmail.com>
The mmiotrace tracer was added May 12th 2008. At that time, resources
created in pipe_open() could not be freed because there was not
pipe_close function pointer of the tracer. The pipe_close function pointer
was added in December 7th, 2009, but the mmiotrace tracer was not updated.
mmio_pipe_open() allocates a header_iter and takes a pci_dev reference
when trace_pipe is opened. mmio_close() frees them, but it was only
wired to the tracer's .close callback.
tracing_release_pipe() invokes .pipe_close, not .close, when the
trace_pipe file is released. As a result, closing trace_pipe with the
mmiotrace tracer active leaked the header_iter allocation and left a
stale pci_dev reference.
Set .pipe_close to mmio_close, matching how function_graph wires both
callbacks to the same handler.
Note, if the trace_pipe is read to completion, it will clean up the
resources, but if one were to run:
# head -n 1 /sys/kernel/tracing/trace_pipe
VERSION 20070824
Over and over again, it would trigger a massive leak.
Cc: stable@vger.kernel.org
Fixes: c521efd1700a8 ("tracing: Add pipe_close interface)
Link: https://patch.msgid.link/20260715143604.14481-1-gaikwad.dcg@gmail.com
Signed-off-by: deepakraog <gaikwad.dcg@gmail.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
kernel/trace/trace_mmiotrace.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/trace/trace_mmiotrace.c b/kernel/trace/trace_mmiotrace.c
index 226cf66e0d68..20812e7f911f 100644
--- a/kernel/trace/trace_mmiotrace.c
+++ b/kernel/trace/trace_mmiotrace.c
@@ -109,7 +109,6 @@ static void mmio_pipe_open(struct trace_iterator *iter)
iter->private = hiter;
}
-/* XXX: This is not called when the pipe is closed! */
static void mmio_close(struct trace_iterator *iter)
{
struct header_iter *hiter = iter->private;
@@ -279,6 +278,7 @@ static struct tracer mmio_tracer __read_mostly =
.start = mmio_trace_start,
.pipe_open = mmio_pipe_open,
.close = mmio_close,
+ .pipe_close = mmio_close,
.read = mmio_read,
.print_line = mmio_print_line,
.noboot = true,
--
2.53.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [for-linus][PATCH 4/9] tracing: Fix mmiotrace possible NULL dereferencing of hiter->dev
2026-07-24 23:18 [for-linus][PATCH 0/9] tracing: Fixes for 7.2 Steven Rostedt
` (2 preceding siblings ...)
2026-07-24 23:18 ` [for-linus][PATCH 3/9] tracing: Fix resource leak on mmiotrace trace_pipe close Steven Rostedt
@ 2026-07-24 23:18 ` Steven Rostedt
2026-07-24 23:18 ` [for-linus][PATCH 5/9] tracing: Fix union collision of module and refcnt for dynamic events Steven Rostedt
` (4 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Steven Rostedt @ 2026-07-24 23:18 UTC (permalink / raw)
To: linux-kernel
Cc: Masami Hiramatsu, Mark Rutland, Mathieu Desnoyers, Andrew Morton,
stable, Sashiko
From: Steven Rostedt <rostedt@goodmis.org>
If the mmio_pipe_open() fails to find a PCI device, the hiter->dev
will be assigned to NULL. The mmiotrace read() function dereferences the
hiter->dev if hiter exists.
Change the test of the read to not only check hiter being NULL, but also
the hiter->dev before dereferencing it.
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260721211143.36dbd559@gandalf.local.home
Fixes: f984b51e0779 ("ftrace: add mmiotrace plugin")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Link: https://sashiko.dev/#/patchset/20260715143604.14481-1-gaikwad.dcg%40gmail.com
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
kernel/trace/trace_mmiotrace.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/trace/trace_mmiotrace.c b/kernel/trace/trace_mmiotrace.c
index 20812e7f911f..b88b8d9923ad 100644
--- a/kernel/trace/trace_mmiotrace.c
+++ b/kernel/trace/trace_mmiotrace.c
@@ -145,7 +145,7 @@ static ssize_t mmio_read(struct trace_iterator *iter, struct file *filp,
goto print_out;
}
- if (!hiter)
+ if (!hiter || !hiter->dev)
return 0;
mmio_print_pcidev(s, hiter->dev);
--
2.53.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [for-linus][PATCH 5/9] tracing: Fix union collision of module and refcnt for dynamic events
2026-07-24 23:18 [for-linus][PATCH 0/9] tracing: Fixes for 7.2 Steven Rostedt
` (3 preceding siblings ...)
2026-07-24 23:18 ` [for-linus][PATCH 4/9] tracing: Fix mmiotrace possible NULL dereferencing of hiter->dev Steven Rostedt
@ 2026-07-24 23:18 ` Steven Rostedt
2026-07-24 23:18 ` [for-linus][PATCH 6/9] selftests/ftrace: Reset triggers at top level before instance loop Steven Rostedt
` (3 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Steven Rostedt @ 2026-07-24 23:18 UTC (permalink / raw)
To: linux-kernel
Cc: Masami Hiramatsu, Mark Rutland, Mathieu Desnoyers, Andrew Morton,
stable
From: "Masami Hiramatsu (Google)" <mhiramat@kernel.org>
In 'struct trace_event_call', the 'module' pointer and the 'refcnt'
atomic variable share the same memory space in a union. For dynamic
events, the union member is 'refcnt', which acts as an active
reference counter.
When a dynamic event (such as kprobe, uprobe, fprobe, eprobe, or
wprobe) has a non-zero reference count (e.g. due to active event
triggers or perf attachments), its 'call->module' evaluates to a
small non-zero integer instead of NULL.
When filtering or setting events for a specific module (e.g., writing
':mod:<module>' to 'set_event'), the code in
'__ftrace_set_clr_event_nolock()' and 'update_event_fields()' reads
'call->module' directly without checking whether the event is dynamic.
This causes the kernel to treat the small integer (refcnt) as a
'struct module' pointer, leading to a NULL/invalid pointer dereference
(Oops) when dereferencing the module name.
Fix this by ensuring that the 'TRACE_EVENT_FL_DYNAMIC' flag is checked
before treating 'call->module' as a valid pointer in these code paths.
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/178425670947.84440.11344393611899824907.stgit@devnote2
Fixes: 4c86bc531e60 ("tracing: Add :mod: command to enabled module events")
Assisted-by: Antigravity:gemini-3.5-flash
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
kernel/trace/trace_events.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index c46e623e7e0d..956692856fa8 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -1350,7 +1350,9 @@ __ftrace_set_clr_event_nolock(struct trace_array *tr, const char *match,
call = file->event_call;
/* If a module is specified, skip events that are not that module */
- if (module && (!call->module || strcmp(module_name(call->module), module)))
+ if (module &&
+ ((call->flags & TRACE_EVENT_FL_DYNAMIC) ||
+ !call->module || strcmp(module_name(call->module), module)))
continue;
name = trace_event_name(call);
--
2.53.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [for-linus][PATCH 6/9] selftests/ftrace: Reset triggers at top level before instance loop
2026-07-24 23:18 [for-linus][PATCH 0/9] tracing: Fixes for 7.2 Steven Rostedt
` (4 preceding siblings ...)
2026-07-24 23:18 ` [for-linus][PATCH 5/9] tracing: Fix union collision of module and refcnt for dynamic events Steven Rostedt
@ 2026-07-24 23:18 ` Steven Rostedt
2026-07-24 23:18 ` [for-linus][PATCH 7/9] tracing: Fix context switch counter truncation Steven Rostedt
` (2 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Steven Rostedt @ 2026-07-24 23:18 UTC (permalink / raw)
To: linux-kernel
Cc: Masami Hiramatsu, Mark Rutland, Mathieu Desnoyers, Andrew Morton,
stable
From: "Masami Hiramatsu (Google)" <mhiramat@kernel.org>
When running instance tests, 'ftracetest' creates a new ftrace instance
and runs the tests inside it. Before starting each test, it executes
'initialize_system()' to reset the ftrace state to initial-state.
However, since 'initialize_system()' is executed in the context of the
instance directory, it only cleans up triggers and filters of that
instance.
Any triggers or dynamic events left behind in the top-level instance by
previous failed top-level tests, are left completely untouched. These
top-level leftovers can cause subsequent instance-based tests to fail
or even crash the kernel.
Fix this by executing 'initialize_system()' in the top-level tracing
directory once before entering the instance loop.
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/178425671889.84440.9477850701738666404.stgit@devnote2
Fixes: b5b77be812de ("selftests: ftrace: Allow some tests to be run in a tracing instance")
Assisted-by: Antigravity:gemini-3.5-flash
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
tools/testing/selftests/ftrace/ftracetest | 1 +
1 file changed, 1 insertion(+)
diff --git a/tools/testing/selftests/ftrace/ftracetest b/tools/testing/selftests/ftrace/ftracetest
index 0a56bf209f6c..8ad2c385407e 100755
--- a/tools/testing/selftests/ftrace/ftracetest
+++ b/tools/testing/selftests/ftrace/ftracetest
@@ -503,6 +503,7 @@ for t in $TEST_CASES; do
done
# Test on instance loop
+(cd $TRACING_DIR; initialize_system)
INSTANCE=" (instance) "
for t in $TEST_CASES; do
test_on_instance $t || continue
--
2.53.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [for-linus][PATCH 7/9] tracing: Fix context switch counter truncation
2026-07-24 23:18 [for-linus][PATCH 0/9] tracing: Fixes for 7.2 Steven Rostedt
` (5 preceding siblings ...)
2026-07-24 23:18 ` [for-linus][PATCH 6/9] selftests/ftrace: Reset triggers at top level before instance loop Steven Rostedt
@ 2026-07-24 23:18 ` Steven Rostedt
2026-07-24 23:18 ` [for-linus][PATCH 8/9] tracing: Fix use-after-free freeing trigger private data Steven Rostedt
2026-07-24 23:18 ` [for-linus][PATCH 9/9] tracing: Delay module ref count for "enable_event" trigger Steven Rostedt
8 siblings, 0 replies; 10+ messages in thread
From: Steven Rostedt @ 2026-07-24 23:18 UTC (permalink / raw)
To: linux-kernel
Cc: Masami Hiramatsu, Mark Rutland, Mathieu Desnoyers, Andrew Morton,
stable, Breno Leitao, Usama Arif
From: Usama Arif <usama.arif@linux.dev>
trace_user_fault_read() samples nr_context_switches_cpu() before enabling
preemption and retries the user copy if the counter changes. The helper
returns unsigned long long because rq->nr_switches is u64, but the saved
value is unsigned int.
Once a CPU has performed 2^32 context switches, assigning the counter to
cnt discards its upper bits. The comparison after the copy promotes cnt
back to unsigned long long, but the lost bits remain zero, so it reports a
change even when the task was never scheduled out. Every retry then fails
the same way until the 100-try guard warns and the user copy is abandoned.
This affects long-running systems and workloads with high context-switch
rates. A CPU switching 1,000 times per second takes about 50 days.
Store the sampled count in unsigned long long so the full value is
preserved.
Cc: stable@vger.kernel.org
Fixes: 64cf7d058a00 ("tracing: Have trace_marker use per-cpu data to read user space")
Link: https://patch.msgid.link/20260717173252.3431565-1-usama.arif@linux.dev
Reported-by: Breno Leitao <leitao@debian.org>
Signed-off-by: Usama Arif <usama.arif@linux.dev>
Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Reviewed-by: Breno Leitao <leitao@debian.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
kernel/trace/trace.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 18710c190c92..01a5e87af299 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -6187,7 +6187,7 @@ char *trace_user_fault_read(struct trace_user_buf_info *tinfo,
{
int cpu = smp_processor_id();
char *buffer = per_cpu_ptr(tinfo->tbuf, cpu)->buf;
- unsigned int cnt;
+ unsigned long long cnt;
int trys = 0;
int ret;
--
2.53.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [for-linus][PATCH 8/9] tracing: Fix use-after-free freeing trigger private data
2026-07-24 23:18 [for-linus][PATCH 0/9] tracing: Fixes for 7.2 Steven Rostedt
` (6 preceding siblings ...)
2026-07-24 23:18 ` [for-linus][PATCH 7/9] tracing: Fix context switch counter truncation Steven Rostedt
@ 2026-07-24 23:18 ` Steven Rostedt
2026-07-24 23:18 ` [for-linus][PATCH 9/9] tracing: Delay module ref count for "enable_event" trigger Steven Rostedt
8 siblings, 0 replies; 10+ messages in thread
From: Steven Rostedt @ 2026-07-24 23:18 UTC (permalink / raw)
To: linux-kernel
Cc: Masami Hiramatsu, Mark Rutland, Mathieu Desnoyers, Andrew Morton,
David Carlier
From: David Carlier <devnexen@gmail.com>
Commit 61d445af0a7c ("tracing: Add bulk garbage collection of freeing
event_trigger_data") moved the kfree() of event_trigger_data to a kthread
that runs tracepoint_synchronize_unregister() before freeing. That removed
the synchronization the trigger .free callbacks used to get implicitly and
inline from trigger_data_free().
event_hist_trigger_free(), event_hist_trigger_named_free() and
event_enable_trigger_free() free their satellite data (hist_data, cmd_ops,
enable_data) right after trigger_data_free() returns. With the
synchronization now deferred to the kthread, a concurrent tracepoint
handler can still reach that data through the list_del_rcu()'d trigger,
causing a use-after-free.
The histogram teardown must stay synchronous: remove_hist_vars() and
unregister_field_var_hists() have to detach a synthetic event from the
histogram before the trigger-removal write returns, otherwise a following
command races in and the synthetic-event removal fails with -EBUSY, as the
trigger-synthetic-eprobe.tc selftest catches. Make those callbacks wait
with the correct barrier - tracepoint_synchronize_unregister(), matching
the free kthread - before freeing.
The enable trigger has no such synchronous requirement, and a blocking
synchronize there would re-serialize the path that commit deliberately
deferred. Give it an optional private_data_free() callback that the free
kthread runs after its grace period, and free enable_data from there.
Link: https://patch.msgid.link/20260724030523.19081-1-devnexen@gmail.com
Suggested-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Suggested-by: Steven Rostedt <rostedt@goodmis.org>
Fixes: 61d445af0a7c ("tracing: Add bulk garbage collection of freeing event_trigger_data")
Signed-off-by: David Carlier <devnexen@gmail.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
kernel/trace/trace.h | 1 +
kernel/trace/trace_events_hist.c | 2 ++
kernel/trace/trace_events_trigger.c | 18 +++++++++++++++---
3 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 80fe152af1dd..bf77331f56a4 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -1941,6 +1941,7 @@ struct event_trigger_data {
struct list_head named_list;
struct event_trigger_data *named_data;
struct llist_node llist;
+ void (*private_data_free)(struct event_trigger_data *data);
};
/* Avoid typos */
diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
index 82ce492ab268..58d28cd1afa3 100644
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -6349,6 +6349,7 @@ static void event_hist_trigger_free(struct event_trigger_data *data)
trigger_data_free(data);
+ tracepoint_synchronize_unregister();
remove_hist_vars(hist_data);
unregister_field_var_hists(hist_data);
@@ -6388,6 +6389,7 @@ static void event_hist_trigger_named_free(struct event_trigger_data *data)
del_named_trigger(data);
trigger_data_free(data);
+ tracepoint_synchronize_unregister();
kfree(cmd_ops);
}
}
diff --git a/kernel/trace/trace_events_trigger.c b/kernel/trace/trace_events_trigger.c
index 655db2e82513..46e60b70a4bb 100644
--- a/kernel/trace/trace_events_trigger.c
+++ b/kernel/trace/trace_events_trigger.c
@@ -38,6 +38,13 @@ static void trigger_create_kthread_locked(void)
}
}
+static void trigger_data_free_one(struct event_trigger_data *data)
+{
+ if (data->private_data_free)
+ data->private_data_free(data);
+ kfree(data);
+}
+
static void trigger_data_free_queued_locked(void)
{
struct event_trigger_data *data, *tmp;
@@ -52,7 +59,7 @@ static void trigger_data_free_queued_locked(void)
tracepoint_synchronize_unregister();
llist_for_each_entry_safe(data, tmp, llnodes, llist)
- kfree(data);
+ trigger_data_free_one(data);
}
/* Bulk garbage collection of event_trigger_data elements */
@@ -75,7 +82,7 @@ static int trigger_kthread_fn(void *ignore)
tracepoint_synchronize_unregister();
llist_for_each_entry_safe(data, tmp, llnodes, llist)
- kfree(data);
+ trigger_data_free_one(data);
}
return 0;
@@ -1717,6 +1724,11 @@ int event_enable_trigger_print(struct seq_file *m,
return 0;
}
+static void enable_trigger_private_data_free(struct event_trigger_data *data)
+{
+ kfree(data->private_data);
+}
+
void event_enable_trigger_free(struct event_trigger_data *data)
{
struct enable_trigger_data *enable_data = data->private_data;
@@ -1728,9 +1740,9 @@ void event_enable_trigger_free(struct event_trigger_data *data)
if (!data->ref) {
/* Remove the SOFT_MODE flag */
trace_event_enable_disable(enable_data->file, 0, 1);
+ data->private_data_free = enable_trigger_private_data_free;
trace_event_put_ref(enable_data->file->event_call);
trigger_data_free(data);
- kfree(enable_data);
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [for-linus][PATCH 9/9] tracing: Delay module ref count for "enable_event" trigger
2026-07-24 23:18 [for-linus][PATCH 0/9] tracing: Fixes for 7.2 Steven Rostedt
` (7 preceding siblings ...)
2026-07-24 23:18 ` [for-linus][PATCH 8/9] tracing: Fix use-after-free freeing trigger private data Steven Rostedt
@ 2026-07-24 23:18 ` Steven Rostedt
8 siblings, 0 replies; 10+ messages in thread
From: Steven Rostedt @ 2026-07-24 23:18 UTC (permalink / raw)
To: linux-kernel
Cc: Masami Hiramatsu, Mark Rutland, Mathieu Desnoyers, Andrew Morton,
stable, Sashiko
From: Steven Rostedt <rostedt@goodmis.org>
Triggers are now delayed from freeing, but can still be triggered until
after the RCU grace period has ended. The freeing of the enable_event data
is put into the private_data_free() callback, but the put of the module
refcount is done immediately.
It is possible that if a module is removed that has an event that would
enable (or disable) it is still active, it can read the data of the module
after it is removed causing a use-after-free bug.
Move the trace_event_put_ref() that releases the module into the delayed
callback so that the module can not be removed until any reference to its
events are finished.
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260724132415.1b5005db@gandalf.local.home
Reported-by: Sashiko <sashiko-bot@kernel.org>
Link: https://sashiko.dev/#/patchset/20260724030523.19081-1-devnexen%40gmail.com
Fixes: 61d445af0a7c ("tracing: Add bulk garbage collection of freeing event_trigger_data")
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
kernel/trace/trace_events_trigger.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/kernel/trace/trace_events_trigger.c b/kernel/trace/trace_events_trigger.c
index 46e60b70a4bb..ad83419cb420 100644
--- a/kernel/trace/trace_events_trigger.c
+++ b/kernel/trace/trace_events_trigger.c
@@ -1726,7 +1726,10 @@ int event_enable_trigger_print(struct seq_file *m,
static void enable_trigger_private_data_free(struct event_trigger_data *data)
{
- kfree(data->private_data);
+ struct enable_trigger_data *enable_data = data->private_data;
+
+ trace_event_put_ref(enable_data->file->event_call);
+ kfree(enable_data);
}
void event_enable_trigger_free(struct event_trigger_data *data)
@@ -1741,7 +1744,6 @@ void event_enable_trigger_free(struct event_trigger_data *data)
/* Remove the SOFT_MODE flag */
trace_event_enable_disable(enable_data->file, 0, 1);
data->private_data_free = enable_trigger_private_data_free;
- trace_event_put_ref(enable_data->file->event_call);
trigger_data_free(data);
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 10+ messages in thread