powerpc: Randomise the brk region
authorAnton Blanchard <anton@samba.org>
Sun, 22 Feb 2009 01:50:04 +0000 (01:50 +0000)
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>
Mon, 23 Feb 2009 04:53:20 +0000 (15:53 +1100)
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>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
arch/powerpc/include/asm/elf.h
arch/powerpc/kernel/process.c

index 3f94d88..968b37f 100644 (file)
@@ -276,6 +276,9 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
        (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 69b9d2d..30b149c 100644 (file)
@@ -1147,3 +1147,26 @@ unsigned long arch_align_stack(unsigned long sp)
                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;
+}