diff options
Diffstat (limited to 'arch/powerpc/mm/mmap.c')
-rw-r--r-- | arch/powerpc/mm/mmap.c | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/arch/powerpc/mm/mmap.c b/arch/powerpc/mm/mmap.c index 8ff5757af0d7..f7376dbb653b 100644 --- a/arch/powerpc/mm/mmap.c +++ b/arch/powerpc/mm/mmap.c | |||
@@ -24,6 +24,7 @@ | |||
24 | 24 | ||
25 | #include <linux/personality.h> | 25 | #include <linux/personality.h> |
26 | #include <linux/mm.h> | 26 | #include <linux/mm.h> |
27 | #include <linux/random.h> | ||
27 | #include <linux/sched.h> | 28 | #include <linux/sched.h> |
28 | 29 | ||
29 | /* | 30 | /* |
@@ -45,6 +46,20 @@ static inline int mmap_is_legacy(void) | |||
45 | return sysctl_legacy_va_layout; | 46 | return sysctl_legacy_va_layout; |
46 | } | 47 | } |
47 | 48 | ||
49 | static unsigned long mmap_rnd(void) | ||
50 | { | ||
51 | unsigned long rnd = 0; | ||
52 | |||
53 | if (current->flags & PF_RANDOMIZE) { | ||
54 | /* 8MB for 32bit, 1GB for 64bit */ | ||
55 | if (is_32bit_task()) | ||
56 | rnd = (long)(get_random_int() % (1<<(23-PAGE_SHIFT))); | ||
57 | else | ||
58 | rnd = (long)(get_random_int() % (1<<(30-PAGE_SHIFT))); | ||
59 | } | ||
60 | return rnd << PAGE_SHIFT; | ||
61 | } | ||
62 | |||
48 | static inline unsigned long mmap_base(void) | 63 | static inline unsigned long mmap_base(void) |
49 | { | 64 | { |
50 | unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur; | 65 | unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur; |
@@ -54,7 +69,7 @@ static inline unsigned long mmap_base(void) | |||
54 | else if (gap > MAX_GAP) | 69 | else if (gap > MAX_GAP) |
55 | gap = MAX_GAP; | 70 | gap = MAX_GAP; |
56 | 71 | ||
57 | return TASK_SIZE - (gap & PAGE_MASK); | 72 | return PAGE_ALIGN(TASK_SIZE - gap - mmap_rnd()); |
58 | } | 73 | } |
59 | 74 | ||
60 | /* | 75 | /* |