Re: [PATCH v2 0/2] mm/mremap: fix two issues with MREMAP_DONTUNMAP
From: Anirudh Srinivasan
Date: Wed Sep 30 2026 - 17:33:08 EST
On Wed, Sep 30, 2026 at 1:47 PM Lorenzo Stoakes (ARM) <ljs@xxxxxxxxxx> wrote:
>
> 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 if the VMA is mlock()'d, 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>
> ---
> v2:
> * Added tags (thanks everybody!)
> * Updated 2/2 to avoid splitting the VMA if the VMA was not mlock()'d. It
> is only meaningful and necessary to perform the split in this case. This
> also fixes the proc_maps_race selftests that broke, as reported by
> Anirudh.
>
> v1:
> https://lore.kernel.org/r/20260920-fix-dontunmap-partial-self-merge-v1-0-6ffb556f8f8b@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 | 70 ++++++++++++++++++++++++++++++++-----------
> mm/vma.c | 21 +++++++++++--
> mm/vma.h | 7 ++++-
> tools/testing/vma/tests/vma.c | 10 +++----
> 4 files changed, 81 insertions(+), 27 deletions(-)
Thanks, the selftests are passing now.
Tested-by: Anirudh Srinivasan <asrinivasan@xxxxxxxxxxxxxxxxxxx>
Regards
Anirudh Srinivasan