]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
mm/mremap: do not incorrectly reference invalid VMA in VM_WARN_ON_ONCE()
authorLorenzo Stoakes <lorenzo.stoakes@oracle.com>
Sat, 16 Aug 2025 07:37:41 +0000 (08:37 +0100)
committerAndrew Morton <akpm@linux-foundation.org>
Mon, 18 Aug 2025 05:07:56 +0000 (22:07 -0700)
The VMA which is referenced here may have since been merged (which is the
entire point of the warning), and yet we still reference it.

Fix this by storing whether or not a multi move is permitted ahead of time
and have the VM_WARN_ON_ONCE() be predicated on this.

Link: https://lkml.kernel.org/r/b6dbda20-667e-4053-abae-8ed4fa84bb6c@lucifer.local
Reported-by: syzbot+4e221abf50259362f4f4@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/linux-mm/689ff5f6.050a0220.e29e5.0030.GAE@google.com/
Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Reviewed-by: Vlastimil Babka <vbabka@suse.cz>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
mm/mremap.c

index 18aa0b3b828fe531b71dd380df8a9fea908bd387..33b642076205db1789fe90b5da4b25931e8591f8 100644 (file)
@@ -1837,6 +1837,7 @@ static unsigned long remap_move(struct vma_remap_struct *vrm)
                unsigned long addr = max(vma->vm_start, start);
                unsigned long len = min(end, vma->vm_end) - addr;
                unsigned long offset, res_vma;
+               bool multi_allowed;
 
                /* No gap permitted at the start of the range. */
                if (!seen_vma && start < vma->vm_start)
@@ -1865,7 +1866,8 @@ static unsigned long remap_move(struct vma_remap_struct *vrm)
                vrm->new_addr = target_addr + offset;
                vrm->old_len = vrm->new_len = len;
 
-               if (!vma_multi_allowed(vma)) {
+               multi_allowed = vma_multi_allowed(vma);
+               if (!multi_allowed) {
                        /* This is not the first VMA, abort immediately. */
                        if (seen_vma)
                                return -EFAULT;
@@ -1881,8 +1883,7 @@ static unsigned long remap_move(struct vma_remap_struct *vrm)
                        return res_vma;
 
                if (!seen_vma) {
-                       VM_WARN_ON_ONCE(vma_multi_allowed(vma) &&
-                                       res_vma != new_addr);
+                       VM_WARN_ON_ONCE(multi_allowed && res_vma != new_addr);
                        res = res_vma;
                }