From: Peter Zijlstra <peterz@infradead.org>
To: Will Rosenberg <whrosenb@asu.edu>
Cc: yi1.lai@linux.intel.com, Ingo Molnar <mingo@redhat.com>,
Arnaldo Carvalho de Melo <acme@kernel.org>,
Namhyung Kim <namhyung@kernel.org>,
Mark Rutland <mark.rutland@arm.com>,
Alexander Shishkin <alexander.shishkin@linux.intel.com>,
Jiri Olsa <jolsa@kernel.org>, Ian Rogers <irogers@google.com>,
Adrian Hunter <adrian.hunter@intel.com>,
James Clark <james.clark@linaro.org>,
Lorenzo Stoakes <lorenzo.stoakes@oracle.com>,
Thomas Gleixner <tglx@linutronix.de>,
"open list:PERFORMANCE EVENTS SUBSYSTEM"
<linux-perf-users@vger.kernel.org>,
"open list:PERFORMANCE EVENTS SUBSYSTEM"
<linux-kernel@vger.kernel.org>
Subject: Re: [PATCH v2] perf: Fix refcount warning on event->mmap_count increment
Date: Tue, 6 Jan 2026 10:34:31 +0100 [thread overview]
Message-ID: <20260106093431.GA3707837@noisy.programming.kicks-ass.net> (raw)
In-Reply-To: <20260105165149.30200-1-whrosenb@asu.edu>
On Mon, Jan 05, 2026 at 09:51:49AM -0700, Will Rosenberg wrote:
> When calling refcount_inc(&event->mmap_count) inside perf_mmap_rb(), the
> following warning is triggered:
>
> refcount_t: addition on 0; use-after-free.
> WARNING: lib/refcount.c:25
>
> PoC:
>
> struct perf_event_attr attr = {0};
> int fd = syscall(__NR_perf_event_open, &attr, 0, -1, -1, 0);
> mmap(NULL, 0x3000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
> int victim = syscall(__NR_perf_event_open, &attr, 0, -1, fd,
> PERF_FLAG_FD_OUTPUT);
> mmap(NULL, 0x3000, PROT_READ | PROT_WRITE, MAP_SHARED, victim, 0);
>
> This occurs when creating a group member event with the flag
> PERF_FLAG_FD_OUTPUT. The group leader should be mmap-ed and then mmap-ing
> the event triggers the warning.
>
> Since the event has copied the output_event in perf_event_set_output(),
> event->rb is set. As a result, perf_mmap_rb() calls
> refcount_inc(&event->mmap_count) when event->mmap_count = 0.
>
> Account for the case when event->mmap_count = 0. This patch goes against
> the design philosophy of the refcount library by re-enabling an empty
> refcount, but the patch remains inline with the current treatment of
> mmap_count.
>
> Fixes: 448f97fba901 ("perf: Convert mmap() refcounts to refcount_t")
> Signed-off-by: Will Rosenberg <whrosenb@asu.edu>
> ---
>
> Notes:
> v1 -> v2: Add Fixes tag
>
> I also have a related concern about code that handles the mmap_count.
> In perf_mmap_close(), if refcount_dec_and_mutex_lock() decrements
> event->mmap_count to zero, then event->rb is set to NULL. This
> effectively undos our ring buffer copy. However, is this desired
> behavior? Should event->rb remain unchanged since it may still be
> mmap-ed by other events and can still be used?
>
> kernel/events/core.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/kernel/events/core.c b/kernel/events/core.c
> index 376fb07d869b..49709b627b1f 100644
> --- a/kernel/events/core.c
> +++ b/kernel/events/core.c
> @@ -7279,7 +7279,8 @@ static int perf_mmap_rb(struct vm_area_struct *vma, struct perf_event *event,
> * multiple times.
> */
> perf_mmap_account(vma, user_extra, extra);
> - refcount_inc(&event->mmap_count);
> + if (!refcount_inc_not_zero(&event->mmap_count))
> + refcount_set(&event->mmap_count, 1);
So this pattern was an instant red flag; this cannot be right.
Yes, this makes the error go away, but I think the result is bad.
The sequence as provided will create a mapping for event fd, and create
victim such that its events are redirected to this buffer.
So far so good.
However, the mmap() of victim will create an alias of the earlier buffer
(which is pointless but isn't a problem per-se), but by setting
event->mmap_count, you're saying this second event should also update
the user_page (struct perf_event_mmap_page at offset +0).
This means that if you make this succeed you end up with both events
(fd, victim) writing to the same page (which is mapped twice). And that
is broken.
I'm thinking we should dis-allow this mmap()... something like so, hmm?
---
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 3c2a491200c6..ccf3aecbfff5 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -7273,6 +7273,15 @@ static int perf_mmap_rb(struct vm_area_struct *vma, struct perf_event *event,
if (data_page_nr(event->rb) != nr_pages)
return -EINVAL;
+ /*
+ * If this event doesn't have mmap_count, we're attempting to
+ * create an alias of another event's mmap(); this would mean
+ * both events will end up scribbling the same user_page;
+ * which makes no sense.
+ */
+ if (refcount_read(&event->mmap_count))
+ return -EBUSY;
+
if (refcount_inc_not_zero(&event->rb->mmap_count)) {
/*
* Success -- managed to mmap() the same buffer
next prev parent reply other threads:[~2026-01-06 9:34 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-12-29 21:03 [PATCH] perf: Fix refcount warning on event->mmap_count increment Will Rosenberg
2026-01-05 8:47 ` Lai, Yi
2026-01-05 16:51 ` [PATCH v2] " Will Rosenberg
2026-01-06 9:34 ` Peter Zijlstra [this message]
2026-01-06 20:35 ` [PATCH v3] " Will Rosenberg
2026-01-19 18:49 ` [PATCH v3 RESEND] " Will Rosenberg
2026-01-20 12:23 ` Peter Zijlstra
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=20260106093431.GA3707837@noisy.programming.kicks-ass.net \
--to=peterz@infradead.org \
--cc=acme@kernel.org \
--cc=adrian.hunter@intel.com \
--cc=alexander.shishkin@linux.intel.com \
--cc=irogers@google.com \
--cc=james.clark@linaro.org \
--cc=jolsa@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=lorenzo.stoakes@oracle.com \
--cc=mark.rutland@arm.com \
--cc=mingo@redhat.com \
--cc=namhyung@kernel.org \
--cc=tglx@linutronix.de \
--cc=whrosenb@asu.edu \
--cc=yi1.lai@linux.intel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox