From: Mathias Krause <minipli@grsecurity.net>
To: Steven Rostedt <rostedt@goodmis.org>
Cc: "Ajay Kaher" <ajay.kaher@broadcom.com>,
"Masami Hiramatsu" <mhiramat@kernel.org>,
"Ilkka Naulapää" <digirigawa@gmail.com>,
"Linus Torvalds" <torvalds@linux-foundation.org>,
"Al Viro" <viro@zeniv.linux.org.uk>,
linux-trace-kernel@vger.kernel.org, linux-kernel@vger.kernel.org,
regressions@leemhuis.info,
"Dan Carpenter" <dan.carpenter@linaro.org>,
"Vasavi Sirnapalli" <vasavi.sirnapalli@broadcom.com>,
"Alexey Makhalov" <alexey.makhalov@broadcom.com>,
"Florian Fainelli" <florian.fainelli@broadcom.com>,
"Beau Belgrave" <beaub@linux.microsoft.com>
Subject: Re: tracing: user events UAF crash report
Date: Fri, 26 Jul 2024 10:25:05 +0200 [thread overview]
Message-ID: <920258cb-d2d5-4065-874a-df5a36c6a563@grsecurity.net> (raw)
In-Reply-To: <20240725190632.2755cb70@gandalf.local.home>
On 26.07.24 01:06, Steven Rostedt wrote:
> On Thu, 25 Jul 2024 23:32:30 +0200
> Mathias Krause <minipli@grsecurity.net> wrote:
>
>> That was for a single run of
>> tools/testing/selftests/user_events/ftrace_test with the read loop of
>> /sys/kernel/tracing/events/user_events/__test_event/format in a
>> different shell.
>>
>>>
>>> destroy_user_event() which is under event_mutex calls
>>> user_event_set_call_visible() with false, that will then call:
>>>
>>> trace_remove_event_call() -> probe_remove_event_call() ->
>>> __trace_remove_event_call() -> event_remove() ->
>>> remove_event_from_tracers()
>>>
>>> Where remove_event_from_tracers() loops over all the instances and will set
>>> each of the file pointers flags associated to the event: EVENT_FILE_FL_FREED
>>>
>>> Then it returns back to destroy_user_event() that would free the event.
>>>
>>> The f_start() that was in your crash, with the new patch, should take the
>>> event_mutex before referencing the event that was freed. And with that flag
>>> being set, it should exit out.
>>
>> Looking at the very first report:
>>
>> [ 76.306946] BUG: KASAN: slab-use-after-free in f_start+0x36e/0x3d0
>>
>> That's what faddr2line gives me:
>>
>> f_start+0x36e/0x3d0:
>> f_start at kernel/trace/trace_events.c:1637 (discriminator 1)
>>
>> Which is:
>> 1635 mutex_lock(&event_mutex);
>> 1636 file = event_file_data(m->private);
>> 1637 if (!file || (file->flags & EVENT_FILE_FL_FREED))
>> 1638 return ERR_PTR(-ENODEV);
>
> BAH! I finally figured it out.
>
> I was able to reproduce it and this does stop the UAF from happening.
>
> The issue was, as a short cut, I had the "format" file's i_private point to
> the "call" entry directly, and not go via the "file". This is because the
> all format files are the same for the same "call", so no reason to
> differentiate them. The other files maintain state (like the "enable",
> "trigger", etc). But this means if the file were to disappear, the "format"
> file would be unaware of it.
>
> This should fix it for you. It fixed it for me.
Heureka, it did!
Thanks, Steve!
>
> -- Steve
>
>
> diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
> index 6ef29eba90ce..852643d957de 100644
> --- a/kernel/trace/trace_events.c
> +++ b/kernel/trace/trace_events.c
> @@ -1540,7 +1540,8 @@ enum {
>
> static void *f_next(struct seq_file *m, void *v, loff_t *pos)
> {
> - struct trace_event_call *call = event_file_data(m->private);
> + struct trace_event_file *file = event_file_data(m->private);
> + struct trace_event_call *call = file->event_call;
> struct list_head *common_head = &ftrace_common_fields;
> struct list_head *head = trace_get_fields(call);
> struct list_head *node = v;
> @@ -1572,7 +1573,8 @@ static void *f_next(struct seq_file *m, void *v, loff_t *pos)
>
> static int f_show(struct seq_file *m, void *v)
> {
> - struct trace_event_call *call = event_file_data(m->private);
> + struct trace_event_file *file = event_file_data(m->private);
> + struct trace_event_call *call = file->event_call;
> struct ftrace_event_field *field;
> const char *array_descriptor;
>
> @@ -1627,12 +1629,14 @@ static int f_show(struct seq_file *m, void *v)
>
> static void *f_start(struct seq_file *m, loff_t *pos)
> {
> + struct trace_event_file *file;
> void *p = (void *)FORMAT_HEADER;
> loff_t l = 0;
>
> /* ->stop() is called even if ->start() fails */
> mutex_lock(&event_mutex);
> - if (!event_file_data(m->private))
> + file = event_file_data(m->private);
> + if (!file || (file->flags & EVENT_FILE_FL_FREED))
> return ERR_PTR(-ENODEV);
>
> while (l < *pos && p)
> @@ -2485,7 +2489,6 @@ static int event_callback(const char *name, umode_t *mode, void **data,
> if (strcmp(name, "format") == 0) {
> *mode = TRACE_MODE_READ;
> *fops = &ftrace_event_format_fops;
> - *data = call;
> return 1;
> }
>
Will ack the patch you send.
Thanks again,
Mathias
next prev parent reply other threads:[~2024-07-26 8:25 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-07-19 20:47 tracing: user events UAF crash report Mathias Krause
2024-07-20 3:33 ` Dan Carpenter
2024-07-22 11:13 ` Ajay Kaher
2024-07-22 12:08 ` Mathias Krause
2024-07-25 13:33 ` Ajay Kaher
2024-07-25 16:15 ` Ajay Kaher
2024-07-25 16:30 ` Ajay Kaher
2024-07-25 17:10 ` Steven Rostedt
2024-07-25 17:16 ` Steven Rostedt
2024-07-25 18:12 ` Mathias Krause
2024-07-25 19:05 ` Steven Rostedt
2024-07-25 19:42 ` Mathias Krause
2024-07-25 20:15 ` Steven Rostedt
2024-07-25 20:41 ` Mathias Krause
2024-07-25 21:14 ` Steven Rostedt
2024-07-25 21:32 ` Mathias Krause
2024-07-25 23:06 ` Steven Rostedt
2024-07-26 8:25 ` Mathias Krause [this message]
2024-07-25 19:53 ` Mathias Krause
2024-07-25 16:48 ` Steven Rostedt
2024-07-23 0:11 ` Steven Rostedt
2024-07-23 12:25 ` [PATCH] eventfs: Don't return NULL in eventfs_create_dir() Mathias Krause
2024-07-23 14:43 ` tracing: user events UAF crash report Steven Rostedt
2024-07-23 20:54 ` Mathias Krause
2024-07-23 21:07 ` [PATCH] eventfs: Use SRCU for freeing eventfs_inodes Mathias Krause
2024-07-23 21:23 ` Steven Rostedt
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=920258cb-d2d5-4065-874a-df5a36c6a563@grsecurity.net \
--to=minipli@grsecurity.net \
--cc=ajay.kaher@broadcom.com \
--cc=alexey.makhalov@broadcom.com \
--cc=beaub@linux.microsoft.com \
--cc=dan.carpenter@linaro.org \
--cc=digirigawa@gmail.com \
--cc=florian.fainelli@broadcom.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-trace-kernel@vger.kernel.org \
--cc=mhiramat@kernel.org \
--cc=regressions@leemhuis.info \
--cc=rostedt@goodmis.org \
--cc=torvalds@linux-foundation.org \
--cc=vasavi.sirnapalli@broadcom.com \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.