From: sashiko-bot@kernel.org
To: vineash <vineash30640@gmail.com>
Cc: linux-perf-users@vger.kernel.org
Subject: Re: [PATCH] perf/core: Fix double put of the system-wide perf_ctx_data reference
Date: Sat, 03 Oct 2026 20:30:40 +0000 [thread overview]
Message-ID: <20261003203040.EE6631F0089B@smtp.kernel.org> (raw)
In-Reply-To: <179105852659.1844849.16381123619267169417@gmail.com>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] perf/core: memory leak of perf_ctx_data due to TOCTOU race in attach_global_ctx_data()
- [Medium] perf/core: data race on cd->global leading to undefined behavior
--
commit 6c40093668f0aa28205d435b7cecaca312682e03
Author: vineash <vineash30640@gmail.com>
perf/core: Fix double put of the system-wide perf_ctx_data reference
The reference on a task's perf_ctx_data that belongs to the system-wide
events (cd->global) can be put twice. __detach_global_ctx_data() puts it
when the last system-wide event goes away, and perf_event_exit_task()
puts it again when the task exits.
> diff --git a/kernel/events/core.c b/kernel/events/core.c
> index a34ff4cb410da..63122c3b872ef 100644
> --- a/kernel/events/core.c
> +++ b/kernel/events/core.c
> @@ -5498,8 +5498,9 @@ attach_global_ctx_data(struct kmem_cache *ctx_cache)
> continue;
> cd = rcu_dereference(p->perf_ctx_data);
> if (cd && !cd->global) {
> - cd->global = 1;
> - if (!refcount_inc_not_zero(&cd->refcount))
> + if (refcount_inc_not_zero(&cd->refcount))
> + cd->global = 1;
[Severity: High]
Does this introduce a TOCTOU race condition that can leak the perf_ctx_data
reference?
Earlier in attach_global_ctx_data(), the code checks if the task is exiting
without holding locks that exclude do_exit():
if (p->flags & PF_EXITING)
continue;
Could a task concurrently set PF_EXITING and call perf_event_exit_task(),
which then calls detach_task_global_ctx_data()?
If so, the exiting task would observe cd->global == 0 via xchg(), miss the
cleanup, and return. Then this code continues, increments cd->refcount, and
sets cd->global = 1. Because the exiting task has already bypassed the
cleanup phase, it will never drop this reference. Once the task is unhashed,
__detach_global_ctx_data() will not find it, resulting in a permanent
memory leak of the perf_ctx_data structure.
A local user with perf_event_paranoid=2 might trigger this by racing
CPU-wide perf event creation with task exits.
[Severity: Medium]
Does this plain store to cd->global race with the atomic xchg() operation in
detach_task_global_ctx_data() from an exiting task?
Because perf_event_exit_task() executes without holding global_ctx_data_rwsem,
these accesses appear unsynchronized, which violates the Linux Kernel Memory
Model and can lead to undefined behavior.
> + else
> cd = NULL;
> }
> if (!cd) {
[ ... ]
> @@ -5569,19 +5570,33 @@ detach_task_ctx_data(struct task_struct *p)
> perf_free_ctx_data_rcu(cd);
> }
>
> +/*
> + * Drop the reference owned by the system-wide events, if @p still holds one.
> + *
> + * Both __detach_global_ctx_data() and perf_event_exit_task() may try to drop
> + * it concurrently; claiming ->global with xchg() makes sure only one of them
> + * does, otherwise the refcount is decremented twice.
> + */
> +static void detach_task_global_ctx_data(struct task_struct *p)
> +{
> + struct perf_ctx_data *cd;
> +
> + scoped_guard (rcu) {
> + cd = rcu_dereference(p->perf_ctx_data);
> + if (!cd || !xchg(&cd->global, 0))
> + return;
> + }
> +
> + detach_task_ctx_data(p);
> +}
[ ... ]
> @@ -9459,8 +9474,8 @@ perf_event_alloc_task_data(struct task_struct *child,
> }
>
> if (!cd->global) {
> - cd->global = 1;
> refcount_inc(&cd->refcount);
> + cd->global = 1;
[Severity: Medium]
Similar to the concern in attach_global_ctx_data(), does this plain store
to cd->global race with the atomic xchg() operation from an exiting task in
detach_task_global_ctx_data()?
> }
> }
>
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/179105852659.1844849.16381123619267169417@gmail.com?part=1
prev parent reply other threads:[~2026-10-03 20:30 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-03 20:15 [PATCH] perf/core: Fix double put of the system-wide perf_ctx_data reference vineash
2026-10-03 20:30 ` 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=20261003203040.EE6631F0089B@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
--cc=vineash30640@gmail.com \
/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.