mm: split ET_DYN ASLR from mmap ASLR 28/276528/1 accepted/tizen/6.5/unified/20220621.140310 accepted/tizen/unified/20220621.140350 submit/tizen/20220620.065520 submit/tizen_6.5/20220620.065947
authorKees Cook <keescook@chromium.org>
Tue, 14 Apr 2015 22:48:07 +0000 (15:48 -0700)
committerSeung-Woo Kim <sw0312.kim@samsung.com>
Mon, 20 Jun 2022 05:26:43 +0000 (14:26 +0900)
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>
[sw0312.kim: back-port mainline commit d1fd836dcf00 to fix pie executable heap address issue]
Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
Change-Id: I86d8daa6a489f61205cc97b465c43273460b0c66

arch/arm/Kconfig
arch/mips/Kconfig
arch/s390/include/asm/elf.h
arch/s390/kernel/process.c
arch/x86/Kconfig
fs/Kconfig.binfmt
fs/binfmt_elf.c

index b85ea23..bb6d20c 100644 (file)
@@ -1,7 +1,6 @@
 config ARM
        bool
        default y
-       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
        select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
        select ARCH_HAS_ELF_RANDOMIZE
        select ARCH_HAVE_CUSTOM_GPIO_H
index d4d68be..a6953bf 100644 (file)
@@ -17,7 +17,6 @@ config MIPS
        select HAVE_KPROBES
        select HAVE_KRETPROBES
        select HAVE_DEBUG_KMEMLEAK
-       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
        select ARCH_HAS_ELF_RANDOMIZE
        select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES && 64BIT
        select RTC_LIB if !MACH_LOONGSON
index 78f4f87..ad95788 100644 (file)
@@ -162,8 +162,7 @@ extern unsigned int vdso_enabled;
    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.  */
 
-extern unsigned long randomize_et_dyn(unsigned long base);
-#define ELF_ET_DYN_BASE                (randomize_et_dyn(STACK_TOP / 3 * 2))
+#define ELF_ET_DYN_BASE                (STACK_TOP / 3 * 2)
 
 /* This yields a mask that user programs can use to figure out what
    instruction set this CPU supports. */
index 2bc3edd..8553f6b 100644 (file)
@@ -261,14 +261,3 @@ unsigned long arch_randomize_brk(struct mm_struct *mm)
                return mm->brk;
        return ret;
 }
-
-unsigned long randomize_et_dyn(unsigned long base)
-{
-       unsigned long ret = PAGE_ALIGN(base + brk_rnd());
-
-       if (!(current->flags & PF_RANDOMIZE))
-               return base;
-       if (ret < base)
-               return base;
-       return ret;
-}
index 0bd682c..e4cda58 100644 (file)
@@ -78,7 +78,6 @@ config X86
        select HAVE_CMPXCHG_DOUBLE
        select HAVE_ARCH_KMEMCHECK
        select HAVE_USER_RETURN_NOTIFIER
-       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
        select ARCH_HAS_ELF_RANDOMIZE
        select HAVE_ARCH_JUMP_LABEL
        select HAVE_TEXT_POKE_SMP
index 370b24c..81f7515 100644 (file)
@@ -27,9 +27,6 @@ config COMPAT_BINFMT_ELF
        bool
        depends on COMPAT && BINFMT_ELF
 
-config ARCH_BINFMT_ELF_RANDOMIZE_PIE
-       bool
-
 config BINFMT_ELF_FDPIC
        bool "Kernel support for FDPIC ELF binaries"
        default y
index 3c4d879..b29e741 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/security.h>
 #include <linux/random.h>
 #include <linux/elf.h>
+#include <linux/elf-randomize.h>
 #include <linux/utsname.h>
 #include <linux/coredump.h>
 #include <linux/sched.h>
@@ -805,21 +806,10 @@ static int load_elf_binary(struct linux_binprm *bprm)
                         * default mmap base, as well as whatever program they
                         * might try to exec.  This is because the brk will
                         * follow the loader, and is not movable.  */
-#ifdef CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE
-                       /* Memory randomization might have been switched off
-                        * in runtime via sysctl or explicit setting of
-                        * personality flags.
-                        * If that is the case, retain the original non-zero
-                        * load_bias value in order to establish proper
-                        * non-randomized mappings.
-                        */
+                       load_bias = ELF_ET_DYN_BASE - vaddr;
                        if (current->flags & PF_RANDOMIZE)
-                               load_bias = 0;
-                       else
-                               load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
-#else
-                       load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
-#endif
+                               load_bias += arch_mmap_rnd();
+                       load_bias = ELF_PAGESTART(load_bias);
                }
 
                error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,