On Mon, Sep 07, 2026 at 09:29:43AM +0000, [email protected] wrote:
> This isn't a bug introduced by this patch, but does this error path leave
> the new trigger on the global named_triggers list?
>
> If event_hist_trigger_init() fails, the trigger is never removed from the
> list before the function returns the error. The caller then propagates
> this error, eventually calling trigger_data_free() which frees the
> structure. Can this lead to a Use-After-Free list corruption when the
> global named_triggers list is accessed later?

Yes, and so does the second one. Both end in the same read this patch is
about, and neither is fixed by it.

event_hist_trigger_named_init() publishes the trigger before the only step
that can fail:

        data->ref++;

        save_named_trigger(data->named_data->name, data);

        ret = event_hist_trigger_init(data->named_data);

event_hist_trigger_init() can only fail on alloc_hist_pad() returning
-ENOMEM. Forcing that, with this patch applied:

  BUG: KASAN: slab-use-after-free in find_named_trigger+0xac/0xc0
  Read of size 8 at addr ffff888009346860 by task init/1
   find_named_trigger+0xac/0xc0
   hist_register_trigger+0xc1/0xa00
   event_hist_trigger_parse+0x3146/0x6af0
   event_trigger_write+0xce/0x160
  Freed by task 67:
   kfree+0x154/0x420
   trigger_kthread_fn+0xfd/0x160

> If hist_trigger_enable() fails, it drops the trigger from the local file
> list but then we jump to out_unreg. Because the trigger is no longer in
> file->triggers, event_trigger_unregister() won't find it and skips calling
> cmd_ops->free() (which would normally call del_named_trigger()).
>
> The code then falls through to trigger_data_free(). Does this manually
> free the memory without ever calling del_named_trigger(), leaving a freed
> node on the global named_triggers list?

Yes. hist_trigger_enable() removes the trigger from file->triggers before
returning the error, so the list walk in hist_unregister_trigger() matches
nothing, test stays NULL, cmd_ops->free() is not called and
del_named_trigger() never runs. Forcing trace_event_enable_disable() to
fail for a named trigger:

  BUG: KASAN: slab-use-after-free in find_named_trigger+0xac/0xc0
  Read of size 8 at addr ffff8880091d3160 by task init/1
   find_named_trigger+0xac/0xc0
   hist_register_trigger+0xc1/0xa00
   event_hist_trigger_parse+0x3146/0x6af0
   event_trigger_write+0xce/0x160
  Freed by task 69:
   kfree+0x154/0x420
   trigger_kthread_fn+0xfd/0x160

A control run with no injected failure is clean on both.

Both fixed here:

  
https://lore.kernel.org/linux-trace-kernel/[email protected]/

Reply via email to