1
2
3
4
5
6
7
8
9
10
11
12
13
14#include <linux/personality.h>
15#include <linux/mm.h>
16#include <linux/random.h>
17#include <linux/limits.h>
18#include <linux/sched/signal.h>
19#include <linux/sched/mm.h>
20#include <linux/compat.h>
21#include <linux/elf-randomize.h>
22#include <asm/elf.h>
23#include <asm/io.h>
24
25#include "physaddr.h"
26
27struct va_alignment __read_mostly va_align = {
28 .flags = -1,
29};
30
31unsigned long task_size_32bit(void)
32{
33 return IA32_PAGE_OFFSET;
34}
35
36unsigned long task_size_64bit(int full_addr_space)
37{
38 return full_addr_space ? TASK_SIZE_MAX : DEFAULT_MAP_WINDOW;
39}
40
41static unsigned long stack_maxrandom_size(unsigned long task_size)
42{
43 unsigned long max = 0;
44 if (current->flags & PF_RANDOMIZE) {
45 max = (-1UL) & __STACK_RND_MASK(task_size == task_size_32bit());
46 max <<= PAGE_SHIFT;
47 }
48
49 return max;
50}
51
52#ifdef CONFIG_COMPAT
53# define mmap32_rnd_bits mmap_rnd_compat_bits
54# define mmap64_rnd_bits mmap_rnd_bits
55#else
56# define mmap32_rnd_bits mmap_rnd_bits
57# define mmap64_rnd_bits mmap_rnd_bits
58#endif
59
60#define SIZE_128M (128 * 1024 * 1024UL)
61
62static int mmap_is_legacy(void)
63{
64 if (current->personality & ADDR_COMPAT_LAYOUT)
65 return 1;
66
67 return sysctl_legacy_va_layout;
68}
69
70static unsigned long arch_rnd(unsigned int rndbits)
71{
72 if (!(current->flags & PF_RANDOMIZE))
73 return 0;
74 return (get_random_long() & ((1UL << rndbits) - 1)) << PAGE_SHIFT;
75}
76
77unsigned long arch_mmap_rnd(void)
78{
79 return arch_rnd(mmap_is_ia32() ? mmap32_rnd_bits : mmap64_rnd_bits);
80}
81
82static unsigned long mmap_base(unsigned long rnd, unsigned long task_size,
83 struct rlimit *rlim_stack)
84{
85 unsigned long gap = rlim_stack->rlim_cur;
86 unsigned long pad = stack_maxrandom_size(task_size) + stack_guard_gap;
87 unsigned long gap_min, gap_max;
88
89
90 if (gap + pad > gap)
91 gap += pad;
92
93
94
95
96
97 gap_min = SIZE_128M;
98 gap_max = (task_size / 6) * 5;
99
100 if (gap < gap_min)
101 gap = gap_min;
102 else if (gap > gap_max)
103 gap = gap_max;
104
105 return PAGE_ALIGN(task_size - gap - rnd);
106}
107
108static unsigned long mmap_legacy_base(unsigned long rnd,
109 unsigned long task_size)
110{
111 return __TASK_UNMAPPED_BASE(task_size) + rnd;
112}
113
114
115
116
117
118static void arch_pick_mmap_base(unsigned long *base, unsigned long *legacy_base,
119 unsigned long random_factor, unsigned long task_size,
120 struct rlimit *rlim_stack)
121{
122 *legacy_base = mmap_legacy_base(random_factor, task_size);
123 if (mmap_is_legacy())
124 *base = *legacy_base;
125 else
126 *base = mmap_base(random_factor, task_size, rlim_stack);
127}
128
129void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack)
130{
131 if (mmap_is_legacy())
132 mm->get_unmapped_area = arch_get_unmapped_area;
133 else
134 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
135
136 arch_pick_mmap_base(&mm->mmap_base, &mm->mmap_legacy_base,
137 arch_rnd(mmap64_rnd_bits), task_size_64bit(0),
138 rlim_stack);
139
140#ifdef CONFIG_HAVE_ARCH_COMPAT_MMAP_BASES
141
142
143
144
145
146
147 arch_pick_mmap_base(&mm->mmap_compat_base, &mm->mmap_compat_legacy_base,
148 arch_rnd(mmap32_rnd_bits), task_size_32bit(),
149 rlim_stack);
150#endif
151}
152
153unsigned long get_mmap_base(int is_legacy)
154{
155 struct mm_struct *mm = current->mm;
156
157#ifdef CONFIG_HAVE_ARCH_COMPAT_MMAP_BASES
158 if (in_32bit_syscall()) {
159 return is_legacy ? mm->mmap_compat_legacy_base
160 : mm->mmap_compat_base;
161 }
162#endif
163 return is_legacy ? mm->mmap_legacy_base : mm->mmap_base;
164}
165
166const char *arch_vma_name(struct vm_area_struct *vma)
167{
168 return NULL;
169}
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209bool mmap_address_hint_valid(unsigned long addr, unsigned long len)
210{
211 if (TASK_SIZE - len < addr)
212 return false;
213
214 return (addr > DEFAULT_MAP_WINDOW) == (addr + len > DEFAULT_MAP_WINDOW);
215}
216
217
218int valid_phys_addr_range(phys_addr_t addr, size_t count)
219{
220 return addr + count - 1 <= __pa(high_memory - 1);
221}
222
223
224int valid_mmap_phys_addr_range(unsigned long pfn, size_t count)
225{
226 phys_addr_t addr = (phys_addr_t)pfn << PAGE_SHIFT;
227
228 return phys_addr_valid(addr + count - 1);
229}
230
231
232
233
234
235
236
237
238bool pfn_modify_allowed(unsigned long pfn, pgprot_t prot)
239{
240 if (!boot_cpu_has_bug(X86_BUG_L1TF))
241 return true;
242 if (!__pte_needs_invert(pgprot_val(prot)))
243 return true;
244
245 if (pfn_valid(pfn))
246 return true;
247 if (pfn >= l1tf_pfn_limit() && !capable(CAP_SYS_ADMIN))
248 return false;
249 return true;
250}
251