aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2006-03-17 20:42:57 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-03-20 04:16:37 -0500
commit05f9ca83596c7801549a2b4eba469d51baf5480f (patch)
tree22270db01a13dda0af9b158662712f9e6b6a934c
parentd61e16df940e02e25679bdc1aee8c25786f6de90 (diff)
[SPARC64]: Randomize mm->mmap_base when PF_RANDOMIZE is set.
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--arch/sparc64/kernel/sys_sparc.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c
index 9019b41fc02a..7a869138c37f 100644
--- a/arch/sparc64/kernel/sys_sparc.c
+++ b/arch/sparc64/kernel/sys_sparc.c
@@ -25,6 +25,7 @@
25#include <linux/syscalls.h> 25#include <linux/syscalls.h>
26#include <linux/ipc.h> 26#include <linux/ipc.h>
27#include <linux/personality.h> 27#include <linux/personality.h>
28#include <linux/random.h>
28 29
29#include <asm/uaccess.h> 30#include <asm/uaccess.h>
30#include <asm/ipc.h> 31#include <asm/ipc.h>
@@ -358,6 +359,17 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, u
358/* Essentially the same as PowerPC... */ 359/* Essentially the same as PowerPC... */
359void arch_pick_mmap_layout(struct mm_struct *mm) 360void arch_pick_mmap_layout(struct mm_struct *mm)
360{ 361{
362 unsigned long random_factor = 0UL;
363
364 if (current->flags & PF_RANDOMIZE) {
365 random_factor = get_random_int();
366 if (test_thread_flag(TIF_32BIT))
367 random_factor &= ((1 * 1024 * 1024) - 1);
368 else
369 random_factor = ((random_factor << PAGE_SHIFT) &
370 0xffffffffUL);
371 }
372
361 /* 373 /*
362 * Fall back to the standard layout if the personality 374 * Fall back to the standard layout if the personality
363 * bit is set, or if the expected stack growth is unlimited: 375 * bit is set, or if the expected stack growth is unlimited:
@@ -366,7 +378,7 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
366 (current->personality & ADDR_COMPAT_LAYOUT) || 378 (current->personality & ADDR_COMPAT_LAYOUT) ||
367 current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY || 379 current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY ||
368 sysctl_legacy_va_layout) { 380 sysctl_legacy_va_layout) {
369 mm->mmap_base = TASK_UNMAPPED_BASE; 381 mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
370 mm->get_unmapped_area = arch_get_unmapped_area; 382 mm->get_unmapped_area = arch_get_unmapped_area;
371 mm->unmap_area = arch_unmap_area; 383 mm->unmap_area = arch_unmap_area;
372 } else { 384 } else {
@@ -380,7 +392,7 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
380 if (gap > (task_size / 6 * 5)) 392 if (gap > (task_size / 6 * 5))
381 gap = (task_size / 6 * 5); 393 gap = (task_size / 6 * 5);
382 394
383 mm->mmap_base = task_size - (gap & PAGE_MASK); 395 mm->mmap_base = PAGE_ALIGN(task_size - gap - random_factor);
384 mm->get_unmapped_area = arch_get_unmapped_area_topdown; 396 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
385 mm->unmap_area = arch_unmap_area_topdown; 397 mm->unmap_area = arch_unmap_area_topdown;
386 } 398 }