All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "David Carlier" <devnexen@gmail.com>
Cc: linux-trace-kernel@vger.kernel.org
Subject: Re: [PATCH] tracing/user_events: Don't free an event that a dynamic event still references
Date: Sat, 31 Oct 2026 21:15:49 +0000	[thread overview]
Message-ID: <sashiko-outbox-192162@kernel.org> (raw)
In-Reply-To: <20261031210420.501187-1-devnexen@gmail.com>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] tracing/user_events: permanent leak of non-persistent event in destroy_user_event()
--

commit 426e76d7362e855d5b85cce6bb2e395443a0a474
Author: David Carlier <devnexen@gmail.com>

tracing/user_events: Don't free an event that a dynamic event still references

This commit prevents destroy_user_event() from freeing a user_event while a
dynamic event still holds a reference on user->call by checking
trace_event_dyn_busy(&user->call) and returning -EBUSY.

> diff --git a/kernel/trace/trace_events_user.c b/kernel/trace/trace_events_user.c
> index f658c3a77aa7a..49b857a7f1d78 100644
> --- a/kernel/trace/trace_events_user.c
> +++ b/kernel/trace/trace_events_user.c
> @@ -1506,6 +1506,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;

[Severity: High]
Does returning -EBUSY here cause non-persistent user_event instances to leak
and become permanently undeletable if their last reference is dropped while
user->call.refcnt is non-zero?

When a non-persistent event is created via DIAG_IOCSREG without
USER_EVENT_REG_PERSIST, user->refcnt tracks active user and probe references.
If a dynamic event consumer holds a reference on user->call (such as an
eprobe via find_and_get_event(), a histogram action via
trace_get_event_file(), or an enable_event trigger during teardown in
event_enable_trigger_free() before trigger_kthread runs
enable_trigger_private_data_free()) when the last user->refcnt reference is
dropped in user_event_put(), delayed_destroy_user_event() runs:

kernel/trace/trace_events_user.c:delayed_destroy_user_event() {
	...
	if (!refcount_dec_and_test(&user->refcnt))
		goto out;

	if (destroy_user_event(user)) {
		...
		pr_warn("user_events: Unable to delete event\n");
		refcount_set(&user->refcnt, 1);
	}
out:
	mutex_unlock(&event_mutex);
}

Because destroy_user_event() now returns -EBUSY, delayed_destroy_user_event()
resets user->refcnt to 1 without setting USER_EVENT_REG_PERSIST in
user->reg_flags, and with no owner holding that reference.

Once the eprobe or trigger later drops its reference on user->call, how can
this user_event ever be freed?

1. Manual deletion via dynamic_events in user_event_free(), via DIAG_IOCSDEL
in delete_user_event(), or via dyn_events_release_all() ->
user_event_is_busy() all check user_event_last_ref():

kernel/trace/trace_events_user.c:user_event_last_ref() {
	int last = 0;

	if (user->reg_flags & USER_EVENT_REG_PERSIST)
		last = 1;

	return refcount_read(&user->refcnt) == last;
}

Because USER_EVENT_REG_PERSIST is not set, user_event_last_ref() requires
user->refcnt to be 0, so manual deletion permanently fails with -EBUSY.

2. Re-opening and closing the event increments user->refcnt from 1 to 2 and
decrements it back to 1 in user_event_put(), never reaching 0 to re-queue
delayed_destroy_user_event().

As a result, the struct user_event, its fields and validators, its tracefs
entry, and a current_user_events quota slot appear to be leaked until reboot.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261031210420.501187-1-devnexen@gmail.com?part=1

      reply	other threads:[~2026-10-31 21:15 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-31 21:03 [PATCH] tracing/user_events: Don't free an event that a dynamic event still references David Carlier
2026-10-31 21:15 ` sashiko-bot [this message]

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=sashiko-outbox-192162@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=devnexen@gmail.com \
    --cc=linux-trace-kernel@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /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.