[PATCH] mm: nommu: free unused resources when mremap shrinks the vma

From: Hajime Tazaki

Date: Thu Jul 09 2026 - 22:10:38 EST


WIP:

When shrinking a VMA via mremap, the bounds are modified directly:
mm/nommu.c:do_mremap() {
...
vma->vm_end = vma->vm_start + new_len;
...
}
This shrink the VMA without updating its bounds in the maple tree.
If the maple tree (mm->mm_mt) still contains the old bounds, a user
process could access the freed portion. The stale maple tree would
incorrectly return the shrunk VMA for an address past its new vm_end.

This commit fixes this issue by calling vmi_shrink_vma() when shrink
happens.

Link: https://sashiko.dev/#/patchset/20260702012546.665383-1-thehajime@xxxxxxxxx
Signed-off-by: Hajime Tazaki <thehajime@xxxxxxxxx>
---
mm/nommu.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/mm/nommu.c b/mm/nommu.c
index 852ec9bd0505..10794e3b6be9 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -1598,7 +1598,17 @@ static unsigned long do_mremap(unsigned long addr,
return (unsigned long) -ENOMEM;

/* all checks complete - do it */
- vma->vm_end = vma->vm_start + new_len;
+ if (new_len < old_len) {
+ /* shrink only happens addr + new_len and old_len are in different pages */
+ VMA_ITERATOR(vmi, current->mm, addr);
+ /* vmi_shrink_vma() needs from/to pointers to be removed,
+ * (mainly used in munmap) so, specify them.
+ */
+ vmi_shrink_vma(&vmi, vma, addr + new_len, addr + old_len);
+ } else {
+ /* when there are no shrink, update vma. */
+ vma->vm_end = vma->vm_start + new_len;
+ }
return vma->vm_start;
}

--
2.43.0