Thank you for your contribution! Sashiko AI review found 1 potential issue(s) 
to consider:

Pre-existing issues:
- [High] trace_event_file UAF and trigger memory leak on module unload
--

commit a41f148580cfeaf3b10b318f7d55d016bb4307cc
Author: Ali Ahmet Memiş <[email protected]>

tracing: Don't dereference trace_event_file in deferred trigger free

This commit addresses a use-after-free by avoiding the dereference of
trace_event_file during a deferred trigger free. It does so by directly
keeping the trace_event_call in the enable_trigger_data structure.

Link: 
https://lore.kernel.org/all/[email protected]/

> diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
> index 5e76f94e7a80e..0e4baecc7c737 100644
> --- a/kernel/trace/trace.h
> +++ b/kernel/trace/trace.h
> @@ -1952,6 +1952,7 @@ struct event_trigger_data {
>  
>  struct enable_trigger_data {
>       struct trace_event_file         *file;
> +     struct trace_event_call         *call;
>       bool                            enable;
>       bool                            hist;
>  };
> diff --git a/kernel/trace/trace_events_trigger.c 
> b/kernel/trace/trace_events_trigger.c
> index 149300cc5e8ad..4d2fde996c0f6 100644
> --- a/kernel/trace/trace_events_trigger.c
> +++ b/kernel/trace/trace_events_trigger.c
> @@ -1728,7 +1728,8 @@ static void enable_trigger_private_data_free(struct 
> event_trigger_data *data)
>  {
>       struct enable_trigger_data *enable_data = data->private_data;
>  
> -     trace_event_put_ref(enable_data->file->event_call);
> +     /* The file may already be freed here, only the call is kept alive */
> +     trace_event_put_ref(enable_data->call);

[Severity: High]
This isn't a bug introduced by this patch, but it is a preexisting issue in
the subsystem's module unload handling.

When a privileged user registers a trace event trigger (like traceon or
enable_event) on a trace event defined in a kernel module and then unloads
that module, trace_module_remove_events() removes the events and eventually
frees the trace_event_file structure synchronously:

kernel/trace/trace_events.c:remove_event_file_dir() {
...
        file->flags |= EVENT_FILE_FL_FREED;
        event_file_put(file);
...
}

kernel/trace/trace_events.c:event_file_put() {
...
        if (refcount_dec_and_test(&file->ref)) {
                /* Count should only go to zero when it is freed */
                if (WARN_ON_ONCE(!(file->flags & EVENT_FILE_FL_FREED)))
                        return;
                kmem_cache_free(file_cachep, file);
        }
}

Does this code leak the file->triggers list and cause memory corruption?

Because remove_event_file_dir() does not wait for an RCU grace period via
tracepoint_synchronize_unregister() before freeing the file, couldn't
concurrent RCU readers executing the tracepoint probe dereference the freed
file pointer?

Also, without cleaning up the triggers attached to file->triggers, are these
trigger structures permanently leaked?

>       kfree(enable_data);
>  }
>

-- 
Sashiko AI review · 
https://sashiko.dev/#/patchset/[email protected]?part=1

Reply via email to