aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKees Cook <keescook@chromium.org>2015-04-14 18:48:00 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-04-14 19:49:05 -0400
commit2b68f6caeac271620cd2f9362aeaed360e317df0 (patch)
tree8dae384ab3db6e078675a9bb63e4f58b0ab50dd4
parent8e89a356feb6f196824a72101861d931a97ac2d2 (diff)
mm: expose arch_mmap_rnd when available
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>
-rw-r--r--arch/Kconfig7
-rw-r--r--arch/arm/Kconfig1
-rw-r--r--arch/arm/mm/mmap.c4
-rw-r--r--arch/arm64/Kconfig1
-rw-r--r--arch/arm64/mm/mmap.c4
-rw-r--r--arch/mips/Kconfig1
-rw-r--r--arch/mips/mm/mmap.c4
-rw-r--r--arch/powerpc/Kconfig1
-rw-r--r--arch/powerpc/mm/mmap.c4
-rw-r--r--arch/s390/Kconfig1
-rw-r--r--arch/s390/mm/mmap.c8
-rw-r--r--arch/x86/Kconfig1
-rw-r--r--arch/x86/mm/mmap.c4
-rw-r--r--include/linux/elf-randomize.h10
14 files changed, 37 insertions, 14 deletions
diff --git a/arch/Kconfig b/arch/Kconfig
index c88c23f0a1da..474904a8e540 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -491,6 +491,13 @@ config PGTABLE_LEVELS
491 int 491 int
492 default 2 492 default 2
493 493
494config ARCH_HAS_ELF_RANDOMIZE
495 bool
496 help
497 An architecture supports choosing randomized locations for
498 stack, mmap, brk, and ET_DYN. Defined functions:
499 - arch_mmap_rnd()
500
494# 501#
495# ABI hall of shame 502# ABI hall of shame
496# 503#
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 696cf3c61e0f..f85200a63a8b 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -3,6 +3,7 @@ config ARM
3 default y 3 default y
4 select ARCH_BINFMT_ELF_RANDOMIZE_PIE 4 select ARCH_BINFMT_ELF_RANDOMIZE_PIE
5 select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE 5 select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
6 select ARCH_HAS_ELF_RANDOMIZE
6 select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST 7 select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
7 select ARCH_HAVE_CUSTOM_GPIO_H 8 select ARCH_HAVE_CUSTOM_GPIO_H
8 select ARCH_HAS_GCOV_PROFILE_ALL 9 select ARCH_HAS_GCOV_PROFILE_ALL
diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
index 15a8160096b3..407dc786583a 100644
--- a/arch/arm/mm/mmap.c
+++ b/arch/arm/mm/mmap.c
@@ -169,7 +169,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
169 return addr; 169 return addr;
170} 170}
171 171
172static unsigned long mmap_rnd(void) 172unsigned long arch_mmap_rnd(void)
173{ 173{
174 unsigned long rnd; 174 unsigned long rnd;
175 175
@@ -184,7 +184,7 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
184 unsigned long random_factor = 0UL; 184 unsigned long random_factor = 0UL;
185 185
186 if (current->flags & PF_RANDOMIZE) 186 if (current->flags & PF_RANDOMIZE)
187 random_factor = mmap_rnd(); 187 random_factor = arch_mmap_rnd();
188 188
189 if (mmap_is_legacy()) { 189 if (mmap_is_legacy()) {
190 mm->mmap_base = TASK_UNMAPPED_BASE + random_factor; 190 mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 3f2fba996bc2..7c1dbeb73e8d 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -2,6 +2,7 @@ config ARM64
2 def_bool y 2 def_bool y
3 select ARCH_BINFMT_ELF_RANDOMIZE_PIE 3 select ARCH_BINFMT_ELF_RANDOMIZE_PIE
4 select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE 4 select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
5 select ARCH_HAS_ELF_RANDOMIZE
5 select ARCH_HAS_GCOV_PROFILE_ALL 6 select ARCH_HAS_GCOV_PROFILE_ALL
6 select ARCH_HAS_SG_CHAIN 7 select ARCH_HAS_SG_CHAIN
7 select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST 8 select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
diff --git a/arch/arm64/mm/mmap.c b/arch/arm64/mm/mmap.c
index ba776c01b552..ed177475dd8c 100644
--- a/arch/arm64/mm/mmap.c
+++ b/arch/arm64/mm/mmap.c
@@ -47,7 +47,7 @@ static int mmap_is_legacy(void)
47 return sysctl_legacy_va_layout; 47 return sysctl_legacy_va_layout;
48} 48}
49 49
50static unsigned long mmap_rnd(void) 50unsigned long arch_mmap_rnd(void)
51{ 51{
52 unsigned long rnd; 52 unsigned long rnd;
53 53
@@ -77,7 +77,7 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
77 unsigned long random_factor = 0UL; 77 unsigned long random_factor = 0UL;
78 78
79 if (current->flags & PF_RANDOMIZE) 79 if (current->flags & PF_RANDOMIZE)
80 random_factor = mmap_rnd(); 80 random_factor = arch_mmap_rnd();
81 81
82 /* 82 /*
83 * Fall back to the standard layout if the personality bit is set, or 83 * Fall back to the standard layout if the personality bit is set, or
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index a9d112d2a135..688ce274f59d 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -24,6 +24,7 @@ config MIPS
24 select HAVE_DEBUG_KMEMLEAK 24 select HAVE_DEBUG_KMEMLEAK
25 select HAVE_SYSCALL_TRACEPOINTS 25 select HAVE_SYSCALL_TRACEPOINTS
26 select ARCH_BINFMT_ELF_RANDOMIZE_PIE 26 select ARCH_BINFMT_ELF_RANDOMIZE_PIE
27 select ARCH_HAS_ELF_RANDOMIZE
27 select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES && 64BIT 28 select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES && 64BIT
28 select RTC_LIB if !MACH_LOONGSON 29 select RTC_LIB if !MACH_LOONGSON
29 select GENERIC_ATOMIC64 if !64BIT 30 select GENERIC_ATOMIC64 if !64BIT
diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c
index 9a4f1f5c1f0e..5c81fdd032c3 100644
--- a/arch/mips/mm/mmap.c
+++ b/arch/mips/mm/mmap.c
@@ -142,7 +142,7 @@ unsigned long arch_get_unmapped_area_topdown(struct file *filp,
142 addr0, len, pgoff, flags, DOWN); 142 addr0, len, pgoff, flags, DOWN);
143} 143}
144 144
145static unsigned long mmap_rnd(void) 145unsigned long arch_mmap_rnd(void)
146{ 146{
147 unsigned long rnd; 147 unsigned long rnd;
148 148
@@ -161,7 +161,7 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
161 unsigned long random_factor = 0UL; 161 unsigned long random_factor = 0UL;
162 162
163 if (current->flags & PF_RANDOMIZE) 163 if (current->flags & PF_RANDOMIZE)
164 random_factor = mmap_rnd(); 164 random_factor = arch_mmap_rnd();
165 165
166 if (mmap_is_legacy()) { 166 if (mmap_is_legacy()) {
167 mm->mmap_base = TASK_UNMAPPED_BASE + random_factor; 167 mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 91ad76f30d18..fc5fffbb331b 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -89,6 +89,7 @@ config PPC
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 ARCH_BINFMT_ELF_RANDOMIZE_PIE
92 select ARCH_HAS_ELF_RANDOMIZE
92 select OF 93 select OF
93 select OF_EARLY_FLATTREE 94 select OF_EARLY_FLATTREE
94 select OF_RESERVED_MEM 95 select OF_RESERVED_MEM
diff --git a/arch/powerpc/mm/mmap.c b/arch/powerpc/mm/mmap.c
index 1ad2299d795d..0f0502e12f6c 100644
--- a/arch/powerpc/mm/mmap.c
+++ b/arch/powerpc/mm/mmap.c
@@ -53,7 +53,7 @@ static inline int mmap_is_legacy(void)
53 return sysctl_legacy_va_layout; 53 return sysctl_legacy_va_layout;
54} 54}
55 55
56static unsigned long mmap_rnd(void) 56unsigned long arch_mmap_rnd(void)
57{ 57{
58 unsigned long rnd; 58 unsigned long rnd;
59 59
@@ -87,7 +87,7 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
87 unsigned long random_factor = 0UL; 87 unsigned long random_factor = 0UL;
88 88
89 if (current->flags & PF_RANDOMIZE) 89 if (current->flags & PF_RANDOMIZE)
90 random_factor = mmap_rnd(); 90 random_factor = arch_mmap_rnd();
91 91
92 /* 92 /*
93 * Fall back to the standard layout if the personality 93 * Fall back to the standard layout if the personality
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index f6aebcb7a0f8..ac2b75d74cd2 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -65,6 +65,7 @@ config S390
65 def_bool y 65 def_bool y
66 select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE 66 select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
67 select ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS 67 select ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS
68 select ARCH_HAS_ELF_RANDOMIZE
68 select ARCH_HAS_GCOV_PROFILE_ALL 69 select ARCH_HAS_GCOV_PROFILE_ALL
69 select ARCH_HAS_SG_CHAIN 70 select ARCH_HAS_SG_CHAIN
70 select ARCH_HAVE_NMI_SAFE_CMPXCHG 71 select ARCH_HAVE_NMI_SAFE_CMPXCHG
diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c
index db57078075c5..a94504d99c47 100644
--- a/arch/s390/mm/mmap.c
+++ b/arch/s390/mm/mmap.c
@@ -60,7 +60,7 @@ static inline int mmap_is_legacy(void)
60 return sysctl_legacy_va_layout; 60 return sysctl_legacy_va_layout;
61} 61}
62 62
63static unsigned long mmap_rnd(void) 63unsigned long arch_mmap_rnd(void)
64{ 64{
65 if (is_32bit_task()) 65 if (is_32bit_task())
66 return (get_random_int() & 0x7ff) << PAGE_SHIFT; 66 return (get_random_int() & 0x7ff) << PAGE_SHIFT;
@@ -187,7 +187,7 @@ unsigned long randomize_et_dyn(void)
187 base &= ~((1UL << 32) - 1); 187 base &= ~((1UL << 32) - 1);
188 188
189 if (current->flags & PF_RANDOMIZE) 189 if (current->flags & PF_RANDOMIZE)
190 base += mmap_rnd(); 190 base += arch_mmap_rnd();
191 191
192 return base; 192 return base;
193} 193}
@@ -203,7 +203,7 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
203 unsigned long random_factor = 0UL; 203 unsigned long random_factor = 0UL;
204 204
205 if (current->flags & PF_RANDOMIZE) 205 if (current->flags & PF_RANDOMIZE)
206 random_factor = mmap_rnd(); 206 random_factor = arch_mmap_rnd();
207 207
208 /* 208 /*
209 * Fall back to the standard layout if the personality 209 * Fall back to the standard layout if the personality
@@ -283,7 +283,7 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
283 unsigned long random_factor = 0UL; 283 unsigned long random_factor = 0UL;
284 284
285 if (current->flags & PF_RANDOMIZE) 285 if (current->flags & PF_RANDOMIZE)
286 random_factor = mmap_rnd(); 286 random_factor = arch_mmap_rnd();
287 287
288 /* 288 /*
289 * Fall back to the standard layout if the personality 289 * Fall back to the standard layout if the personality
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 0f948cefaeb1..782ddbbc1c9a 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -88,6 +88,7 @@ config X86
88 select HAVE_ARCH_KASAN if X86_64 && SPARSEMEM_VMEMMAP 88 select HAVE_ARCH_KASAN if X86_64 && SPARSEMEM_VMEMMAP
89 select HAVE_USER_RETURN_NOTIFIER 89 select HAVE_USER_RETURN_NOTIFIER
90 select ARCH_BINFMT_ELF_RANDOMIZE_PIE 90 select ARCH_BINFMT_ELF_RANDOMIZE_PIE
91 select ARCH_HAS_ELF_RANDOMIZE
91 select HAVE_ARCH_JUMP_LABEL 92 select HAVE_ARCH_JUMP_LABEL
92 select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE 93 select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
93 select SPARSE_IRQ 94 select SPARSE_IRQ
diff --git a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c
index ebfa52030d5c..9d518d693b4b 100644
--- a/arch/x86/mm/mmap.c
+++ b/arch/x86/mm/mmap.c
@@ -65,7 +65,7 @@ static int mmap_is_legacy(void)
65 return sysctl_legacy_va_layout; 65 return sysctl_legacy_va_layout;
66} 66}
67 67
68static unsigned long mmap_rnd(void) 68unsigned long arch_mmap_rnd(void)
69{ 69{
70 unsigned long rnd; 70 unsigned long rnd;
71 71
@@ -114,7 +114,7 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
114 unsigned long random_factor = 0UL; 114 unsigned long random_factor = 0UL;
115 115
116 if (current->flags & PF_RANDOMIZE) 116 if (current->flags & PF_RANDOMIZE)
117 random_factor = mmap_rnd(); 117 random_factor = arch_mmap_rnd();
118 118
119 mm->mmap_legacy_base = mmap_legacy_base(random_factor); 119 mm->mmap_legacy_base = mmap_legacy_base(random_factor);
120 120
diff --git a/include/linux/elf-randomize.h b/include/linux/elf-randomize.h
new file mode 100644
index 000000000000..7a4eda02d2b1
--- /dev/null
+++ b/include/linux/elf-randomize.h
@@ -0,0 +1,10 @@
1#ifndef _ELF_RANDOMIZE_H
2#define _ELF_RANDOMIZE_H
3
4#ifndef CONFIG_ARCH_HAS_ELF_RANDOMIZE
5static inline unsigned long arch_mmap_rnd(void) { return 0; }
6#else
7extern unsigned long arch_mmap_rnd(void);
8#endif
9
10#endif