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 by309d08d9b3
(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/20221018191613.4133459-1-Liam.Howlett@oracle.com Link: https://lore.kernel.org/all/Y06yk66SKxlrwwfb@lakrids/ Link: https://lore.kernel.org/all/20201203085350.22624-1-liuzixian4@huawei.com/ Fixes:4dd1b84140
("mm/mmap: use advanced maple tree API for mmap_region()") Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com> Reported-by: Mark Rutland <mark.rutland@arm.com> Cc: Liu Zixian <liuzixian4@huawei.com> Cc: David Hildenbrand <david@redhat.com> Cc: Jason Gunthorpe <jgg@nvidia.com> Cc: Matthew Wilcox <willy@infradead.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
parent
1cd916d034
commit
a57b70519d
15
mm/mmap.c
15
mm/mmap.c
@ -2626,14 +2626,14 @@ cannot_expand:
|
|||||||
if (error)
|
if (error)
|
||||||
goto unmap_and_free_vma;
|
goto unmap_and_free_vma;
|
||||||
|
|
||||||
/* Can addr have changed??
|
/*
|
||||||
*
|
* Expansion is handled above, merging is handled below.
|
||||||
* Answer: Yes, several device drivers can do it in their
|
* Drivers should not alter the address of the VMA.
|
||||||
* f_op->mmap method. -DaveM
|
|
||||||
*/
|
*/
|
||||||
WARN_ON_ONCE(addr != vma->vm_start);
|
if (WARN_ON((addr != vma->vm_start))) {
|
||||||
|
error = -EINVAL;
|
||||||
addr = vma->vm_start;
|
goto close_and_free_vma;
|
||||||
|
}
|
||||||
mas_reset(&mas);
|
mas_reset(&mas);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2655,7 +2655,6 @@ cannot_expand:
|
|||||||
vm_area_free(vma);
|
vm_area_free(vma);
|
||||||
vma = merge;
|
vma = merge;
|
||||||
/* Update vm_flags to pick up the change. */
|
/* Update vm_flags to pick up the change. */
|
||||||
addr = vma->vm_start;
|
|
||||||
vm_flags = vma->vm_flags;
|
vm_flags = vma->vm_flags;
|
||||||
goto unmap_writable;
|
goto unmap_writable;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user