From: Hui Peng <benquike@gmail.com>
To: akpm@linux-foundation.org, liam@infradead.org, ljs@kernel.org
Cc: vbabka@kernel.org, jannh@google.com, pfalcato@suse.de,
bgeffon@google.com, linux-mm@kvack.org,
linux-kernel@vger.kernel.org
Subject: [PATCH] mm/mremap: account unmoved locked pages in dontunmap_complete()
Date: Sat, 19 Sep 2026 21:06:12 +0000 [thread overview]
Message-ID: <20260919210612.3028241-1-benquike@gmail.com> (raw)
When MREMAP_DONTUNMAP is performed on a VM_LOCKED VMA,
dontunmap_complete() clears VMA_LOCKED_MASK on the entire source VMA
(vrm->vma) before vrm_stat_account() runs. This assumes that the entire
source VMA was moved into a distinct destination VMA (new_vma != vma) of
equal size, transferring the VM_LOCKED accounting 1:1 from vma to
new_vma.
However, two cases violate this assumption:
1. Partial MREMAP_DONTUNMAP on a multi-page VM_LOCKED VMA (vrm->old_len
< vma->vm_end - vma->vm_start): vma_clear_flags_mask(vma,
VMA_LOCKED_MASK) clears VM_LOCKED on the entire source VMA of size
vma_pages(vma), while new_vma only inherits VM_LOCKED for
vrm->old_len >> PAGE_SHIFT pages. The remaining unmoved pages in vma
lose VM_LOCKED without decrementing mm->locked_vm.
2. Self-merge in copy_vma() (new_vma == vma, when new_addr is
immediately adjacent to vma): copy_vma() expands vma by vrm->new_len,
and dontunmap_complete() then clears VMA_LOCKED_MASK on the combined
VMA. All originally locked pages lose VM_LOCKED without decrementing
mm->locked_vm.
In both cases, subsequent munmap() of the VMAs sees VM_LOCKED cleared
and does not decrement mm->locked_vm, permanently leaking mm->locked_vm
until process exit and allowing unprivileged processes to exhaust
RLIMIT_MEMLOCK.
Fix this in dontunmap_complete() by subtracting the number of pages that
lose VM_LOCKED from current->mm->locked_vm before clearing
VMA_LOCKED_MASK.
Fixes: e346b3813067 ("mm/mremap: add MREMAP_DONTUNMAP to mremap()")
Assisted-by: LLM
Signed-off-by: Hui Peng <benquike@gmail.com>
---
mm/mremap.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/mm/mremap.c b/mm/mremap.c
index 7c368440fafe..ff794e24f78f 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -1335,6 +1335,16 @@ static void dontunmap_complete(struct vma_remap_struct *vrm,
unsigned long old_start = vma->vm_start;
unsigned long old_end = vma->vm_end;
+ if (vma_test(vma, VMA_LOCKED_BIT)) {
+ unsigned long unl_pages = vma_pages(vma);
+
+ if (new_vma != vma)
+ unl_pages -= vrm->old_len >> PAGE_SHIFT;
+ else
+ unl_pages -= vrm->new_len >> PAGE_SHIFT;
+ current->mm->locked_vm -= unl_pages;
+ }
+
/* We always clear VMA_LOCKED[ONFAULT]_BIT on the old VMA. */
vma_clear_flags_mask(vma, VMA_LOCKED_MASK);
--
2.55.0.1082.g2b9226bbc0-goog
next reply other threads:[~2026-09-19 21:06 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-19 21:06 Hui Peng [this message]
2026-09-20 10:15 ` Lorenzo Stoakes (ARM)
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=20260919210612.3028241-1-benquike@gmail.com \
--to=benquike@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=bgeffon@google.com \
--cc=jannh@google.com \
--cc=liam@infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=ljs@kernel.org \
--cc=pfalcato@suse.de \
--cc=vbabka@kernel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®