Commit df992848f5aa803fcacd2c5e7d67034bb89e3fa3
Committed by
Andi Kleen
1 parent
d3cf7f0615
Exists in
master
and in
4 other branches
[PATCH] Fix pte_exec/mkexec and use it in change_page_attr()
Fix the pte_exec/mkexec page table accessor functions to really use the NX bit. Previously they only checked the USER bit, but weren't actually used for anything. Then use them in change_page_attr() to manipulate the NX bit properly. Signed-off-by: Andi Kleen <ak@suse.de>
Showing 2 changed files with 7 additions and 5 deletions Side-by-side Diff
arch/x86_64/mm/pageattr.c
| ... | ... | @@ -190,10 +190,12 @@ |
| 190 | 190 | * lowmem */ |
| 191 | 191 | if (__pa(address) < KERNEL_TEXT_SIZE) { |
| 192 | 192 | unsigned long addr2; |
| 193 | - pgprot_t prot2 = prot; | |
| 193 | + pgprot_t prot2; | |
| 194 | 194 | addr2 = __START_KERNEL_map + __pa(address); |
| 195 | - pgprot_val(prot2) &= ~_PAGE_NX; | |
| 196 | - err = __change_page_attr(addr2, pfn, prot2, PAGE_KERNEL_EXEC); | |
| 195 | + /* Make sure the kernel mappings stay executable */ | |
| 196 | + prot2 = pte_pgprot(pte_mkexec(pfn_pte(0, prot))); | |
| 197 | + err = __change_page_attr(addr2, pfn, prot2, | |
| 198 | + PAGE_KERNEL_EXEC); | |
| 197 | 199 | } |
| 198 | 200 | } |
| 199 | 201 | up_write(&init_mm.mmap_sem); |
include/asm-x86_64/pgtable.h
| ... | ... | @@ -265,7 +265,7 @@ |
| 265 | 265 | #define __LARGE_PTE (_PAGE_PSE|_PAGE_PRESENT) |
| 266 | 266 | static inline int pte_user(pte_t pte) { return pte_val(pte) & _PAGE_USER; } |
| 267 | 267 | static inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_USER; } |
| 268 | -static inline int pte_exec(pte_t pte) { return pte_val(pte) & _PAGE_USER; } | |
| 268 | +static inline int pte_exec(pte_t pte) { return !(pte_val(pte) & _PAGE_NX); } | |
| 269 | 269 | static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } |
| 270 | 270 | static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } |
| 271 | 271 | static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; } |
| ... | ... | @@ -278,7 +278,7 @@ |
| 278 | 278 | static inline pte_t pte_mkold(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_ACCESSED)); return pte; } |
| 279 | 279 | static inline pte_t pte_wrprotect(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_RW)); return pte; } |
| 280 | 280 | static inline pte_t pte_mkread(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER)); return pte; } |
| 281 | -static inline pte_t pte_mkexec(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER)); return pte; } | |
| 281 | +static inline pte_t pte_mkexec(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_NX)); return pte; } | |
| 282 | 282 | static inline pte_t pte_mkdirty(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY)); return pte; } |
| 283 | 283 | static inline pte_t pte_mkyoung(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); return pte; } |
| 284 | 284 | static inline pte_t pte_mkwrite(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_RW)); return pte; } |