@@ -9,6 +9,7 @@
#include <linux/io.h>
#include <linux/personality.h>
#include <linux/random.h>
+#include <linux/security.h>
#include <asm/cachetype.h>
#define COLOUR_ALIGN(addr,pgoff) \
@@ -78,7 +79,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
return addr;
}
- if (len > TASK_SIZE)
+ if (len > TASK_SIZE - mmap_min_addr)
return -ENOMEM;
if (addr) {
@@ -88,14 +89,14 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
addr = PAGE_ALIGN(addr);
vma = find_vma(mm, addr);
- if (TASK_SIZE - len >= addr &&
+ if (TASK_SIZE - len >= addr && addr >= mmap_min_addr &&
(!vma || addr + len <= vma->vm_start))
return addr;
}
info.flags = 0;
info.length = len;
- info.low_limit = mm->mmap_base;
+ info.low_limit = max(mm->mmap_base, mmap_min_addr);
info.high_limit = TASK_SIZE;
info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
info.align_offset = pgoff << PAGE_SHIFT;
@@ -122,7 +123,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
do_align = filp || (flags & MAP_SHARED);
/* requested length too big for entire address space */
- if (len > TASK_SIZE)
+ if (len > TASK_SIZE - mmap_min_addr)
return -ENOMEM;
if (flags & MAP_FIXED) {
@@ -139,14 +140,14 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
else
addr = PAGE_ALIGN(addr);
vma = find_vma(mm, addr);
- if (TASK_SIZE - len >= addr &&
+ if (TASK_SIZE - len >= addr && addr >= mmap_min_addr &&
(!vma || addr + len <= vma->vm_start))
return addr;
}
info.flags = VM_UNMAPPED_AREA_TOPDOWN;
info.length = len;
- info.low_limit = PAGE_SIZE;
+ info.low_limit = max(PAGE_SIZE, mmap_min_addr);
info.high_limit = mm->mmap_base;
info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
info.align_offset = pgoff << PAGE_SHIFT;
@@ -161,7 +162,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
if (addr & ~PAGE_MASK) {
VM_BUG_ON(addr != -ENOMEM);
info.flags = 0;
- info.low_limit = mm->mmap_base;
+ info.low_limit = max(mm->mmap_base, mmap_min_addr);
info.high_limit = TASK_SIZE;
addr = vm_unmapped_area(&info);
}