This source file includes following definitions.
- task_size_32bit
- task_size_64bit
- stack_maxrandom_size
- mmap_is_legacy
- arch_rnd
- arch_mmap_rnd
- mmap_base
- mmap_legacy_base
- arch_pick_mmap_base
- arch_pick_mmap_layout
- get_mmap_base
- arch_vma_name
- mmap_address_hint_valid
- valid_phys_addr_range
- valid_mmap_phys_addr_range
- pfn_modify_allowed
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 <asm/elf.h>
22
23 #include "physaddr.h"
24
25 struct va_alignment __read_mostly va_align = {
26 .flags = -1,
27 };
28
29 unsigned long task_size_32bit(void)
30 {
31 return IA32_PAGE_OFFSET;
32 }
33
34 unsigned long task_size_64bit(int full_addr_space)
35 {
36 return full_addr_space ? TASK_SIZE_MAX : DEFAULT_MAP_WINDOW;
37 }
38
39 static unsigned long stack_maxrandom_size(unsigned long task_size)
40 {
41 unsigned long max = 0;
42 if (current->flags & PF_RANDOMIZE) {
43 max = (-1UL) & __STACK_RND_MASK(task_size == task_size_32bit());
44 max <<= PAGE_SHIFT;
45 }
46
47 return max;
48 }
49
50 #ifdef CONFIG_COMPAT
51 # define mmap32_rnd_bits mmap_rnd_compat_bits
52 # define mmap64_rnd_bits mmap_rnd_bits
53 #else
54 # define mmap32_rnd_bits mmap_rnd_bits
55 # define mmap64_rnd_bits mmap_rnd_bits
56 #endif
57
58 #define SIZE_128M (128 * 1024 * 1024UL)
59
60 static int mmap_is_legacy(void)
61 {
62 if (current->personality & ADDR_COMPAT_LAYOUT)
63 return 1;
64
65 return sysctl_legacy_va_layout;
66 }
67
68 static unsigned long arch_rnd(unsigned int rndbits)
69 {
70 if (!(current->flags & PF_RANDOMIZE))
71 return 0;
72 return (get_random_long() & ((1UL << rndbits) - 1)) << PAGE_SHIFT;
73 }
74
75 unsigned long arch_mmap_rnd(void)
76 {
77 return arch_rnd(mmap_is_ia32() ? mmap32_rnd_bits : mmap64_rnd_bits);
78 }
79
80 static unsigned long mmap_base(unsigned long rnd, unsigned long task_size,
81 struct rlimit *rlim_stack)
82 {
83 unsigned long gap = rlim_stack->rlim_cur;
84 unsigned long pad = stack_maxrandom_size(task_size) + stack_guard_gap;
85 unsigned long gap_min, gap_max;
86
87
88 if (gap + pad > gap)
89 gap += pad;
90
91
92
93
94
95 gap_min = SIZE_128M;
96 gap_max = (task_size / 6) * 5;
97
98 if (gap < gap_min)
99 gap = gap_min;
100 else if (gap > gap_max)
101 gap = gap_max;
102
103 return PAGE_ALIGN(task_size - gap - rnd);
104 }
105
106 static unsigned long mmap_legacy_base(unsigned long rnd,
107 unsigned long task_size)
108 {
109 return __TASK_UNMAPPED_BASE(task_size) + rnd;
110 }
111
112
113
114
115
116 static void arch_pick_mmap_base(unsigned long *base, unsigned long *legacy_base,
117 unsigned long random_factor, unsigned long task_size,
118 struct rlimit *rlim_stack)
119 {
120 *legacy_base = mmap_legacy_base(random_factor, task_size);
121 if (mmap_is_legacy())
122 *base = *legacy_base;
123 else
124 *base = mmap_base(random_factor, task_size, rlim_stack);
125 }
126
127 void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack)
128 {
129 if (mmap_is_legacy())
130 mm->get_unmapped_area = arch_get_unmapped_area;
131 else
132 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
133
134 arch_pick_mmap_base(&mm->mmap_base, &mm->mmap_legacy_base,
135 arch_rnd(mmap64_rnd_bits), task_size_64bit(0),
136 rlim_stack);
137
138 #ifdef CONFIG_HAVE_ARCH_COMPAT_MMAP_BASES
139
140
141
142
143
144
145 arch_pick_mmap_base(&mm->mmap_compat_base, &mm->mmap_compat_legacy_base,
146 arch_rnd(mmap32_rnd_bits), task_size_32bit(),
147 rlim_stack);
148 #endif
149 }
150
151 unsigned long get_mmap_base(int is_legacy)
152 {
153 struct mm_struct *mm = current->mm;
154
155 #ifdef CONFIG_HAVE_ARCH_COMPAT_MMAP_BASES
156 if (in_32bit_syscall()) {
157 return is_legacy ? mm->mmap_compat_legacy_base
158 : mm->mmap_compat_base;
159 }
160 #endif
161 return is_legacy ? mm->mmap_legacy_base : mm->mmap_base;
162 }
163
164 const char *arch_vma_name(struct vm_area_struct *vma)
165 {
166 if (vma->vm_flags & VM_MPX)
167 return "[mpx]";
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
209 bool 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
218 int valid_phys_addr_range(phys_addr_t addr, size_t count)
219 {
220 return addr + count - 1 <= __pa(high_memory - 1);
221 }
222
223
224 int 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
238 bool 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 }