diff options
| author | David S. Miller <davem@sunset.davemloft.net> | 2006-03-17 20:42:57 -0500 |
|---|---|---|
| committer | David S. Miller <davem@sunset.davemloft.net> | 2006-03-20 04:16:37 -0500 |
| commit | 05f9ca83596c7801549a2b4eba469d51baf5480f (patch) | |
| tree | 22270db01a13dda0af9b158662712f9e6b6a934c | |
| parent | d61e16df940e02e25679bdc1aee8c25786f6de90 (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.c | 16 |
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... */ |
| 359 | void arch_pick_mmap_layout(struct mm_struct *mm) | 360 | void 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 | } |
