mm: expose arch_mmap_rnd when available 27/276527/1
authorKees Cook <keescook@chromium.org>
Tue, 14 Apr 2015 22:48:00 +0000 (15:48 -0700)
committerSeung-Woo Kim <sw0312.kim@samsung.com>
Mon, 20 Jun 2022 05:26:29 +0000 (14:26 +0900)
When an architecture fully supports randomizing the ELF load location,
a per-arch mmap_rnd() function is used to find a randomized mmap base.
In preparation for randomizing the location of ET_DYN binaries
separately from mmap, this renames and exports these functions as
arch_mmap_rnd(). Additionally introduces CONFIG_ARCH_HAS_ELF_RANDOMIZE
for describing this feature on architectures that support it
(which is a superset of ARCH_BINFMT_ELF_RANDOMIZE_PIE, since s390
already supports a separated ET_DYN ASLR from mmap ASLR without the
ARCH_BINFMT_ELF_RANDOMIZE_PIE logic).

Signed-off-by: Kees Cook <keescook@chromium.org>
Cc: 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 upstream commit 2b68f6caeac2 to apply upstream commit d1fd836dcf00 ("mm: split ET_DYN ASLR from mmap ASLR")]
Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
Change-Id: I31089760dd503776dc0473b6bce777389e3d6a1e

14 files changed:
arch/Kconfig
arch/arm/Kconfig
arch/arm/mm/mmap.c
arch/arm64/Kconfig
arch/arm64/mm/mmap.c
arch/mips/Kconfig
arch/mips/mm/mmap.c
arch/powerpc/Kconfig
arch/powerpc/mm/mmap_64.c
arch/s390/Kconfig
arch/s390/mm/mmap.c
arch/x86/Kconfig
arch/x86/mm/mmap.c
include/linux/elf-randomize.h [new file with mode: 0644]

index 4c0a1d03ae0d82940ac6328ebbd8fba3c32c3d67..b3eef6d51fc26af2657e1468f1d442b2ddb42fc5 100644 (file)
@@ -391,6 +391,13 @@ config HAVE_UNDERSCORE_SYMBOL_PREFIX
          Some architectures generate an _ in front of C symbols; things like
          module loading and assembly files need to know about this.
 
+config ARCH_HAS_ELF_RANDOMIZE
+       bool
+       help
+         An architecture supports choosing randomized locations for
+         stack, mmap, brk, and ET_DYN. Defined functions:
+         - arch_mmap_rnd()
+
 #
 # ABI hall of shame
 #
index cf3ea92670683d813a73e0ab2ed41dc71feb5b30..b85ea23b7ab6b644558e20732aa8632f1d8f6331 100644 (file)
@@ -3,6 +3,7 @@ config ARM
        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
        select ARCH_SUPPORTS_ATOMIC_RMW
        select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
index 4ece7d2320337c79e3977a96c08a79a89258d41d..e3236037ae7db4347131527be82fe751c0826dbb 100644 (file)
@@ -169,7 +169,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
        return addr;
 }
 
-static unsigned long mmap_rnd(void)
+unsigned long arch_mmap_rnd(void)
 {
        unsigned long rnd;
 
@@ -184,7 +184,7 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
        unsigned long random_factor = 0UL;
 
        if (current->flags & PF_RANDOMIZE)
-               random_factor = mmap_rnd();
+               random_factor = arch_mmap_rnd();
 
        if (mmap_is_legacy()) {
                mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
index 7bdcfc43a7e2985ed04f9cf3a38394a510098344..2d3a59333f7c27af641e89adbe7f902606561e8b 100755 (executable)
@@ -1,6 +1,7 @@
 config ARM64
        def_bool y
        select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
+       select ARCH_HAS_ELF_RANDOMIZE
        select ARCH_HAS_OPP
        select ARCH_USE_CMPXCHG_LOCKREF
        select ARCH_HAS_OPP
index 7c7be78556387ed548c3c37641cef3be9441ef5a..5754a124d7e411661923de40bac541e638a6c0f4 100644 (file)
@@ -55,7 +55,7 @@ static int mmap_is_legacy(void)
  *
  * To avoid this we can shift the randomness by 1 bit.
  */
-static unsigned long mmap_rnd(void)
+unsigned long arch_mmap_rnd(void)
 {
        unsigned long rnd = 0;
 
@@ -74,7 +74,7 @@ static unsigned long mmap_base(void)
        else if (gap > MAX_GAP)
                gap = MAX_GAP;
 
-       return PAGE_ALIGN(STACK_TOP - gap - mmap_rnd());
+       return PAGE_ALIGN(STACK_TOP - gap - arch_mmap_rnd());
 }
 
 /*
index e53e2b40d695ffcc329d820741b0160c650953bd..d4d68be876191cbd43f570c27069a127915efa11 100644 (file)
@@ -18,6 +18,7 @@ config MIPS
        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
        select GENERIC_ATOMIC64 if !64BIT
index 62dfe499cc3020405681ca796db896372d12e88e..cfb18b96bf5ea07bfbc4b855320a4847afe4b4a3 100644 (file)
@@ -142,7 +142,7 @@ unsigned long arch_get_unmapped_area_topdown(struct file *filp,
                        addr0, len, pgoff, flags, DOWN);
 }
 
-static unsigned long mmap_rnd(void)
+unsigned long arch_mmap_rnd(void)
 {
        unsigned long rnd;
 
@@ -161,7 +161,7 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
        unsigned long random_factor = 0UL;
 
        if (current->flags & PF_RANDOMIZE)
-               random_factor = mmap_rnd();
+               random_factor = arch_mmap_rnd();
 
        if (mmap_is_legacy()) {
                mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
index 7f656f119ea67513eb7aab29419aebf79a19e7de..a5c532468644977167390684b36b1c299acbc89d 100644 (file)
@@ -86,6 +86,7 @@ config PPC
        bool
        default y
        select BINFMT_ELF
+       select ARCH_HAS_ELF_RANDOMIZE
        select OF
        select OF_EARLY_FLATTREE
        select HAVE_FTRACE_MCOUNT_RECORD
index 67a42ed0d2fc8408c7ecb197a3c5bf58c5bee6df..1d0bbb78579861b32463b7e47f5bd6502581d5f9 100644 (file)
@@ -53,7 +53,7 @@ static inline int mmap_is_legacy(void)
        return sysctl_legacy_va_layout;
 }
 
-static unsigned long mmap_rnd(void)
+unsigned long arch_mmap_rnd(void)
 {
        unsigned long rnd = 0;
 
@@ -76,7 +76,7 @@ static inline unsigned long mmap_base(void)
        else if (gap > MAX_GAP)
                gap = MAX_GAP;
 
-       return PAGE_ALIGN(TASK_SIZE - gap - mmap_rnd());
+       return PAGE_ALIGN(TASK_SIZE - gap - arch_mmap_rnd());
 }
 
 /*
index d8d6eeca56b0abaebcda8c6022f74257d6103292..3ec010f238d8e664f3f6c7591f82c8dd4e860903 100644 (file)
@@ -62,6 +62,7 @@ config S390
        def_bool y
        select ARCH_DISCARD_MEMBLOCK
        select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
+       select ARCH_HAS_ELF_RANDOMIZE
        select ARCH_HAVE_NMI_SAFE_CMPXCHG
        select ARCH_INLINE_READ_LOCK
        select ARCH_INLINE_READ_LOCK_BH
index 06bafec00278c654d616c731a2711a0b7b5beced..97a18b0944765954237bc019b07edd37c598f1cd 100644 (file)
@@ -56,7 +56,7 @@ static inline int mmap_is_legacy(void)
        return sysctl_legacy_va_layout;
 }
 
-static unsigned long mmap_rnd(void)
+unsigned long arch_mmap_rnd(void)
 {
        if (!(current->flags & PF_RANDOMIZE))
                return 0;
@@ -73,7 +73,7 @@ static inline unsigned long mmap_base(void)
        else if (gap > MAX_GAP)
                gap = MAX_GAP;
        gap &= PAGE_MASK;
-       return STACK_TOP - stack_maxrandom_size() - mmap_rnd() - gap;
+       return STACK_TOP - stack_maxrandom_size() - arch_mmap_rnd() - gap;
 }
 
 #ifndef CONFIG_64BIT
index 3115eae96ad8a2963d2d78fbf18a8189ac8dde28..0bd682cf5989796ec0713cbbce0e1952ba1be6dc 100644 (file)
@@ -79,6 +79,7 @@ config X86
        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
        select HAVE_GENERIC_HARDIRQS
index 75f9e5d80d02fd8d4944836213acb5d406e41c04..3e7fded6b7a65cbbd7c64eb667986a1cd3b594d6 100644 (file)
@@ -65,7 +65,7 @@ static int mmap_is_legacy(void)
        return sysctl_legacy_va_layout;
 }
 
-static unsigned long mmap_rnd(void)
+unsigned long arch_mmap_rnd(void)
 {
        unsigned long rnd = 0;
 
@@ -91,7 +91,7 @@ static unsigned long mmap_base(void)
        else if (gap > MAX_GAP)
                gap = MAX_GAP;
 
-       return PAGE_ALIGN(TASK_SIZE - gap - mmap_rnd());
+       return PAGE_ALIGN(TASK_SIZE - gap - arch_mmap_rnd());
 }
 
 /*
@@ -103,7 +103,7 @@ static unsigned long mmap_legacy_base(void)
        if (mmap_is_ia32())
                return TASK_UNMAPPED_BASE;
        else
-               return TASK_UNMAPPED_BASE + mmap_rnd();
+               return TASK_UNMAPPED_BASE + arch_mmap_rnd();
 }
 
 /*
diff --git a/include/linux/elf-randomize.h b/include/linux/elf-randomize.h
new file mode 100644 (file)
index 0000000..7a4eda0
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef _ELF_RANDOMIZE_H
+#define _ELF_RANDOMIZE_H
+
+#ifndef CONFIG_ARCH_HAS_ELF_RANDOMIZE
+static inline unsigned long arch_mmap_rnd(void) { return 0; }
+#else
+extern unsigned long arch_mmap_rnd(void);
+#endif
+
+#endif