From: Danny Feng <dfeng@redhat.com> Date: Fri, 29 Jan 2010 09:26:29 -0500 Subject: [mm] take arch_mmap_check into get_unmapped_area Message-id: <20100129092641.4587.97591.sendpatchset@dhcp-65-180.nay.redhat.com> Patchwork-id: 22995 O-Subject: [PATCH RHEL5.5 10/12 BZ556710 CVE-2010-0291] Take arch_mmap_check() into get_unmapped_area() Bugzilla: 556710 RH-Acked-by: Jarod Wilson <jarod@redhat.com> RH-Acked-by: Larry Woodman <lwoodman@redhat.com> backport of upstream commit 9206de95b1ea68357996ec02be5db0638a0de2c1 Subject: [PATCH] Take arch_mmap_check() into get_unmapped_area() Acked-by: Hugh Dickins <hugh.dickins@tiscali.co.uk> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> diff --git a/mm/mmap.c b/mm/mmap.c index e3b7c86..d720106 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -936,13 +936,9 @@ unsigned long do_mmap_pgoff(struct file * file, unsigned long addr, if (!(flags & MAP_FIXED)) addr = round_hint_to_min(addr); - error = arch_mmap_check(addr, len, flags); - if (error) - return error; - /* Careful about overflows.. */ len = PAGE_ALIGN(len); - if (!len || len > TASK_SIZE) + if (!len) return -ENOMEM; /* offset overflow? */ @@ -1398,6 +1394,14 @@ get_unmapped_area_prot(struct file *file, unsigned long addr, unsigned long len, { unsigned long ret; + unsigned long error = arch_mmap_check(addr, len, flags); + if (error) + return error; + + /* Careful about overflows.. */ + if (len > TASK_SIZE) + return -ENOMEM; + if (!(flags & MAP_FIXED)) { unsigned long (*get_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); diff --git a/mm/mremap.c b/mm/mremap.c index 6230afd..27b9604 100644 --- a/mm/mremap.c +++ b/mm/mremap.c @@ -24,10 +24,6 @@ #include <asm/cacheflush.h> #include <asm/tlbflush.h> -#ifndef arch_mmap_check -#define arch_mmap_check(addr, len, flags) (0) -#endif - static pmd_t *get_old_pmd(struct mm_struct *mm, unsigned long addr) { pgd_t *pgd; @@ -349,9 +345,7 @@ static unsigned long mremap_to(unsigned long addr, map_flags = MAP_FIXED; if (vma->vm_flags & VM_MAYSHARE) map_flags |= MAP_SHARED; - ret = arch_mmap_check(new_addr, new_len, map_flags); - if (ret) - goto out1; + ret = get_unmapped_area(vma->vm_file, new_addr, new_len, vma->vm_pgoff + ((addr - vma->vm_start) >> PAGE_SHIFT), map_flags); @@ -371,12 +365,9 @@ out: static int vma_expandable(struct vm_area_struct *vma, unsigned long delta) { unsigned long end = vma->vm_end + delta; - unsigned long max_addr = TASK_SIZE; - if (vma->vm_next) - max_addr = vma->vm_next->vm_start; - if (max_addr < end || end < vma->vm_end) + if (end < vma->vm_end) /* overflow */ return 0; - if (arch_mmap_check(vma->vm_start, end - vma->vm_start, MAP_FIXED)) + if (vma->vm_next && vma->vm_next->vm_start < end) /* intersection */ return 0; if (get_unmapped_area(NULL, vma->vm_start, end - vma->vm_start, 0, MAP_FIXED) & ~PAGE_MASK)