Skip to content

Commit a57b705

Browse files
howlettakpm00
authored andcommitted
mm/mmap: fix MAP_FIXED address return on VMA merge
mmap should return the start address of newly mapped area when successful. On a successful merge of a VMA, the return address was changed and thus was violating that expectation from userspace. This is a restoration of functionality provided by 309d08d (mm/mmap.c: fix mmap return value when vma is merged after call_mmap()). For completeness of fixing MAP_FIXED, implement the comments from the previous discussion to never update the address and fail if the address changes. Leaving the error as a WARN_ON() to avoid crashing the kernel. Link: https://lkml.kernel.org/r/[email protected] Link: https://lore.kernel.org/all/Y06yk66SKxlrwwfb@lakrids/ Link: https://lore.kernel.org/all/[email protected]/ Fixes: 4dd1b84 ("mm/mmap: use advanced maple tree API for mmap_region()") Signed-off-by: Liam R. Howlett <[email protected]> Reported-by: Mark Rutland <[email protected]> Cc: Liu Zixian <[email protected]> Cc: David Hildenbrand <[email protected]> Cc: Jason Gunthorpe <[email protected]> Cc: Matthew Wilcox <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 1cd916d commit a57b705

File tree

1 file changed

+7
-8
lines changed

1 file changed

+7
-8
lines changed

mm/mmap.c

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2626,14 +2626,14 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
26262626
if (error)
26272627
goto unmap_and_free_vma;
26282628

2629-
/* Can addr have changed??
2630-
*
2631-
* Answer: Yes, several device drivers can do it in their
2632-
* f_op->mmap method. -DaveM
2629+
/*
2630+
* Expansion is handled above, merging is handled below.
2631+
* Drivers should not alter the address of the VMA.
26332632
*/
2634-
WARN_ON_ONCE(addr != vma->vm_start);
2635-
2636-
addr = vma->vm_start;
2633+
if (WARN_ON((addr != vma->vm_start))) {
2634+
error = -EINVAL;
2635+
goto close_and_free_vma;
2636+
}
26372637
mas_reset(&mas);
26382638

26392639
/*
@@ -2655,7 +2655,6 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
26552655
vm_area_free(vma);
26562656
vma = merge;
26572657
/* Update vm_flags to pick up the change. */
2658-
addr = vma->vm_start;
26592658
vm_flags = vma->vm_flags;
26602659
goto unmap_writable;
26612660
}

0 commit comments

Comments
 (0)