All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] mm/vma: restore VMA iterator on full-range merge failure
@ 2026-11-14 16:46 shao.mingyin
  2026-11-14 17:14 ` Lorenzo Stoakes (ARM)
  0 siblings, 1 reply; 2+ messages in thread
From: shao.mingyin @ 2026-11-14 16:46 UTC (permalink / raw)
  To: akpm, liam, ljs; +Cc: linux-mm, vbabka, jannh, pfalcato, linux-kernel

From: Shao Mingyin <shao.mingyin@zte.com.cn>

mm/vma: restore VMA iterator on full-range merge failure

vma_merge_existing_range() moves the iterator to the previous VMA when
merging to the left. If the range spans the whole middle VMA and a
vm_ops->close() hook prevents removing it, the function returns without
restoring the iterator.

An mprotect() walk can then visit the middle VMA again. Restore the
iterator to the range start, as the abort path already does. Extend the
existing close-hook merge test to check the iterator after this failure.
No crash or data corruption has been observed in this case.

Fixes: 01c373e9a5ce2 ("mm: rework vm_ops->close() handling on VMA merge")
Signed-off-by: Shao Mingyin <shao.mingyin@zte.com.cn>
---
Tested with tools/testing/vma using its default ASan/UBSan options.
The added iterator assertion fails before the fix; all 29 tests pass
with the fix. Also build-tested mm/vma.o with W=1 on x86_64.
This verifies iterator position, not a crash or a production workload.


 mm/vma.c                        | 5 ++++-
 tools/testing/vma/tests/merge.c | 1 +
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/mm/vma.c b/mm/vma.c
index c82e9306b11ac14f684f44b8d71a0026b7fc145c..c87b29f1beec4ceb02c23f6b37af0e5dff272436 100644
--- a/mm/vma.c
+++ b/mm/vma.c
@@ -983,8 +983,11 @@ static __must_check struct vm_area_struct *vma_merge_existing_range(
 	 * If we need to remove middle in its entirety but are unable to do so,
 	 * we have no sensible recourse but to abort the merge.
 	 */
-	if (vmg->__remove_middle && !can_merge_remove_vma(middle))
+	if (vmg->__remove_middle && !can_merge_remove_vma(middle)) {
+		vma_iter_set(vmg->vmi, start);
+		vma_iter_load(vmg->vmi);
 		return NULL;
+	}
 
 	/* If middle isn't removed then it's resized, i.e. splits. */
 	if (!vmg->__remove_middle && check_split(middle, left_side ? end : start))
diff --git a/tools/testing/vma/tests/merge.c b/tools/testing/vma/tests/merge.c
index b26f1a66a17074775d751a907eb627445cc1dda3..91accb5dc9944724cd11d1bfa47484a3cf9df54c 100644
--- a/tools/testing/vma/tests/merge.c
+++ b/tools/testing/vma/tests/merge.c
@@ -680,6 +680,7 @@ static bool test_vma_merge_with_close(void)
 	 */
 	ASSERT_EQ(merge_existing(&vmg), NULL);
 	ASSERT_EQ(vmg.state, VMA_MERGE_NOMERGE);
+	ASSERT_EQ(vma_iter_addr(&vmi), 0x3000);
 
 	ASSERT_EQ(cleanup_mm(&mm, &vmi), 2);
 

base-commit: 84abb955b1015477aa11a96e2f3ac1b938b77f48
-- 
2.43.0

^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-11-14 17:14 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-14 16:46 [PATCH] mm/vma: restore VMA iterator on full-range merge failure shao.mingyin
2026-11-14 17:14 ` Lorenzo Stoakes (ARM)

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.