Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mm: split ET_DYN ASLR from mmap ASLR

This fixes the "offset2lib" weakness in ASLR for arm, arm64, mips,
powerpc, and x86. The problem is that if there is a leak of ASLR from
the executable (ET_DYN), it means a leak of shared library offset as
well (mmap), and vice versa. Further details and a PoC of this attack
is available here:

http://cybersecurity.upv.es/attacks/offset2lib/offset2lib.html

With this patch, a PIE linked executable (ET_DYN) has its own ASLR
region:

$ ./show_mmaps_pie
54859ccd6000-54859ccd7000 r-xp ... /tmp/show_mmaps_pie
54859ced6000-54859ced7000 r--p ... /tmp/show_mmaps_pie
54859ced7000-54859ced8000 rw-p ... /tmp/show_mmaps_pie
7f75be764000-7f75be91f000 r-xp ... /lib/x86_64-linux-gnu/libc.so.6
7f75be91f000-7f75beb1f000 ---p ... /lib/x86_64-linux-gnu/libc.so.6
7f75beb1f000-7f75beb23000 r--p ... /lib/x86_64-linux-gnu/libc.so.6
7f75beb23000-7f75beb25000 rw-p ... /lib/x86_64-linux-gnu/libc.so.6
7f75beb25000-7f75beb2a000 rw-p ...
7f75beb2a000-7f75beb4d000 r-xp ... /lib64/ld-linux-x86-64.so.2
7f75bed45000-7f75bed46000 rw-p ...
7f75bed46000-7f75bed47000 r-xp ...
7f75bed47000-7f75bed4c000 rw-p ...
7f75bed4c000-7f75bed4d000 r--p ... /lib64/ld-linux-x86-64.so.2
7f75bed4d000-7f75bed4e000 rw-p ... /lib64/ld-linux-x86-64.so.2
7f75bed4e000-7f75bed4f000 rw-p ...
7fffb3741000-7fffb3762000 rw-p ... [stack]
7fffb377b000-7fffb377d000 r--p ... [vvar]
7fffb377d000-7fffb377f000 r-xp ... [vdso]

The change is to add a call the newly created arch_mmap_rnd() into the
ELF loader for handling ET_DYN ASLR in a separate region from mmap ASLR,
as was already done on s390. Removes CONFIG_BINFMT_ELF_RANDOMIZE_PIE,
which is no longer needed.

Signed-off-by: Kees Cook <keescook@chromium.org>
Reported-by: Hector Marco-Gisbert <hecmargi@upv.es>
Cc: Russell King <linux@arm.linux.org.uk>
Reviewed-by: Ingo Molnar <mingo@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: "David A. Long" <dave.long@linaro.org>
Cc: Andrey Ryabinin <a.ryabinin@samsung.com>
Cc: Arun Chandran <achandran@mvista.com>
Cc: Yann Droneaud <ydroneaud@opteya.com>
Cc: Min-Hua Chen <orca.chen@gmail.com>
Cc: Paul Burton <paul.burton@imgtec.com>
Cc: Alex Smith <alex@alex-smith.me.uk>
Cc: Markos Chandras <markos.chandras@imgtec.com>
Cc: Vineeth Vijayan <vvijayan@mvista.com>
Cc: Jeff Bailey <jeffbailey@google.com>
Cc: Michael Holzheu <holzheu@linux.vnet.ibm.com>
Cc: Ben Hutchings <ben@decadent.org.uk>
Cc: Behan Webster <behanw@converseincode.com>
Cc: Ismael Ripoll <iripoll@upv.es>
Cc: Jan-Simon Mller <dl9pf@gmx.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Kees Cook and committed by
Linus Torvalds
d1fd836d c6f5b001

+6 -33
-1
arch/arm/Kconfig
··· 1 1 config ARM 2 2 bool 3 3 default y 4 - select ARCH_BINFMT_ELF_RANDOMIZE_PIE 5 4 select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE 6 5 select ARCH_HAS_ELF_RANDOMIZE 7 6 select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
-1
arch/arm64/Kconfig
··· 1 1 config ARM64 2 2 def_bool y 3 - select ARCH_BINFMT_ELF_RANDOMIZE_PIE 4 3 select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE 5 4 select ARCH_HAS_ELF_RANDOMIZE 6 5 select ARCH_HAS_GCOV_PROFILE_ALL
-1
arch/mips/Kconfig
··· 23 23 select HAVE_KRETPROBES 24 24 select HAVE_DEBUG_KMEMLEAK 25 25 select HAVE_SYSCALL_TRACEPOINTS 26 - select ARCH_BINFMT_ELF_RANDOMIZE_PIE 27 26 select ARCH_HAS_ELF_RANDOMIZE 28 27 select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES && 64BIT 29 28 select RTC_LIB if !MACH_LOONGSON
-1
arch/powerpc/Kconfig
··· 88 88 select ARCH_MIGHT_HAVE_PC_PARPORT 89 89 select ARCH_MIGHT_HAVE_PC_SERIO 90 90 select BINFMT_ELF 91 - select ARCH_BINFMT_ELF_RANDOMIZE_PIE 92 91 select ARCH_HAS_ELF_RANDOMIZE 93 92 select OF 94 93 select OF_EARLY_FLATTREE
+2 -3
arch/s390/include/asm/elf.h
··· 163 163 the loader. We need to make sure that it is out of the way of the program 164 164 that it will "exec", and that there is sufficient room for the brk. 64-bit 165 165 tasks are aligned to 4GB. */ 166 - extern unsigned long randomize_et_dyn(void); 167 - #define ELF_ET_DYN_BASE (randomize_et_dyn() + (is_32bit_task() ? \ 166 + #define ELF_ET_DYN_BASE (is_32bit_task() ? \ 168 167 (STACK_TOP / 3 * 2) : \ 169 - (STACK_TOP / 3 * 2) & ~((1UL << 32) - 1))) 168 + (STACK_TOP / 3 * 2) & ~((1UL << 32) - 1)) 170 169 171 170 /* This yields a mask that user programs can use to figure out what 172 171 instruction set this CPU supports. */
-8
arch/s390/mm/mmap.c
··· 177 177 return addr; 178 178 } 179 179 180 - unsigned long randomize_et_dyn(void) 181 - { 182 - if (current->flags & PF_RANDOMIZE) 183 - return arch_mmap_rnd(); 184 - 185 - return 0UL; 186 - } 187 - 188 180 #ifndef CONFIG_64BIT 189 181 190 182 /*
-1
arch/x86/Kconfig
··· 87 87 select HAVE_ARCH_KMEMCHECK 88 88 select HAVE_ARCH_KASAN if X86_64 && SPARSEMEM_VMEMMAP 89 89 select HAVE_USER_RETURN_NOTIFIER 90 - select ARCH_BINFMT_ELF_RANDOMIZE_PIE 91 90 select ARCH_HAS_ELF_RANDOMIZE 92 91 select HAVE_ARCH_JUMP_LABEL 93 92 select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
-3
fs/Kconfig.binfmt
··· 27 27 bool 28 28 depends on COMPAT && BINFMT_ELF 29 29 30 - config ARCH_BINFMT_ELF_RANDOMIZE_PIE 31 - bool 32 - 33 30 config ARCH_BINFMT_ELF_STATE 34 31 bool 35 32
+4 -14
fs/binfmt_elf.c
··· 31 31 #include <linux/security.h> 32 32 #include <linux/random.h> 33 33 #include <linux/elf.h> 34 + #include <linux/elf-randomize.h> 34 35 #include <linux/utsname.h> 35 36 #include <linux/coredump.h> 36 37 #include <linux/sched.h> ··· 911 910 * default mmap base, as well as whatever program they 912 911 * might try to exec. This is because the brk will 913 912 * follow the loader, and is not movable. */ 914 - #ifdef CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE 915 - /* Memory randomization might have been switched off 916 - * in runtime via sysctl or explicit setting of 917 - * personality flags. 918 - * If that is the case, retain the original non-zero 919 - * load_bias value in order to establish proper 920 - * non-randomized mappings. 921 - */ 913 + load_bias = ELF_ET_DYN_BASE - vaddr; 922 914 if (current->flags & PF_RANDOMIZE) 923 - load_bias = 0; 924 - else 925 - load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr); 926 - #else 927 - load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr); 928 - #endif 915 + load_bias += arch_mmap_rnd(); 916 + load_bias = ELF_PAGESTART(load_bias); 929 917 total_size = total_mapping_size(elf_phdata, 930 918 loc->elf_ex.e_phnum); 931 919 if (!total_size) {