|
@@ -25,6 +25,7 @@
|
|
#include <linux/syscalls.h>
|
|
#include <linux/syscalls.h>
|
|
#include <linux/ipc.h>
|
|
#include <linux/ipc.h>
|
|
#include <linux/personality.h>
|
|
#include <linux/personality.h>
|
|
|
|
+#include <linux/random.h>
|
|
|
|
|
|
#include <asm/uaccess.h>
|
|
#include <asm/uaccess.h>
|
|
#include <asm/ipc.h>
|
|
#include <asm/ipc.h>
|
|
@@ -358,6 +359,17 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, u
|
|
/* Essentially the same as PowerPC... */
|
|
/* Essentially the same as PowerPC... */
|
|
void arch_pick_mmap_layout(struct mm_struct *mm)
|
|
void arch_pick_mmap_layout(struct mm_struct *mm)
|
|
{
|
|
{
|
|
|
|
+ unsigned long random_factor = 0UL;
|
|
|
|
+
|
|
|
|
+ if (current->flags & PF_RANDOMIZE) {
|
|
|
|
+ random_factor = get_random_int();
|
|
|
|
+ if (test_thread_flag(TIF_32BIT))
|
|
|
|
+ random_factor &= ((1 * 1024 * 1024) - 1);
|
|
|
|
+ else
|
|
|
|
+ random_factor = ((random_factor << PAGE_SHIFT) &
|
|
|
|
+ 0xffffffffUL);
|
|
|
|
+ }
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* Fall back to the standard layout if the personality
|
|
* Fall back to the standard layout if the personality
|
|
* bit is set, or if the expected stack growth is unlimited:
|
|
* bit is set, or if the expected stack growth is unlimited:
|
|
@@ -366,7 +378,7 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
|
|
(current->personality & ADDR_COMPAT_LAYOUT) ||
|
|
(current->personality & ADDR_COMPAT_LAYOUT) ||
|
|
current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY ||
|
|
current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY ||
|
|
sysctl_legacy_va_layout) {
|
|
sysctl_legacy_va_layout) {
|
|
- mm->mmap_base = TASK_UNMAPPED_BASE;
|
|
|
|
|
|
+ mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
|
|
mm->get_unmapped_area = arch_get_unmapped_area;
|
|
mm->get_unmapped_area = arch_get_unmapped_area;
|
|
mm->unmap_area = arch_unmap_area;
|
|
mm->unmap_area = arch_unmap_area;
|
|
} else {
|
|
} else {
|
|
@@ -380,7 +392,7 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
|
|
if (gap > (task_size / 6 * 5))
|
|
if (gap > (task_size / 6 * 5))
|
|
gap = (task_size / 6 * 5);
|
|
gap = (task_size / 6 * 5);
|
|
|
|
|
|
- mm->mmap_base = task_size - (gap & PAGE_MASK);
|
|
|
|
|
|
+ mm->mmap_base = PAGE_ALIGN(task_size - gap - random_factor);
|
|
mm->get_unmapped_area = arch_get_unmapped_area_topdown;
|
|
mm->get_unmapped_area = arch_get_unmapped_area_topdown;
|
|
mm->unmap_area = arch_unmap_area_topdown;
|
|
mm->unmap_area = arch_unmap_area_topdown;
|
|
}
|
|
}
|