[PATCH] UBUNTU: SAUCE: x86: brk away from exec rand area

Kees Cook kees at ubuntu.com
Tue Jan 19 18:31:34 UTC 2010


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.

Additionally, the nx-emulation patch was still randomizing addresses
even when randomize_va_space was disabled, which would cause collisions
even faster if someone tried to disable randomization.

BugLink: http://bugs.launchpad.net/bugs/452175

Signed-off-by: Kees Cook <kees.cook at canonical.com>
---
 arch/x86/kernel/process.c |   12 +++++++++++-
 mm/mmap.c                 |   11 ++++++++---
 2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 5284cd2..bf5c156 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -607,6 +607,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);
 }
 
diff --git a/mm/mmap.c b/mm/mmap.c
index a1483c5..c6d7e53 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1500,8 +1500,11 @@ arch_get_unmapped_exec_area(struct file *filp, unsigned long addr0,
 	if (flags & MAP_FIXED)
 		return addr;
 
-	if (!addr)
-		addr = randomize_range(SHLIB_BASE, 0x01000000, len);
+	if (!addr) {
+		addr = SHLIB_BASE;
+		if ((current->flags & PF_RANDOMIZE) && randomize_va_space)
+			addr = randomize_range(addr, 0x01000000, len);
+	}
 
 	if (addr) {
 		addr = PAGE_ALIGN(addr);
@@ -1529,7 +1532,9 @@ arch_get_unmapped_exec_area(struct file *filp, unsigned long addr0,
 			 * Up until the brk area we randomize addresses
 			 * as much as possible:
 			 */
-			if (addr >= 0x01000000) {
+			if ((current->flags & PF_RANDOMIZE) &&
+                            randomize_va_space &&
+                            addr >= 0x01000000) {
 				tmp = randomize_range(0x01000000,
 					PAGE_ALIGN(max(mm->start_brk,
 					(unsigned long)0x08000000)), len);
-- 
1.6.5

-- 
Kees Cook
Ubuntu Security Team




More information about the kernel-team mailing list