|
2 | 2 | #ifndef _LINUX_MMAN_H
|
3 | 3 | #define _LINUX_MMAN_H
|
4 | 4 |
|
| 5 | +#include <linux/fs.h> |
5 | 6 | #include <linux/mm.h>
|
6 | 7 | #include <linux/percpu_counter.h>
|
7 | 8 |
|
@@ -94,7 +95,7 @@ static inline void vm_unacct_memory(long pages)
|
94 | 95 | #endif
|
95 | 96 |
|
96 | 97 | #ifndef arch_calc_vm_flag_bits
|
97 |
| -#define arch_calc_vm_flag_bits(flags) 0 |
| 98 | +#define arch_calc_vm_flag_bits(file, flags) 0 |
98 | 99 | #endif
|
99 | 100 |
|
100 | 101 | #ifndef arch_validate_prot
|
@@ -151,13 +152,13 @@ calc_vm_prot_bits(unsigned long prot, unsigned long pkey)
|
151 | 152 | * Combine the mmap "flags" argument into "vm_flags" used internally.
|
152 | 153 | */
|
153 | 154 | static inline unsigned long
|
154 |
| -calc_vm_flag_bits(unsigned long flags) |
| 155 | +calc_vm_flag_bits(struct file *file, unsigned long flags) |
155 | 156 | {
|
156 | 157 | return _calc_vm_trans(flags, MAP_GROWSDOWN, VM_GROWSDOWN ) |
|
157 | 158 | _calc_vm_trans(flags, MAP_LOCKED, VM_LOCKED ) |
|
158 | 159 | _calc_vm_trans(flags, MAP_SYNC, VM_SYNC ) |
|
159 | 160 | _calc_vm_trans(flags, MAP_STACK, VM_NOHUGEPAGE) |
|
160 |
| - arch_calc_vm_flag_bits(flags); |
| 161 | + arch_calc_vm_flag_bits(file, flags); |
161 | 162 | }
|
162 | 163 |
|
163 | 164 | unsigned long vm_commit_limit(void);
|
@@ -188,16 +189,31 @@ static inline bool arch_memory_deny_write_exec_supported(void)
|
188 | 189 | *
|
189 | 190 | * d) mmap(PROT_READ | PROT_EXEC)
|
190 | 191 | * mmap(PROT_READ | PROT_EXEC | PROT_BTI)
|
| 192 | + * |
| 193 | + * This is only applicable if the user has set the Memory-Deny-Write-Execute |
| 194 | + * (MDWE) protection mask for the current process. |
| 195 | + * |
| 196 | + * @old specifies the VMA flags the VMA originally possessed, and @new the ones |
| 197 | + * we propose to set. |
| 198 | + * |
| 199 | + * Return: false if proposed change is OK, true if not ok and should be denied. |
191 | 200 | */
|
192 |
| -static inline bool map_deny_write_exec(struct vm_area_struct *vma, unsigned long vm_flags) |
| 201 | +static inline bool map_deny_write_exec(unsigned long old, unsigned long new) |
193 | 202 | {
|
| 203 | + /* If MDWE is disabled, we have nothing to deny. */ |
194 | 204 | if (!test_bit(MMF_HAS_MDWE, ¤t->mm->flags))
|
195 | 205 | return false;
|
196 | 206 |
|
197 |
| - if ((vm_flags & VM_EXEC) && (vm_flags & VM_WRITE)) |
| 207 | + /* If the new VMA is not executable, we have nothing to deny. */ |
| 208 | + if (!(new & VM_EXEC)) |
| 209 | + return false; |
| 210 | + |
| 211 | + /* Under MDWE we do not accept newly writably executable VMAs... */ |
| 212 | + if (new & VM_WRITE) |
198 | 213 | return true;
|
199 | 214 |
|
200 |
| - if (!(vma->vm_flags & VM_EXEC) && (vm_flags & VM_EXEC)) |
| 215 | + /* ...nor previously non-executable VMAs becoming executable. */ |
| 216 | + if (!(old & VM_EXEC)) |
201 | 217 | return true;
|
202 | 218 |
|
203 | 219 | return false;
|
|
0 commit comments