[PATCH 0/2] mm/mremap: fix two issues with MREMAP_DONTUNMAP

From: Lorenzo Stoakes (ARM)

Date: Sun Sep 20 2026 - 10:14:10 EST


The MREMAP_DONTUNMAP feature is highly unusual in that it permits mremap()
operations that keep the original VMA in place.

Historically this has led to a lot of bugs where non-obvious interactions
occur between existing mremap() operations and the original VMA.

Commit 397432cab17b ("mm/mremap: account mm->locked_vm correctly for
MREMAP_DONTUNMAP") fixed an accidentally introduced bug around
mm->locked_vm accounting, but this wasn't the only issue.

And thus history repeats itself, as it turns out that mm->locked_vm
accounting is broken by MREMAP_DONTUNMAP yet again by two further cases,
and has been broken ever since the feature was introduced.

Both relate to the fact that VMA_LOCKED_BIT is cleared on the source
VMA (it has to be as all page tables are moved):

1. If an unfaulted VMA_LOCKONFAULT_BIT anonymous VMA self-merges it
clears the VMA_LOCKED_BIT flag and permanently leaks mm->locked_vm
pages.

2. If a partial mremap() is performed on a locked VMA there is a leak equal
to the number of pages not copied.

(Both for MREMAP_DONTUNMAP operations only)

Both issues can be fixed by treating the source range as distinct from the
destination range, which is the definition of what MREMAP_DONTUNMAP does so
is appropriate.

In case 1, simply disallow the self-merge, keeping adjacent source and
destination VMAs distinct.

In case 2, split the source range ahead of time, so accounting is always
correct.

Both changes were tested locally and confirmed to fix the issues.

For the purposes of a backport, the fixes are kept distinct, a follow-up
series can add self-tests.

Signed-off-by: Lorenzo Stoakes (ARM) <ljs@xxxxxxxxxx>
---
Lorenzo Stoakes (ARM) (2):
mm/mremap: fix locked_vm leak from MREMAP_DONTUNMAP self-merge
mm/mremap: fix locked_vm leak by splitting VMA for MREMAP_DONTUNMAP

mm/mremap.c | 87 +++++++++++++++++++++++++++----------------
mm/vma.c | 19 +++++++++-
mm/vma.h | 7 +++-
tools/testing/vma/tests/vma.c | 10 ++---
4 files changed, 83 insertions(+), 40 deletions(-)
---
base-commit: a3d0117e02bfa1c3bb6c50e7afe42bbecdbb3459
change-id: 20260920-fix-dontunmap-partial-self-merge-74a98b1d5a65

Best regards,
--
Lorenzo Stoakes (ARM) <ljs@xxxxxxxxxx>