struct vm_area_struct * vma;
unsigned long task_size = TASK_SIZE;
int do_color_align;
+ unsigned long offset = gr_rand_threadstack_offset(mm, filp, flags);
struct vm_unmapped_area_info info;
if (flags & MAP_FIXED) {
/* We do not accept a shared mapping if it would violate
* cache aliasing constraints.
*/
- if ((flags & MAP_SHARED) &&
+ if ((filp || (flags & MAP_SHARED)) &&
((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
return -EINVAL;
return addr;
if (filp || (flags & MAP_SHARED))
do_color_align = 1;
+#ifdef CONFIG_PAX_RANDMMAP
+ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
+#endif
+
if (addr) {
if (do_color_align)
addr = COLOR_ALIGN(addr, pgoff);
addr = PAGE_ALIGN(addr);
vma = find_vma(mm, addr);
- if (task_size - len >= addr &&
- (!vma || addr + len <= vma->vm_start))
+ if (task_size - len >= addr && check_heap_stack_gap(vma, addr, len, offset))
return addr;
}
info.flags = 0;
info.length = len;
- info.low_limit = TASK_UNMAPPED_BASE;
+ info.low_limit = mm->mmap_base;
info.high_limit = min(task_size, VA_EXCLUDE_START);
info.align_mask = do_color_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
info.align_offset = pgoff << PAGE_SHIFT;
+ info.threadstack_offset = offset;
addr = vm_unmapped_area(&info);
if ((addr & ~PAGE_MASK) && task_size > VA_EXCLUDE_END) {
VM_BUG_ON(addr != -ENOMEM);
info.low_limit = VA_EXCLUDE_END;
+
+#ifdef CONFIG_PAX_RANDMMAP
+ if (mm->pax_flags & MF_PAX_RANDMMAP)
+ info.low_limit += mm->delta_mmap;
+#endif
+
info.high_limit = task_size;
addr = vm_unmapped_area(&info);
}
unsigned long task_size = STACK_TOP32;
unsigned long addr = addr0;
int do_color_align;
+ unsigned long offset = gr_rand_threadstack_offset(mm, filp, flags);
struct vm_unmapped_area_info info;
/* This should only ever run for 32-bit processes. */
/* We do not accept a shared mapping if it would violate
* cache aliasing constraints.
*/
- if ((flags & MAP_SHARED) &&
+ if ((filp || (flags & MAP_SHARED)) &&
((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
return -EINVAL;
return addr;
if (filp || (flags & MAP_SHARED))
do_color_align = 1;
+#ifdef CONFIG_PAX_RANDMMAP
+ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
+#endif
+
/* requesting a specific address */
if (addr) {
if (do_color_align)
addr = PAGE_ALIGN(addr);
vma = find_vma(mm, addr);
- if (task_size - len >= addr &&
- (!vma || addr + len <= vma->vm_start))
+ if (task_size - len >= addr && check_heap_stack_gap(vma, addr, len, offset))
return addr;
}
info.high_limit = mm->mmap_base;
info.align_mask = do_color_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
info.align_offset = pgoff << PAGE_SHIFT;
+ info.threadstack_offset = offset;
addr = vm_unmapped_area(&info);
/*
VM_BUG_ON(addr != -ENOMEM);
info.flags = 0;
info.low_limit = TASK_UNMAPPED_BASE;
+
+#ifdef CONFIG_PAX_RANDMMAP
+ if (mm->pax_flags & MF_PAX_RANDMMAP)
+ info.low_limit += mm->delta_mmap;
+#endif
+
info.high_limit = STACK_TOP32;
addr = vm_unmapped_area(&info);
}
EXPORT_SYMBOL(get_fb_unmapped_area);
/* Essentially the same as PowerPC. */
-static unsigned long mmap_rnd(void)
+static unsigned long mmap_rnd(struct mm_struct *mm)
{
unsigned long rnd = 0UL;
+#ifdef CONFIG_PAX_RANDMMAP
+ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
+#endif
+
if (current->flags & PF_RANDOMIZE) {
unsigned long val = get_random_int();
if (test_thread_flag(TIF_32BIT))
void arch_pick_mmap_layout(struct mm_struct *mm)
{
- unsigned long random_factor = mmap_rnd();
+ unsigned long random_factor = mmap_rnd(mm);
unsigned long gap;
/*
gap == RLIM_INFINITY ||
sysctl_legacy_va_layout) {
mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
+
+#ifdef CONFIG_PAX_RANDMMAP
+ if (mm->pax_flags & MF_PAX_RANDMMAP)
+ mm->mmap_base += mm->delta_mmap;
+#endif
+
mm->get_unmapped_area = arch_get_unmapped_area;
} else {
/* We know it's 32-bit */
gap = (task_size / 6 * 5);
mm->mmap_base = PAGE_ALIGN(task_size - gap - random_factor);
+
+#ifdef CONFIG_PAX_RANDMMAP
+ if (mm->pax_flags & MF_PAX_RANDMMAP)
+ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
+#endif
+
mm->get_unmapped_area = arch_get_unmapped_area_topdown;
}
}