From fff25a2ad108da8e32461ee1a3156a09abd58ae4 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Sep 03 2010 15:48:57 +0000 Subject: exec-randomization: brk away from exec rand area This is a fix for the NX emulation patch to force the brk area well outside of the exec randomization area to avoid future allocation or brk growth collisions. Normally this isn't a problem, except when the text region has been loaded from a PIE binary and the CS limit can't be put just above bss. A test-case that will show failures without this patch can be found here: http://bazaar.launchpad.net/~ubuntu-bugcontrol/qa-regression-testing/master/annotate/head%3A/scripts/kernel-aslr-collisions/explode-brk.c Signed-off-by: Kees Cook --- diff --git a/kernel.spec b/kernel.spec index 8342c4a..114580f 100644 --- a/kernel.spec +++ b/kernel.spec @@ -1877,6 +1877,9 @@ fi %changelog * Fri Sep 03 2010 Dave Jones +- exec-randomization: brk away from exec rand area (Kees Cook) + +* Fri Sep 03 2010 Dave Jones - Remove the execshield boot parameter. Based on a patch from Kees Cook diff --git a/linux-2.6-i386-nx-emulation.patch b/linux-2.6-i386-nx-emulation.patch index 2ea7645..e36bb5e 100644 --- a/linux-2.6-i386-nx-emulation.patch +++ b/linux-2.6-i386-nx-emulation.patch @@ -591,3 +591,25 @@ mmu_notifier_invalidate_range_start(mm, start, end); if (is_vm_hugetlb_page(vma)) hugetlb_change_protection(vma, start, end, vma->vm_page_prot); +diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c +index 57d1868..29c0c35 100644 +--- a/arch/x86/kernel/process.c ++++ b/arch/x86/kernel/process.c +@@ -669,6 +669,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 ++ /* in the case of NX emulation, shove the brk segment way out of the ++ way of the exec randomization 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); + } +