linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [patch 00/10] PowerPC address space randomisation
@ 2009-02-22 11:49 Anton Blanchard
  2009-02-22 11:49 ` [patch 01/10] powerpc: Move is_32bit_task Anton Blanchard
                   ` (9 more replies)
  0 siblings, 10 replies; 11+ messages in thread
From: Anton Blanchard @ 2009-02-22 11:49 UTC (permalink / raw)
  To: linuxppc-dev

The following set of patches adds randomisation of mmaps, heap and
position independent executables, and increases the randomisation applied to
the stack on 64bit binaries.

-- 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [patch 01/10] powerpc: Move is_32bit_task
  2009-02-22 11:49 [patch 00/10] PowerPC address space randomisation Anton Blanchard
@ 2009-02-22 11:49 ` Anton Blanchard
  2009-02-22 11:49 ` [patch 02/10] powerpc: Use new layout for 64bit binaries Anton Blanchard
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Anton Blanchard @ 2009-02-22 11:49 UTC (permalink / raw)
  To: linuxppc-dev

Move is_32bit_task into asm/thread_info.h, that allows us to test for
32/64bit tasks without an ugly CONFIG_PPC64 ifdef.

Signed-off-by: Anton Blanchard <anton@samba.org>
---

Index: linux-2.6/arch/powerpc/include/asm/thread_info.h
===================================================================
--- linux-2.6.orig/arch/powerpc/include/asm/thread_info.h	2009-02-20 13:44:37.000000000 +1100
+++ linux-2.6/arch/powerpc/include/asm/thread_info.h	2009-02-20 16:03:02.000000000 +1100
@@ -154,6 +154,13 @@
 	ti->local_flags |= _TLF_RESTORE_SIGMASK;
 	set_bit(TIF_SIGPENDING, &ti->flags);
 }
+
+#ifdef CONFIG_PPC64
+#define is_32bit_task()	(test_thread_flag(TIF_32BIT))
+#else
+#define is_32bit_task()	(1)
+#endif
+
 #endif	/* !__ASSEMBLY__ */
 
 #endif /* __KERNEL__ */
Index: linux-2.6/arch/powerpc/kernel/signal.h
===================================================================
--- linux-2.6.orig/arch/powerpc/kernel/signal.h	2009-02-20 13:44:34.000000000 +1100
+++ linux-2.6/arch/powerpc/kernel/signal.h	2009-02-20 13:45:33.000000000 +1100
@@ -39,22 +39,12 @@
 
 #ifdef CONFIG_PPC64
 
-static inline int is_32bit_task(void)
-{
-	return test_thread_flag(TIF_32BIT);
-}
-
 extern int handle_rt_signal64(int signr, struct k_sigaction *ka,
 			      siginfo_t *info, sigset_t *set,
 			      struct pt_regs *regs);
 
 #else /* CONFIG_PPC64 */
 
-static inline int is_32bit_task(void)
-{
-	return 1;
-}
-
 static inline int handle_rt_signal64(int signr, struct k_sigaction *ka,
 				     siginfo_t *info, sigset_t *set,
 				     struct pt_regs *regs)

-- 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [patch 02/10] powerpc: Use new layout for 64bit binaries
  2009-02-22 11:49 [patch 00/10] PowerPC address space randomisation Anton Blanchard
  2009-02-22 11:49 ` [patch 01/10] powerpc: Move is_32bit_task Anton Blanchard
@ 2009-02-22 11:49 ` Anton Blanchard
  2009-02-22 11:50 ` [patch 03/10] powerpc: Rearrange mmap.c Anton Blanchard
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Anton Blanchard @ 2009-02-22 11:49 UTC (permalink / raw)
  To: linuxppc-dev

We currently place mmaps just below the stack on 32bit, but leave them
in the middle of the address space on 64bit:

00100000-00120000 r-xp 00100000 00:00 0                    [vdso]
10000000-10010000 r-xp 00000000 08:06 179534               /tmp/sleep
10010000-10020000 rw-p 00000000 08:06 179534               /tmp/sleep
10020000-10130000 rw-p 10020000 00:00 0                    [heap]
40000000000-40000030000 r-xp 00000000 08:06 440743         /lib64/ld-2.9.so
40000030000-40000040000 rw-p 00020000 08:06 440743         /lib64/ld-2.9.so
40000050000-400001f0000 r-xp 00000000 08:06 440671         /lib64/libc-2.9.so
400001f0000-40000200000 r--p 00190000 08:06 440671         /lib64/libc-2.9.so
40000200000-40000220000 rw-p 001a0000 08:06 440671         /lib64/libc-2.9.so
40000220000-40008230000 rw-p 40000220000 00:00 0 
fffffbc0000-fffffd10000 rw-p fffffeb0000 00:00 0           [stack]

Right now it isn't an issue, but at some stage we will run into mmap or
hugetlb allocation issues. Using the same layout as 32bit gives us a
some breathing room. This matches what x86-64 is doing too.

00100000-00103000 r-xp 00100000 00:00 0                    [vdso]
10000000-10001000 r-xp 00000000 08:06 554894               /tmp/test
10010000-10011000 r--p 00000000 08:06 554894               /tmp/test
10011000-10012000 rw-p 00001000 08:06 554894               /tmp/test
10012000-10113000 rw-p 10012000 00:00 0                    [heap]
fffefdf7000-ffff7df8000 rw-p fffefdf7000 00:00 0 
ffff7df8000-ffff7f97000 r-xp 00000000 08:06 130591         /lib64/libc-2.9.so
ffff7f97000-ffff7fa6000 ---p 0019f000 08:06 130591         /lib64/libc-2.9.so
ffff7fa6000-ffff7faa000 r--p 0019e000 08:06 130591         /lib64/libc-2.9.so
ffff7faa000-ffff7fc0000 rw-p 001a2000 08:06 130591         /lib64/libc-2.9.so
ffff7fc0000-ffff7fc4000 rw-p ffff7fc0000 00:00 0 
ffff7fc4000-ffff7fec000 r-xp 00000000 08:06 130663         /lib64/ld-2.9.so
ffff7fee000-ffff7ff0000 rw-p ffff7fee000 00:00 0 
ffff7ffa000-ffff7ffb000 rw-p ffff7ffa000 00:00 0 
ffff7ffb000-ffff7ffc000 r--p 00027000 08:06 130663         /lib64/ld-2.9.so
ffff7ffc000-ffff7fff000 rw-p 00028000 08:06 130663         /lib64/ld-2.9.so
ffff7fff000-ffff8000000 rw-p ffff7fff000 00:00 0 
fffffc59000-fffffc6e000 rw-p ffffffeb000 00:00 0           [stack]

Signed-off-by: Anton Blanchard <anton@samba.org>
---

Index: linux-2.6/arch/powerpc/mm/mmap.c
===================================================================
--- linux-2.6.orig/arch/powerpc/mm/mmap.c	2009-02-20 13:39:05.000000000 +1100
+++ linux-2.6/arch/powerpc/mm/mmap.c	2009-02-20 13:40:26.000000000 +1100
@@ -48,12 +48,6 @@
 
 static inline int mmap_is_legacy(void)
 {
-	/*
-	 * Force standard allocation for 64 bit programs.
-	 */
-	if (!test_thread_flag(TIF_32BIT))
-		return 1;
-
 	if (current->personality & ADDR_COMPAT_LAYOUT)
 		return 1;
 

-- 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [patch 03/10] powerpc: Rearrange mmap.c
  2009-02-22 11:49 [patch 00/10] PowerPC address space randomisation Anton Blanchard
  2009-02-22 11:49 ` [patch 01/10] powerpc: Move is_32bit_task Anton Blanchard
  2009-02-22 11:49 ` [patch 02/10] powerpc: Use new layout for 64bit binaries Anton Blanchard
@ 2009-02-22 11:50 ` Anton Blanchard
  2009-02-22 11:50 ` [patch 04/10] powerpc: Randomise mmap start address Anton Blanchard
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Anton Blanchard @ 2009-02-22 11:50 UTC (permalink / raw)
  To: linuxppc-dev

Rearrange mmap.c to better match the x86 version.

Signed-off-by: Anton Blanchard <anton@samba.org>
---

Index: linux-2.6/arch/powerpc/mm/mmap.c
===================================================================
--- linux-2.6.orig/arch/powerpc/mm/mmap.c	2009-02-20 13:40:26.000000000 +1100
+++ linux-2.6/arch/powerpc/mm/mmap.c	2009-02-20 13:41:06.000000000 +1100
@@ -34,6 +34,17 @@
 #define MIN_GAP (128*1024*1024)
 #define MAX_GAP (TASK_SIZE/6*5)
 
+static inline int mmap_is_legacy(void)
+{
+	if (current->personality & ADDR_COMPAT_LAYOUT)
+		return 1;
+
+	if (current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY)
+		return 1;
+
+	return sysctl_legacy_va_layout;
+}
+
 static inline unsigned long mmap_base(void)
 {
 	unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
@@ -46,17 +57,6 @@
 	return TASK_SIZE - (gap & PAGE_MASK);
 }
 
-static inline int mmap_is_legacy(void)
-{
-	if (current->personality & ADDR_COMPAT_LAYOUT)
-		return 1;
-
-	if (current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY)
-		return 1;
-
-	return sysctl_legacy_va_layout;
-}
-
 /*
  * This function, called very early during the creation of a new
  * process VM image, sets up which VM layout function to use:

-- 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [patch 04/10] powerpc: Randomise mmap start address
  2009-02-22 11:49 [patch 00/10] PowerPC address space randomisation Anton Blanchard
                   ` (2 preceding siblings ...)
  2009-02-22 11:50 ` [patch 03/10] powerpc: Rearrange mmap.c Anton Blanchard
@ 2009-02-22 11:50 ` Anton Blanchard
  2009-02-22 11:50 ` [patch 05/10] powerpc: More stack randomisation for 64bit binaries Anton Blanchard
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Anton Blanchard @ 2009-02-22 11:50 UTC (permalink / raw)
  To: linuxppc-dev

Randomise mmap start address - 8MB on 32bit and 1GB on 64bit tasks.
Until ppc32 uses the mmap.c functionality, this is ppc64 specific.

Before:

# ./test & cat /proc/${!}/maps|tail -2|head -1
f75fe000-f7fff000 rw-p f75fe000 00:00 0
f75fe000-f7fff000 rw-p f75fe000 00:00 0
f75fe000-f7fff000 rw-p f75fe000 00:00 0
f75fe000-f7fff000 rw-p f75fe000 00:00 0
f75fe000-f7fff000 rw-p f75fe000 00:00 0

After:
# ./test & cat /proc/${!}/maps|tail -2|head -1
f718b000-f7b8c000 rw-p f718b000 00:00 0
f7551000-f7f52000 rw-p f7551000 00:00 0
f6ee7000-f78e8000 rw-p f6ee7000 00:00 0
f74d4000-f7ed5000 rw-p f74d4000 00:00 0
f6e9d000-f789e000 rw-p f6e9d000 00:00 0

Similar for 64bit, but with 1GB of scatter:
# ./test & cat /proc/${!}/maps|tail -2|head -1
fffb97b5000-fffb97b6000 rw-p fffb97b5000 00:00 0
fffce9a3000-fffce9a4000 rw-p fffce9a3000 00:00 0
fffeaaf2000-fffeaaf3000 rw-p fffeaaf2000 00:00 0
fffd88ac000-fffd88ad000 rw-p fffd88ac000 00:00 0
fffbc62e000-fffbc62f000 rw-p fffbc62e000 00:00 0

Signed-off-by: Anton Blanchard <anton@samba.org>
---

Index: linux-2.6/arch/powerpc/mm/mmap.c
===================================================================
--- linux-2.6.orig/arch/powerpc/mm/mmap.c	2009-02-20 13:46:35.000000000 +1100
+++ linux-2.6/arch/powerpc/mm/mmap.c	2009-02-20 13:47:23.000000000 +1100
@@ -24,6 +24,7 @@
 
 #include <linux/personality.h>
 #include <linux/mm.h>
+#include <linux/random.h>
 #include <linux/sched.h>
 
 /*
@@ -45,6 +46,20 @@
 	return sysctl_legacy_va_layout;
 }
 
+static unsigned long mmap_rnd(void)
+{
+	unsigned long rnd = 0;
+
+	if (current->flags & PF_RANDOMIZE) {
+		/* 8MB for 32bit, 1GB for 64bit */
+		if (is_32bit_task())
+			rnd = (long)(get_random_int() % (1<<(23-PAGE_SHIFT)));
+		else
+			rnd = (long)(get_random_int() % (1<<(30-PAGE_SHIFT)));
+	}
+	return rnd << PAGE_SHIFT;
+}
+
 static inline unsigned long mmap_base(void)
 {
 	unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
@@ -54,7 +69,7 @@
 	else if (gap > MAX_GAP)
 		gap = MAX_GAP;
 
-	return TASK_SIZE - (gap & PAGE_MASK);
+	return PAGE_ALIGN(TASK_SIZE - gap - mmap_rnd());
 }
 
 /*

-- 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [patch 05/10] powerpc: More stack randomisation for 64bit binaries
  2009-02-22 11:49 [patch 00/10] PowerPC address space randomisation Anton Blanchard
                   ` (3 preceding siblings ...)
  2009-02-22 11:50 ` [patch 04/10] powerpc: Randomise mmap start address Anton Blanchard
@ 2009-02-22 11:50 ` Anton Blanchard
  2009-02-22 11:50 ` [patch 06/10] powerpc: Randomise lower bits of stack address Anton Blanchard
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Anton Blanchard @ 2009-02-22 11:50 UTC (permalink / raw)
  To: linuxppc-dev

At the moment we randomise the stack by 8MB on 32bit and 64bit tasks. Since we
have a lot more address space to play with on 64bit, lets do what x86 does and
increase that randomisation to 1GB:

before:
# for i in seq `1 10` ; do sleep 1 & cat /proc/${!}/maps | grep stack; done
fffffebc000-fffffed1000 rw-p ffffffeb000 00:00 0       [stack]           
ffffff5a000-ffffff6f000 rw-p ffffffeb000 00:00 0       [stack]           
fffffdb2000-fffffdc7000 rw-p ffffffeb000 00:00 0       [stack]           
fffffd3e000-fffffd53000 rw-p ffffffeb000 00:00 0       [stack]           
fffffad9000-fffffaee000 rw-p ffffffeb000 00:00 0       [stack]           

after:
# for i in seq `1 10` ; do sleep 1 & cat /proc/${!}/maps | grep stack; done
ffff5c27000-ffff5c3c000 rw-p ffffffeb000 00:00 0       [stack]
fffebe5e000-fffebe73000 rw-p ffffffeb000 00:00 0       [stack]
fffcb298000-fffcb2ad000 rw-p ffffffeb000 00:00 0       [stack]
fffc719d000-fffc71b2000 rw-p ffffffeb000 00:00 0       [stack]
fffe01af000-fffe01c4000 rw-p ffffffeb000 00:00 0       [stack]

Signed-off-by: Anton Blanchard <anton@samba.org>
---

Index: linux-2.6/arch/powerpc/include/asm/elf.h
===================================================================
--- linux-2.6.orig/arch/powerpc/include/asm/elf.h	2009-02-20 13:39:05.000000000 +1100
+++ linux-2.6/arch/powerpc/include/asm/elf.h	2009-02-20 13:51:20.000000000 +1100
@@ -270,6 +270,11 @@
 				       int uses_interp);
 #define VDSO_AUX_ENT(a,b) NEW_AUX_ENT(a,b);
 
+/* 1GB for 64bit, 8MB for 32bit */
+#define STACK_RND_MASK (is_32bit_task() ? \
+	(0x7ff >> (PAGE_SHIFT - 12)) : \
+	(0x3ffff >> (PAGE_SHIFT - 12)))
+
 #endif /* __KERNEL__ */
 
 /*

-- 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [patch 06/10] powerpc: Randomise lower bits of stack address
  2009-02-22 11:49 [patch 00/10] PowerPC address space randomisation Anton Blanchard
                   ` (4 preceding siblings ...)
  2009-02-22 11:50 ` [patch 05/10] powerpc: More stack randomisation for 64bit binaries Anton Blanchard
@ 2009-02-22 11:50 ` Anton Blanchard
  2009-02-22 11:50 ` [patch 07/10] powerpc: Randomise the brk region Anton Blanchard
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Anton Blanchard @ 2009-02-22 11:50 UTC (permalink / raw)
  To: linuxppc-dev

Randomise the lower bits of the stack address. More randomisation is good for
security but the scatter can also help with SMT threads that share an L1. A
quick test case shows this working:

int main()
{
	int sp;
	printf("%x\n", (unsigned long)&sp & 4095);
}

before:
80
80
80
80
80

after:
610
490
300
6b0
d80

Signed-off-by: Anton Blanchard <anton@samba.org>
---

Index: linux-2.6/arch/powerpc/include/asm/system.h
===================================================================
--- linux-2.6.orig/arch/powerpc/include/asm/system.h	2009-02-20 13:39:05.000000000 +1100
+++ linux-2.6/arch/powerpc/include/asm/system.h	2009-02-20 13:51:39.000000000 +1100
@@ -531,7 +531,7 @@
 #define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
 #endif
 
-#define arch_align_stack(x) (x)
+extern unsigned long arch_align_stack(unsigned long sp);
 
 /* Used in very early kernel initialization. */
 extern unsigned long reloc_offset(void);
Index: linux-2.6/arch/powerpc/kernel/process.c
===================================================================
--- linux-2.6.orig/arch/powerpc/kernel/process.c	2009-02-20 13:39:05.000000000 +1100
+++ linux-2.6/arch/powerpc/kernel/process.c	2009-02-20 13:51:39.000000000 +1100
@@ -34,6 +34,8 @@
 #include <linux/hardirq.h>
 #include <linux/utsname.h>
 #include <linux/kernel_stat.h>
+#include <linux/personality.h>
+#include <linux/random.h>
 
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
@@ -1122,3 +1124,10 @@
 }
 
 #endif /* THREAD_SHIFT < PAGE_SHIFT */
+
+unsigned long arch_align_stack(unsigned long sp)
+{
+	if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
+		sp -= get_random_int() & ~PAGE_MASK;
+	return sp & ~0xf;
+}

-- 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [patch 07/10] powerpc: Randomise the brk region
  2009-02-22 11:49 [patch 00/10] PowerPC address space randomisation Anton Blanchard
                   ` (5 preceding siblings ...)
  2009-02-22 11:50 ` [patch 06/10] powerpc: Randomise lower bits of stack address Anton Blanchard
@ 2009-02-22 11:50 ` Anton Blanchard
  2009-02-22 11:50 ` [patch 08/10] powerpc: Ensure random space between stack and mmaps Anton Blanchard
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Anton Blanchard @ 2009-02-22 11:50 UTC (permalink / raw)
  To: linuxppc-dev

Randomize the heap.

before:
tundro2:~ # sleep 1 & cat /proc/${!}/maps | grep heap
10017000-10118000 rw-p 10017000 00:00 0                                  [heap]
10017000-10118000 rw-p 10017000 00:00 0                                  [heap]
10017000-10118000 rw-p 10017000 00:00 0                                  [heap]
10017000-10118000 rw-p 10017000 00:00 0                                  [heap]
10017000-10118000 rw-p 10017000 00:00 0                                  [heap]


after
tundro2:~ # sleep 1 & cat /proc/${!}/maps | grep heap
19419000-1951a000 rw-p 19419000 00:00 0                                  [heap]
325ff000-32700000 rw-p 325ff000 00:00 0                                  [heap]
1a97c000-1aa7d000 rw-p 1a97c000 00:00 0                                  [heap]
1cc60000-1cd61000 rw-p 1cc60000 00:00 0                                  [heap]
1afa9000-1b0aa000 rw-p 1afa9000 00:00 0                                  [heap]

Signed-off-by: Anton Blanchard <anton@samba.org>
---

Index: linux-2.6/arch/powerpc/include/asm/elf.h
===================================================================
--- linux-2.6.orig/arch/powerpc/include/asm/elf.h	2009-02-20 16:06:32.000000000 +1100
+++ linux-2.6/arch/powerpc/include/asm/elf.h	2009-02-22 11:58:02.000000000 +1100
@@ -275,6 +275,9 @@
 	(0x7ff >> (PAGE_SHIFT - 12)) : \
 	(0x3ffff >> (PAGE_SHIFT - 12)))
 
+extern unsigned long arch_randomize_brk(struct mm_struct *mm);
+#define arch_randomize_brk arch_randomize_brk
+
 #endif /* __KERNEL__ */
 
 /*
Index: linux-2.6/arch/powerpc/kernel/process.c
===================================================================
--- linux-2.6.orig/arch/powerpc/kernel/process.c	2009-02-20 16:06:32.000000000 +1100
+++ linux-2.6/arch/powerpc/kernel/process.c	2009-02-22 11:58:02.000000000 +1100
@@ -1131,3 +1131,26 @@
 		sp -= get_random_int() & ~PAGE_MASK;
 	return sp & ~0xf;
 }
+
+static inline unsigned long brk_rnd(void)
+{
+        unsigned long rnd = 0;
+
+	/* 8MB for 32bit, 1GB for 64bit */
+	if (is_32bit_task())
+		rnd = (long)(get_random_int() % (1<<(23-PAGE_SHIFT)));
+	else
+		rnd = (long)(get_random_int() % (1<<(30-PAGE_SHIFT)));
+
+	return rnd << PAGE_SHIFT;
+}
+
+unsigned long arch_randomize_brk(struct mm_struct *mm)
+{
+	unsigned long ret = PAGE_ALIGN(mm->brk + brk_rnd());
+
+	if (ret < mm->brk)
+		return mm->brk;
+
+	return ret;
+}

-- 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [patch 08/10] powerpc: Ensure random space between stack and mmaps
  2009-02-22 11:49 [patch 00/10] PowerPC address space randomisation Anton Blanchard
                   ` (6 preceding siblings ...)
  2009-02-22 11:50 ` [patch 07/10] powerpc: Randomise the brk region Anton Blanchard
@ 2009-02-22 11:50 ` Anton Blanchard
  2009-02-22 11:50 ` [patch 09/10] powerpc: Increase stack gap on 64bit binaries Anton Blanchard
  2009-02-22 11:50 ` [patch 10/10] powerpc: Randomise PIEs Anton Blanchard
  9 siblings, 0 replies; 11+ messages in thread
From: Anton Blanchard @ 2009-02-22 11:50 UTC (permalink / raw)
  To: linuxppc-dev

get_random_int() returns the same value within a 1 jiffy interval. This means
that the mmap and stack regions will almost always end up the same distance
apart, making a relative offset based attack possible.

To fix this, shift the randomness we use for the mmap region by 1 bit.

Signed-off-by: Anton Blanchard <anton@samba.org>
---

Index: linux-2.6/arch/powerpc/mm/mmap.c
===================================================================
--- linux-2.6.orig/arch/powerpc/mm/mmap.c	2009-02-22 11:58:54.000000000 +1100
+++ linux-2.6/arch/powerpc/mm/mmap.c	2009-02-22 12:05:01.000000000 +1100
@@ -46,6 +46,14 @@
 	return sysctl_legacy_va_layout;
 }
 
+/*
+ * Since get_random_int() returns the same value within a 1 jiffy window,
+ * we will almost always get the same randomisation for the stack and mmap
+ * region. This will mean the relative distance between stack and mmap will
+ * be the same.
+ *
+ * To avoid this we can shift the randomness by 1 bit.
+ */
 static unsigned long mmap_rnd(void)
 {
 	unsigned long rnd = 0;
@@ -53,11 +61,11 @@
 	if (current->flags & PF_RANDOMIZE) {
 		/* 8MB for 32bit, 1GB for 64bit */
 		if (is_32bit_task())
-			rnd = (long)(get_random_int() % (1<<(23-PAGE_SHIFT)));
+			rnd = (long)(get_random_int() % (1<<(22-PAGE_SHIFT)));
 		else
-			rnd = (long)(get_random_int() % (1<<(30-PAGE_SHIFT)));
+			rnd = (long)(get_random_int() % (1<<(29-PAGE_SHIFT)));
 	}
-	return rnd << PAGE_SHIFT;
+	return (rnd << PAGE_SHIFT) * 2;
 }
 
 static inline unsigned long mmap_base(void)

-- 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [patch 09/10] powerpc: Increase stack gap on 64bit binaries
  2009-02-22 11:49 [patch 00/10] PowerPC address space randomisation Anton Blanchard
                   ` (7 preceding siblings ...)
  2009-02-22 11:50 ` [patch 08/10] powerpc: Ensure random space between stack and mmaps Anton Blanchard
@ 2009-02-22 11:50 ` Anton Blanchard
  2009-02-22 11:50 ` [patch 10/10] powerpc: Randomise PIEs Anton Blanchard
  9 siblings, 0 replies; 11+ messages in thread
From: Anton Blanchard @ 2009-02-22 11:50 UTC (permalink / raw)
  To: linuxppc-dev

On 64bit there is a possibility our stack and mmap randomisation will put
the two close enough such that we can't expand our stack to match the ulimit
specified.

To avoid this, start the upper mmap address at 1GB + 128MB below the top of our
address space, so in the worst case we end up with the same ~128MB hole as in
32bit. This works because we randomise the stack over a 1GB range.

Signed-off-by: Anton Blanchard <anton@samba.org>
---

Index: linux-2.6/arch/powerpc/mm/mmap.c
===================================================================
--- linux-2.6.orig/arch/powerpc/mm/mmap.c	2009-02-21 09:52:23.000000000 +1100
+++ linux-2.6/arch/powerpc/mm/mmap.c	2009-02-21 10:36:36.000000000 +1100
@@ -30,9 +30,16 @@
 /*
  * Top of mmap area (just below the process stack).
  *
- * Leave an at least ~128 MB hole.
+ * Leave at least a ~128 MB hole on 32bit applications.
+ *
+ * On 64bit applications we randomise the stack by 1GB so we need to
+ * space our mmap start address by a further 1GB, otherwise there is a
+ * chance the mmap area will end up closer to the stack than our ulimit
+ * requires.
  */
-#define MIN_GAP (128*1024*1024)
+#define MIN_GAP32 (128*1024*1024)
+#define MIN_GAP64 ((128 + 1024)*1024*1024UL)
+#define MIN_GAP ((is_32bit_task()) ? MIN_GAP32 : MIN_GAP64)
 #define MAX_GAP (TASK_SIZE/6*5)
 
 static inline int mmap_is_legacy(void)

-- 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [patch 10/10] powerpc: Randomise PIEs
  2009-02-22 11:49 [patch 00/10] PowerPC address space randomisation Anton Blanchard
                   ` (8 preceding siblings ...)
  2009-02-22 11:50 ` [patch 09/10] powerpc: Increase stack gap on 64bit binaries Anton Blanchard
@ 2009-02-22 11:50 ` Anton Blanchard
  9 siblings, 0 replies; 11+ messages in thread
From: Anton Blanchard @ 2009-02-22 11:50 UTC (permalink / raw)
  To: linuxppc-dev

Randomise ELF_ET_DYN_BASE, which is used when loading position independent
executables.

Signed-off-by: Anton Blanchard <anton@samba.org>
---

Index: linux-2.6/arch/powerpc/include/asm/elf.h
===================================================================
--- linux-2.6.orig/arch/powerpc/include/asm/elf.h	2009-02-22 21:18:04.000000000 +1100
+++ linux-2.6/arch/powerpc/include/asm/elf.h	2009-02-22 21:34:49.000000000 +1100
@@ -178,7 +178,8 @@
    the loader.  We need to make sure that it is out of the way of the program
    that it will "exec", and that there is sufficient room for the brk.  */
 
-#define ELF_ET_DYN_BASE         (0x20000000)
+extern unsigned long randomize_et_dyn(unsigned long base);
+#define ELF_ET_DYN_BASE		(randomize_et_dyn(0x20000000))
 
 /*
  * Our registers are always unsigned longs, whether we're a 32 bit
Index: linux-2.6/arch/powerpc/kernel/process.c
===================================================================
--- linux-2.6.orig/arch/powerpc/kernel/process.c	2009-02-22 21:21:14.000000000 +1100
+++ linux-2.6/arch/powerpc/kernel/process.c	2009-02-22 21:36:02.000000000 +1100
@@ -1154,3 +1154,13 @@
 
 	return ret;
 }
+
+unsigned long randomize_et_dyn(unsigned long base)
+{
+	unsigned long ret = PAGE_ALIGN(base + brk_rnd());
+
+	if (ret < base)
+		return base;
+
+	return ret;
+}

-- 

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2009-02-22 11:50 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-02-22 11:49 [patch 00/10] PowerPC address space randomisation Anton Blanchard
2009-02-22 11:49 ` [patch 01/10] powerpc: Move is_32bit_task Anton Blanchard
2009-02-22 11:49 ` [patch 02/10] powerpc: Use new layout for 64bit binaries Anton Blanchard
2009-02-22 11:50 ` [patch 03/10] powerpc: Rearrange mmap.c Anton Blanchard
2009-02-22 11:50 ` [patch 04/10] powerpc: Randomise mmap start address Anton Blanchard
2009-02-22 11:50 ` [patch 05/10] powerpc: More stack randomisation for 64bit binaries Anton Blanchard
2009-02-22 11:50 ` [patch 06/10] powerpc: Randomise lower bits of stack address Anton Blanchard
2009-02-22 11:50 ` [patch 07/10] powerpc: Randomise the brk region Anton Blanchard
2009-02-22 11:50 ` [patch 08/10] powerpc: Ensure random space between stack and mmaps Anton Blanchard
2009-02-22 11:50 ` [patch 09/10] powerpc: Increase stack gap on 64bit binaries Anton Blanchard
2009-02-22 11:50 ` [patch 10/10] powerpc: Randomise PIEs Anton Blanchard

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).