* [PATCH v2] tracing/user_events: Don't free an event that a dynamic event still references
@ 2026-10-31 21:24 David Carlier
0 siblings, 0 replies; only message in thread
From: David Carlier @ 2026-10-31 21:24 UTC (permalink / raw)
To: Steven Rostedt, Masami Hiramatsu
Cc: Mathieu Desnoyers, linux-trace-kernel, linux-kernel,
David Carlier, stable
An eprobe takes a reference on the call of the event it attaches to,
and kprobe, uprobe, fprobe and synth events all refuse to go away while
trace_event_dyn_busy() says such a reference exists. user_events never
checks it, so a user event can be freed under an eprobe:
echo 'u:test u32 a' >> dynamic_events
echo 'e:ep user_events/test a=$a' >> dynamic_events
echo '-:user_events/test' >> dynamic_events
echo '-:eprobes/ep' >> dynamic_events
The last write drops the reference on the freed call.
If the last fd of a non-persistent event closes while such a reference
is held, the delayed destroy now fails. Mark the event persistent then,
so it can still be deleted once the reference is gone instead of being
leaked.
Return -EBUSY from destroy_user_event() in that case.
Fixes: 7f5a08c79df3 ("user_events: Add minimal support for trace_event into ftrace")
Cc: stable@vger.kernel.org
Signed-off-by: David Carlier <devnexen@gmail.com>
---
v2: keep an event whose delayed destroy fails deletable by marking it
persistent (Sashiko). Deleting it then needs CAP_PERFMON, like any
persistent event.
v1: https://lore.kernel.org/all/20261031210420.501187-1-devnexen@gmail.com/
kernel/trace/trace_events_user.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/kernel/trace/trace_events_user.c b/kernel/trace/trace_events_user.c
index f658c3a77aa7..ea6a20a30cf5 100644
--- a/kernel/trace/trace_events_user.c
+++ b/kernel/trace/trace_events_user.c
@@ -256,6 +256,11 @@ static void delayed_destroy_user_event(struct work_struct *work)
* attempt to delete it later.
*/
pr_warn("user_events: Unable to delete event\n");
+ /*
+ * Keep it as persistent so it can be still deleted
+ * since nobody own this event
+ */
+ user->reg_flags |= USER_EVENT_REG_PERSIST;
refcount_set(&user->refcnt, 1);
}
out:
@@ -1506,6 +1511,10 @@ static int destroy_user_event(struct user_event *user)
lockdep_assert_held(&event_mutex);
+ /* If there is a reference to a dynamic event */
+ if (trace_event_dyn_busy(&user->call))
+ return -EBUSY;
+
/*
* Detach the fields before removing the call. Removing the event
* frees the field list memory (trace_destroy_fields() is run on
--
2.55.0
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-10-31 21:24 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-31 21:24 [PATCH v2] tracing/user_events: Don't free an event that a dynamic event still references David Carlier
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.