Re: [PATCH v3] perf/core: Fix refcount bug and potential UAF in perf_mmap

From: Peter Zijlstra

Date: Wed Mar 25 2026 - 11:52:32 EST



Argh,. why is this hidden in this old thread :/

On Wed, Mar 25, 2026 at 06:20:53PM +0800, yuhaocheng035@xxxxxxxxx wrote:

> diff --git a/kernel/events/core.c b/kernel/events/core.c
> index 2c35acc2722b..a3228c587de1 100644
> --- a/kernel/events/core.c
> +++ b/kernel/events/core.c
> @@ -6730,9 +6730,10 @@ static void perf_pmu_output_stop(struct perf_event *event);
> * the buffer here, where we still have a VM context. This means we need
> * to detach all events redirecting to us.
> */
> -static void perf_mmap_close(struct vm_area_struct *vma)
> +static void __perf_mmap_close(struct vm_area_struct *vma, struct perf_event *event,
> + bool holds_event_mmap_lock)
> {
> - struct perf_event *event = vma->vm_file->private_data;
> + struct perf_event *iter_event;
> mapped_f unmapped = get_mapped(event, event_unmapped);
> struct perf_buffer *rb = ring_buffer_get(event);
> struct user_struct *mmap_user = rb->mmap_user;
> @@ -6772,11 +6773,14 @@ static void perf_mmap_close(struct vm_area_struct *vma)
> if (refcount_dec_and_test(&rb->mmap_count))
> detach_rest = true;
>
> - if (!refcount_dec_and_mutex_lock(&event->mmap_count, &event->mmap_mutex))
> + if ((!holds_event_mmap_lock &&
> + !refcount_dec_and_mutex_lock(&event->mmap_count, &event->mmap_mutex)) ||
> + (holds_event_mmap_lock && !refcount_dec_and_test(&event->mmap_count)))
> goto out_put;

*groan*, this is horrible.

Let me have a poke to see if there isn't a saner variant around.