Re: [BUG] tracing: use-after-free in t_start() when a trace instance is removed

From: Steven Rostedt

Date: Fri Aug 28 2026 - 09:23:27 EST


On Thu, 27 Aug 2026 20:28:59 -0400
Steven Rostedt <rostedt@xxxxxxxxxxx> wrote:

> I see what the problem is. I guess you were creating and removing trace
> instances while reading available_events. All files that are part of an
> instance needs to get a reference counter on the trace instance when
> opened. This prevents the instance from being freed when there are
> opened files in it. I see that the available_events file doesn't take
> that reference which will allow its instance to be freed while another
> task has its content opened. When it reads that content, it will
> trigger the bug you see.

It's not available_events, it's the two new files that were added that
didn't take a reference:

show_event_filters and show_event_triggers

This should fix it:

diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index 1d39eaf6a0f7..9dbc2441763b 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -2736,14 +2736,14 @@ static const struct file_operations ftrace_show_event_filters_fops = {
.open = ftrace_event_show_filters_open,
.read = seq_read,
.llseek = seq_lseek,
- .release = seq_release,
+ .release = ftrace_event_release,
};

static const struct file_operations ftrace_show_event_triggers_fops = {
.open = ftrace_event_show_triggers_open,
.read = seq_read,
.llseek = seq_lseek,
- .release = seq_release,
+ .release = ftrace_event_release,
};

static const struct file_operations ftrace_set_event_pid_fops = {
@@ -2908,7 +2908,17 @@ ftrace_event_set_open(struct inode *inode, struct file *file)
static int
ftrace_event_show_filters_open(struct inode *inode, struct file *file)
{
- return ftrace_event_open(inode, file, &show_show_event_filters_seq_ops);
+ struct trace_array *tr = inode->i_private;
+ int ret;
+
+ ret = tracing_check_open_get_tr(tr);
+ if (ret)
+ return ret;
+
+ ret = ftrace_event_open(inode, file, &show_show_event_filters_seq_ops);
+ if (ret < 0)
+ trace_array_put(tr);
+ return ret;
}

/**
@@ -2922,7 +2932,17 @@ ftrace_event_show_filters_open(struct inode *inode, struct file *file)
static int
ftrace_event_show_triggers_open(struct inode *inode, struct file *file)
{
- return ftrace_event_open(inode, file, &show_show_event_triggers_seq_ops);
+ struct trace_array *tr = inode->i_private;
+ int ret;
+
+ ret = tracing_check_open_get_tr(tr);
+ if (ret)
+ return ret;
+
+ ret = ftrace_event_open(inode, file, &show_show_event_triggers_seq_ops);
+ if (ret < 0)
+ trace_array_put(tr);
+ return ret;
}

static int


-- Steve