aboutsummaryrefslogtreecommitdiff
path: root/mm
diff options
context:
space:
mode:
authorKirill Korotaev <dev@openvz.org>2006-11-11 01:08:49 +0100
committerAdrian Bunk <bunk@stusta.de>2006-11-11 01:08:49 +0100
commit05c19c4369b40357c726a224fe51a3f5ff21f9bd (patch)
treef10482b32d659dd750853d8db937dbe91be2ed28 /mm
parent567e0e320d52690b9a442beb146ab59af88824a7 (diff)
downloadlinux-linaro-stable-05c19c4369b40357c726a224fe51a3f5ff21f9bd.tar.gz
ia64/sparc: fix local DoS with corrupted ELFs (CVE-2006-4538)
This patch prevents cross-region mappings on IA64 and SPARC which could lead to system crash. Adrian Bunk: Adapted to 2.6.16. Signed-Off-By: Kirill Korotaev <dev@openvz.org> Signed-off-by: Adrian Bunk <bunk@stusta.de>
Diffstat (limited to 'mm')
-rw-r--r--mm/mmap.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/mm/mmap.c b/mm/mmap.c
index 47556d2b3e90..fba355c06528 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -30,6 +30,10 @@
#include <asm/cacheflush.h>
#include <asm/tlb.h>
+#ifndef arch_mmap_check
+#define arch_mmap_check(addr, len, flags) (0)
+#endif
+
static void unmap_region(struct mm_struct *mm,
struct vm_area_struct *vma, struct vm_area_struct *prev,
unsigned long start, unsigned long end);
@@ -906,6 +910,10 @@ unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
if (!len)
return -EINVAL;
+ error = arch_mmap_check(addr, len, flags);
+ if (error)
+ return error;
+
/* Careful about overflows.. */
len = PAGE_ALIGN(len);
if (!len || len > TASK_SIZE)
@@ -1846,6 +1854,7 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
unsigned long flags;
struct rb_node ** rb_link, * rb_parent;
pgoff_t pgoff = addr >> PAGE_SHIFT;
+ int error;
len = PAGE_ALIGN(len);
if (!len)
@@ -1854,6 +1863,12 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
if ((addr + len) > TASK_SIZE || (addr + len) < addr)
return -EINVAL;
+ flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
+
+ error = arch_mmap_check(addr, len, flags);
+ if (error)
+ return error;
+
/*
* mlock MCL_FUTURE?
*/
@@ -1894,8 +1909,6 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
if (security_vm_enough_memory(len >> PAGE_SHIFT))
return -ENOMEM;
- flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
-
/* Can we just expand an old private anonymous mapping? */
if (vma_merge(mm, prev, addr, addr + len, flags,
NULL, NULL, pgoff, NULL))