diff options
| author | Lee Jia Jie <jiajie.lee@starlabs.sg> | 2026-07-09 21:56:19 +0800 |
|---|---|---|
| committer | Ingo Molnar <mingo@kernel.org> | 2026-07-10 12:12:24 +0200 |
| commit | 5948aaf64f81f217a25dcc2bf6c0779bca19566c (patch) | |
| tree | 56c00d2b0465ed08cccf93b3fd4f918002c79703 /rust/zerocopy/src/pointer/git@git.tavy.me:linux-stable.git | |
| parent | 07c60dda9c059c09f83d42a3ebda2e7cc1cf3bc2 (diff) | |
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@starlabs.sg>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: stable@vger.kernel.org
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Diffstat (limited to 'rust/zerocopy/src/pointer/git@git.tavy.me:linux-stable.git')
0 files changed, 0 insertions, 0 deletions
