aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2010-07-14 00:55:23 -0700
committerJohn Rigby <john.rigby@linaro.org>2011-09-23 08:50:55 -0600
commite0dd5cbe67c056d3bd3cf91b4c72f32519c83e49 (patch)
treee3e0a7470591f95cc5e438c17b77f5939b60948f /arch
parent9d11aa4b7e3e261c42c22275605339e01a2edee4 (diff)
UBUNTU: ubuntu: nx-emu - i386: mmap randomization for executable mappings
This code is originally from Ingo Molnar, with some later rebasing and fixes to respect all the randomization-disabling knobs. It provides address randomization algorithm when NX emulation is in use in 32-bit processes. Kees Cook pushed the brk area further away in the case of PIE binaries landing their brk inside the CS limit. Signed-off-by: Kees Cook <kees.cook@canonical.com> Signed-off-by: Leann Ogasawara <leann.ogasawara@canonical.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kernel/process.c12
-rw-r--r--arch/x86/mm/mmap.c6
-rw-r--r--arch/x86/vdso/vdso32-setup.c2
3 files changed, 18 insertions, 2 deletions
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index e1ba8cb24e4..aae0a53e612 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -678,6 +678,16 @@ unsigned long arch_align_stack(unsigned long sp)
unsigned long arch_randomize_brk(struct mm_struct *mm)
{
unsigned long range_end = mm->brk + 0x02000000;
- return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
+ unsigned long bump = 0;
+#ifdef CONFIG_X86_32
+ /* when using ASLR in arch_get_unmapped_exec_area, we must shove
+ the brk segment way out of the way of the exec area, since it
+ can collide with future allocations if not. */
+ if ( (mm->get_unmapped_exec_area == arch_get_unmapped_exec_area) &&
+ (mm->brk < 0x08000000) ) {
+ bump = (TASK_SIZE/6);
+ }
+#endif
+ return bump + (randomize_range(mm->brk, range_end, 0) ? : mm->brk);
}
diff --git a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c
index 1dab5194fd9..ff3a3bfdd64 100644
--- a/arch/x86/mm/mmap.c
+++ b/arch/x86/mm/mmap.c
@@ -131,6 +131,12 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
} else {
mm->mmap_base = mmap_base();
mm->get_unmapped_area = arch_get_unmapped_area_topdown;
+#ifdef CONFIG_X86_32
+ if (!(current->personality & READ_IMPLIES_EXEC)
+ && !(__supported_pte_mask & _PAGE_NX)
+ && mmap_is_ia32())
+ mm->get_unmapped_exec_area = arch_get_unmapped_exec_area;
+#endif
mm->unmap_area = arch_unmap_area_topdown;
}
}
diff --git a/arch/x86/vdso/vdso32-setup.c b/arch/x86/vdso/vdso32-setup.c
index 468d591dde3..df0ac0027b3 100644
--- a/arch/x86/vdso/vdso32-setup.c
+++ b/arch/x86/vdso/vdso32-setup.c
@@ -331,7 +331,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
if (compat)
addr = VDSO_HIGH_BASE;
else {
- addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
+ addr = get_unmapped_area_prot(NULL, 0, PAGE_SIZE, 0, 0, 1);
if (IS_ERR_VALUE(addr)) {
ret = addr;
goto up_fail;