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 <kees.cook@canonical.com>
This commit is contained in:
Dave Jones 2010-09-03 11:48:57 -04:00
parent 55f50f1d14
commit fff25a2ad1
2 changed files with 25 additions and 0 deletions

View File

@ -1876,6 +1876,9 @@ fi
# || || # || ||
%changelog %changelog
* Fri Sep 03 2010 Dave Jones <davej@redhat.com>
- exec-randomization: brk away from exec rand area (Kees Cook)
* Fri Sep 03 2010 Dave Jones <davej@redhat.com> * Fri Sep 03 2010 Dave Jones <davej@redhat.com>
- Remove the execshield boot parameter. - Remove the execshield boot parameter.
Based on a patch from Kees Cook Based on a patch from Kees Cook

View File

@ -591,3 +591,25 @@
mmu_notifier_invalidate_range_start(mm, start, end); mmu_notifier_invalidate_range_start(mm, start, end);
if (is_vm_hugetlb_page(vma)) if (is_vm_hugetlb_page(vma))
hugetlb_change_protection(vma, start, end, vma->vm_page_prot); 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);
}