From: "Liam R. Howlett" <Liam.Howlett@xxxxxxxxxx> mmap_region is already passed sanitized addr and len, so change the call to do_vmi_munmap() to do_vmi_align_munmap() and inline the other checks. Signed-off-by: Liam R. Howlett <Liam.Howlett@xxxxxxxxxx> --- mm/mmap.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/mm/mmap.c b/mm/mmap.c index 8d9be791997a..e9858ca8bbd4 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -2937,12 +2937,20 @@ unsigned long mmap_region(struct file *file, unsigned long addr, return -ENOMEM; } - /* Unmap any existing mapping in the area */ - error = do_vmi_munmap(&vmi, mm, addr, len, uf, false); - if (error == -EPERM) - return error; - else if (error) - return -ENOMEM; + + if (unlikely(!can_modify_mm(mm, addr, end))) + return -EPERM; + + /* arch_unmap() might do unmaps itself. */ + arch_unmap(mm, addr, end); + + /* Find the first overlapping VMA */ + vma = vma_find(&vmi, end); + if (vma) { + if (do_vmi_align_munmap(&vmi, vma, mm, addr, end, uf, false)) + return -ENOMEM; + vma = NULL; + } /* * Private writable mapping: check memory availability -- 2.43.0