From: Hui Peng <benquike@gmail.com>
To: peterz@infradead.org, mingo@redhat.com, acme@kernel.org,
namhyung@kernel.org, mark.rutland@arm.com,
alexander.shishkin@linux.intel.com, jolsa@kernel.org,
irogers@google.com
Cc: linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH] perf/core: fix locked_vm leak on alias mmap() and cross-MM pinned_vm underflow
Date: Sat, 19 Sep 2026 22:17:28 +0000 [thread overview]
Message-ID: <20260919221728.3707189-1-benquike@gmail.com> (raw)
In perf_mmap(), mapping an output ring buffer onto an event via
PERF_EVENT_IOC_SET_OUTPUT / alias mmap() increments user->locked_vm and
mm->pinned_vm without recording the accounting MM on the ring_buffer or
releasing user_extra onperf_mmap_close(), causing a permanent locked_vm
leak and a cross-MM pinned_vm underflow when the mapping is closed in a
different process. Store the accounted mm_struct on struct perf_buffer
and unaccount against the original mm_struct on close.
Fixes: fae85b7c8bcc ("perf: Start the restructuring")
Assisted-by: LLM
Signed-off-by: Hui Peng <benquike@gmail.com>
---
diff --git a/kernel/events/core.c b/kernel/events/core.c
index fe33fe15689d..2be9301dcd7c 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -7050,7 +7050,11 @@ static void perf_mmap_close(struct vm_area_struct *vma)
/* now it's safe to free the pages */
atomic_long_sub(rb->aux_nr_pages - rb->aux_mmap_locked, &mmap_user->locked_vm);
- atomic64_sub(rb->aux_mmap_locked, &vma->vm_mm->pinned_vm);
+ if (rb->aux_mmap_mm) {
+ atomic64_sub(rb->aux_mmap_locked, &rb->aux_mmap_mm->pinned_vm);
+ mmdrop(rb->aux_mmap_mm);
+ rb->aux_mmap_mm = NULL;
+ }
/* this has to be the last one */
rb_free_aux(rb);
@@ -7272,7 +7276,7 @@ static void perf_mmap_unaccount(struct vm_area_struct *vma, struct perf_buffer *
atomic_long_sub((perf_data_size(rb) >> PAGE_SHIFT) + 1 - rb->mmap_locked,
&user->locked_vm);
- atomic64_sub(rb->mmap_locked, &vma->vm_mm->pinned_vm);
+ atomic64_sub(rb->mmap_locked, &rb->mmap_mm->pinned_vm);
}
static int perf_mmap_rb(struct vm_area_struct *vma, struct perf_event *event,
@@ -7311,7 +7315,6 @@ static int perf_mmap_rb(struct vm_area_struct *vma, struct perf_event *event,
* Success -- managed to mmap() the same buffer
* multiple times.
*/
- perf_mmap_account(vma, user_extra, extra);
refcount_inc(&event->mmap_count);
return 0;
}
@@ -7338,6 +7341,8 @@ static int perf_mmap_rb(struct vm_area_struct *vma, struct perf_event *event,
return -ENOMEM;
rb->mmap_locked = extra;
+ rb->mmap_mm = vma->vm_mm;
+ mmgrab(rb->mmap_mm);
ring_buffer_attach(event, rb);
@@ -7399,7 +7404,8 @@ static int perf_mmap_aux(struct vm_area_struct *vma, struct perf_event *event,
if (rb_has_aux(rb)) {
refcount_inc(&rb->aux_mmap_count);
-
+ user_extra = 0;
+ extra = 0;
} else {
if (!perf_mmap_calc_limits(vma, &user_extra, &extra)) {
refcount_dec(&rb->mmap_count);
@@ -7420,6 +7426,8 @@ static int perf_mmap_aux(struct vm_area_struct *vma, struct perf_event *event,
refcount_set(&rb->aux_mmap_count, 1);
rb->aux_mmap_locked = extra;
+ rb->aux_mmap_mm = vma->vm_mm;
+ mmgrab(rb->aux_mmap_mm);
}
perf_mmap_account(vma, user_extra, extra);
diff --git a/kernel/events/internal.h b/kernel/events/internal.h
index c03c4f2eea57..f10eacd8b590 100644
--- a/kernel/events/internal.h
+++ b/kernel/events/internal.h
@@ -5,6 +5,7 @@
#include <linux/hardirq.h>
#include <linux/uaccess.h>
#include <linux/refcount.h>
+#include <linux/sched/mm.h>
/* Buffer handling */
@@ -38,6 +39,8 @@ struct perf_buffer {
refcount_t mmap_count;
unsigned long mmap_locked;
struct user_struct *mmap_user;
+ struct mm_struct *mmap_mm;
+ struct mm_struct *aux_mmap_mm;
/* AUX area */
struct mutex aux_mutex;
@@ -67,6 +70,10 @@ static inline void rb_free_rcu(struct rcu_head *rcu_head)
struct perf_buffer *rb;
rb = container_of(rcu_head, struct perf_buffer, rcu_head);
+ if (rb->aux_mmap_mm)
+ mmdrop(rb->aux_mmap_mm);
+ if (rb->mmap_mm)
+ mmdrop(rb->mmap_mm);
free_uid(rb->mmap_user);
rb_free(rb);
}
next reply other threads:[~2026-09-19 22:17 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-19 22:17 Hui Peng [this message]
2026-09-19 22:31 ` [PATCH] perf/core: fix locked_vm leak on alias mmap() and cross-MM pinned_vm underflow sashiko-bot
2026-09-21 0:33 ` [PATCH v2] perf/core: fix user->locked_vm leak on secondary mmap() Hui Peng
2026-09-21 0:41 ` sashiko-bot
2026-09-21 15:10 ` krzk
2026-09-21 15:13 ` krzk
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=20260919221728.3707189-1-benquike@gmail.com \
--to=benquike@gmail.com \
--cc=acme@kernel.org \
--cc=alexander.shishkin@linux.intel.com \
--cc=irogers@google.com \
--cc=jolsa@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=mingo@redhat.com \
--cc=namhyung@kernel.org \
--cc=peterz@infradead.org \
/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.