[tip: perf/urgent] perf/aux: Fix page UAF in map_range()

From: tip-bot2 for Lee Jia Jie

Date: Fri Jul 10 2026 - 06:25:04 EST


The following commit has been merged into the perf/urgent branch of tip:

Commit-ID: 5948aaf64f81f217a25dcc2bf6c0779bca19566c
Gitweb: https://git.kernel.org/tip/5948aaf64f81f217a25dcc2bf6c0779bca19566c
Author: Lee Jia Jie <jiajie.lee@xxxxxxxxxxx>
AuthorDate: Thu, 09 Jul 2026 21:56:19 +08:00
Committer: Ingo Molnar <mingo@xxxxxxxxxx>
CommitterDate: Fri, 10 Jul 2026 12:12:24 +02:00

perf/aux: Fix page UAF in map_range()

map_range() reads rb->aux_pages[], rb->aux_nr_pages and rb->aux_pgoff via
perf_mmap_to_page() while holding only event->mmap_mutex. Those fields are
serialized by rb->aux_mutex, and mmap_mutex is per event.

Thus, two events sharing one rb via PERF_EVENT_IOC_SET_OUTPUT can race
rb_alloc_aux() with map_range(), leading to a page-UAF scenario as follows:

CPU 0 CPU 1
===== =====
rb_alloc_aux() map_range()
[1]: allocate rb->aux_pages[0]
[2]: rb->aux_nr_pages++
[3]: perf_mmap_to_page()
returns rb->aux_pages[0]
[4]: map it as VM_PFNMAP
[5]: rb->aux_pgoff = 1

munmap the page
[6]: free rb->aux_pages[0]

Pages mapped as VM_PFNMAP have no refcount protection, so CPU 1 holds a
mapping to a freed physical frame.

Fix this by taking rb->aux_mutex across the page walk in map_range().

Fixes: b709eb872e19 ("perf: map pages in advance")
Signed-off-by: Lee Jia Jie <jiajie.lee@xxxxxxxxxxx>
Signed-off-by: Ingo Molnar <mingo@xxxxxxxxxx>
Cc: stable@xxxxxxxxxxxxxxx
Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx>
Cc: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>
Cc: Namhyung Kim <namhyung@xxxxxxxxxx>
---
kernel/events/core.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/kernel/events/core.c b/kernel/events/core.c
index d7f3e2c..ba5bd6a 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -7150,6 +7150,8 @@ static int map_range(struct perf_buffer *rb, struct vm_area_struct *vma)
int err = 0;
unsigned long pagenum;

+ guard(mutex)(&rb->aux_mutex);
+
/*
* We map this as a VM_PFNMAP VMA.
*