diff options
author | Vineeth Vijayan <vvijayan@mvista.com> | 2014-11-14 04:12:05 -0500 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2014-11-17 01:55:11 -0500 |
commit | 59994fb01a102a448ba758c9b824a29b4a99cc1b (patch) | |
tree | 3dfb16993c500822787ebc76098d2cd5525da0da | |
parent | cf2b1e0eb0c281122b001cc879ca0118bff71255 (diff) |
powerpc: Use generic PIE randomization
Back in 2009 we merged 501cb16d3cfd "Randomise PIEs", which added support for
randomizing PIE (Position Independent Executable) binaries.
That commit added randomize_et_dyn(), which correctly randomized the addresses,
but failed to honor PF_RANDOMIZE. That means it was not possible to disable PIE
randomization via the personality flag, or /proc/sys/kernel/randomize_va_space.
Since then there has been generic support for PIE randomization added to
binfmt_elf.c, selectable via ARCH_BINFMT_ELF_RANDOMIZE_PIE.
Enabling that allows us to drop randomize_et_dyn(), which means we start
honoring PF_RANDOMIZE correctly.
It also causes a fairly major change to how we layout PIE binaries.
Currently we will place the binary at 512MB-520MB for 32 bit binaries, or
512MB-1.5GB for 64 bit binaries, eg:
$ cat /proc/$$/maps
4e550000-4e580000 r-xp 00000000 08:02 129813 /bin/dash
4e580000-4e590000 rw-p 00020000 08:02 129813 /bin/dash
10014110000-10014140000 rw-p 00000000 00:00 0 [heap]
3fffaa3f0000-3fffaa5a0000 r-xp 00000000 08:02 921 /lib/powerpc64le-linux-gnu/libc-2.19.so
3fffaa5a0000-3fffaa5b0000 rw-p 001a0000 08:02 921 /lib/powerpc64le-linux-gnu/libc-2.19.so
3fffaa5c0000-3fffaa5d0000 rw-p 00000000 00:00 0
3fffaa5d0000-3fffaa5f0000 r-xp 00000000 00:00 0 [vdso]
3fffaa5f0000-3fffaa620000 r-xp 00000000 08:02 1246 /lib/powerpc64le-linux-gnu/ld-2.19.so
3fffaa620000-3fffaa630000 rw-p 00020000 08:02 1246 /lib/powerpc64le-linux-gnu/ld-2.19.so
3ffffc340000-3ffffc370000 rw-p 00000000 00:00 0 [stack]
With this commit applied we don't do any special randomisation for the binary,
and instead rely on mmap randomisation. This means the binary ends up at high
addresses, eg:
$ cat /proc/$$/maps
3fff99820000-3fff999d0000 r-xp 00000000 08:02 921 /lib/powerpc64le-linux-gnu/libc-2.19.so
3fff999d0000-3fff999e0000 rw-p 001a0000 08:02 921 /lib/powerpc64le-linux-gnu/libc-2.19.so
3fff999f0000-3fff99a00000 rw-p 00000000 00:00 0
3fff99a00000-3fff99a20000 r-xp 00000000 00:00 0 [vdso]
3fff99a20000-3fff99a50000 r-xp 00000000 08:02 1246 /lib/powerpc64le-linux-gnu/ld-2.19.so
3fff99a50000-3fff99a60000 rw-p 00020000 08:02 1246 /lib/powerpc64le-linux-gnu/ld-2.19.so
3fff99a60000-3fff99a90000 r-xp 00000000 08:02 129813 /bin/dash
3fff99a90000-3fff99aa0000 rw-p 00020000 08:02 129813 /bin/dash
3fffc3de0000-3fffc3e10000 rw-p 00000000 00:00 0 [stack]
3fffc55e0000-3fffc5610000 rw-p 00000000 00:00 0 [heap]
Although this should be OK, it's possible it might break badly written
binaries that make assumptions about the address space layout.
Signed-off-by: Vineeth Vijayan <vvijayan@mvista.com>
[mpe: Rewrite changelog]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-rw-r--r-- | arch/powerpc/Kconfig | 1 | ||||
-rw-r--r-- | arch/powerpc/include/asm/elf.h | 3 | ||||
-rw-r--r-- | arch/powerpc/kernel/process.c | 9 |
3 files changed, 2 insertions, 11 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 46227336aacb..421df5cc6d18 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
@@ -88,6 +88,7 @@ config PPC | |||
88 | select ARCH_MIGHT_HAVE_PC_PARPORT | 88 | select ARCH_MIGHT_HAVE_PC_PARPORT |
89 | select ARCH_MIGHT_HAVE_PC_SERIO | 89 | select ARCH_MIGHT_HAVE_PC_SERIO |
90 | select BINFMT_ELF | 90 | select BINFMT_ELF |
91 | select ARCH_BINFMT_ELF_RANDOMIZE_PIE | ||
91 | select OF | 92 | select OF |
92 | select OF_EARLY_FLATTREE | 93 | select OF_EARLY_FLATTREE |
93 | select OF_RESERVED_MEM | 94 | select OF_RESERVED_MEM |
diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h index 888d8f3f2524..57d289acb803 100644 --- a/arch/powerpc/include/asm/elf.h +++ b/arch/powerpc/include/asm/elf.h | |||
@@ -28,8 +28,7 @@ | |||
28 | the loader. We need to make sure that it is out of the way of the program | 28 | the loader. We need to make sure that it is out of the way of the program |
29 | that it will "exec", and that there is sufficient room for the brk. */ | 29 | that it will "exec", and that there is sufficient room for the brk. */ |
30 | 30 | ||
31 | extern unsigned long randomize_et_dyn(unsigned long base); | 31 | #define ELF_ET_DYN_BASE 0x20000000 |
32 | #define ELF_ET_DYN_BASE (randomize_et_dyn(0x20000000)) | ||
33 | 32 | ||
34 | #define ELF_CORE_EFLAGS (is_elf2_task() ? 2 : 0) | 33 | #define ELF_CORE_EFLAGS (is_elf2_task() ? 2 : 0) |
35 | 34 | ||
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index f6b82152e7aa..b4cc7bef6b16 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c | |||
@@ -1654,12 +1654,3 @@ unsigned long arch_randomize_brk(struct mm_struct *mm) | |||
1654 | return ret; | 1654 | return ret; |
1655 | } | 1655 | } |
1656 | 1656 | ||
1657 | unsigned long randomize_et_dyn(unsigned long base) | ||
1658 | { | ||
1659 | unsigned long ret = PAGE_ALIGN(base + brk_rnd()); | ||
1660 | |||
1661 | if (ret < base) | ||
1662 | return base; | ||
1663 | |||
1664 | return ret; | ||
1665 | } | ||