Loading arch/arm64/Kconfig.debug +11 −0 Original line number Diff line number Diff line Loading @@ -23,4 +23,15 @@ config PID_IN_CONTEXTIDR instructions during context switch. Say Y here only if you are planning to use hardware trace tools with this kernel. config DEBUG_SET_MODULE_RONX bool "Set loadable kernel module data as NX and text as RO" depends on MODULES ---help--- This option helps catch unintended modifications to loadable kernel module's text and read-only data. It also prevents execution of module data. Such protection may interfere with run-time code patching and dynamic kernel tracing - and they might also protect against certain classes of kernel exploits. If in doubt, say "N". endmenu arch/arm64/include/asm/cacheflush.h +4 −0 Original line number Diff line number Diff line Loading @@ -164,4 +164,8 @@ static inline void flush_cache_vunmap(unsigned long start, unsigned long end) { } int set_memory_ro(unsigned long addr, int numpages); int set_memory_rw(unsigned long addr, int numpages); int set_memory_x(unsigned long addr, int numpages); int set_memory_nx(unsigned long addr, int numpages); #endif arch/arm64/include/asm/pgtable.h +2 −0 Original line number Diff line number Diff line Loading @@ -156,6 +156,8 @@ PTE_BIT_FUNC(mkdirty, |= PTE_DIRTY); PTE_BIT_FUNC(mkold, &= ~PTE_AF); PTE_BIT_FUNC(mkyoung, |= PTE_AF); PTE_BIT_FUNC(mkspecial, |= PTE_SPECIAL); PTE_BIT_FUNC(mkexec, &= ~PTE_PXN); PTE_BIT_FUNC(mknexec, |= PTE_PXN); static inline void set_pte(pte_t *ptep, pte_t pte) { Loading arch/arm64/mm/mmu.c +42 −0 Original line number Diff line number Diff line Loading @@ -122,6 +122,48 @@ static int __init early_cachepolicy(char *p) } early_param("cachepolicy", early_cachepolicy); #define PTE_SET_FN(_name, pteop) \ static int pte_set_##_name(pte_t *ptep, pgtable_t token, unsigned long addr, \ void *data) \ { \ pte_t pte = pteop(*ptep); \ \ set_pte(ptep, pte); \ return 0; \ } \ #define SET_MEMORY_FN(_name, callback) \ int set_memory_##_name(unsigned long addr, int numpages) \ { \ unsigned long start = addr; \ unsigned long size = PAGE_SIZE*numpages; \ unsigned long end = start + size; \ \ if (start < MODULES_VADDR || start >= MODULES_END) \ return -EINVAL;\ \ if (end < MODULES_VADDR || end >= MODULES_END) \ return -EINVAL; \ \ apply_to_page_range(&init_mm, start, size, callback, NULL); \ flush_tlb_kernel_range(start, end); \ return 0;\ } PTE_SET_FN(ro, pte_wrprotect) PTE_SET_FN(rw, pte_mkwrite) PTE_SET_FN(x, pte_mkexec) PTE_SET_FN(nx, pte_mknexec) SET_MEMORY_FN(ro, pte_set_ro) EXPORT_SYMBOL(set_memory_ro); SET_MEMORY_FN(rw, pte_set_rw) EXPORT_SYMBOL(set_memory_rw); SET_MEMORY_FN(x, pte_set_x) EXPORT_SYMBOL(set_memory_x); SET_MEMORY_FN(nx, pte_set_nx) EXPORT_SYMBOL(set_memory_nx); /* * Adjust the PMD section entries according to the CPU in use. */ Loading Loading
arch/arm64/Kconfig.debug +11 −0 Original line number Diff line number Diff line Loading @@ -23,4 +23,15 @@ config PID_IN_CONTEXTIDR instructions during context switch. Say Y here only if you are planning to use hardware trace tools with this kernel. config DEBUG_SET_MODULE_RONX bool "Set loadable kernel module data as NX and text as RO" depends on MODULES ---help--- This option helps catch unintended modifications to loadable kernel module's text and read-only data. It also prevents execution of module data. Such protection may interfere with run-time code patching and dynamic kernel tracing - and they might also protect against certain classes of kernel exploits. If in doubt, say "N". endmenu
arch/arm64/include/asm/cacheflush.h +4 −0 Original line number Diff line number Diff line Loading @@ -164,4 +164,8 @@ static inline void flush_cache_vunmap(unsigned long start, unsigned long end) { } int set_memory_ro(unsigned long addr, int numpages); int set_memory_rw(unsigned long addr, int numpages); int set_memory_x(unsigned long addr, int numpages); int set_memory_nx(unsigned long addr, int numpages); #endif
arch/arm64/include/asm/pgtable.h +2 −0 Original line number Diff line number Diff line Loading @@ -156,6 +156,8 @@ PTE_BIT_FUNC(mkdirty, |= PTE_DIRTY); PTE_BIT_FUNC(mkold, &= ~PTE_AF); PTE_BIT_FUNC(mkyoung, |= PTE_AF); PTE_BIT_FUNC(mkspecial, |= PTE_SPECIAL); PTE_BIT_FUNC(mkexec, &= ~PTE_PXN); PTE_BIT_FUNC(mknexec, |= PTE_PXN); static inline void set_pte(pte_t *ptep, pte_t pte) { Loading
arch/arm64/mm/mmu.c +42 −0 Original line number Diff line number Diff line Loading @@ -122,6 +122,48 @@ static int __init early_cachepolicy(char *p) } early_param("cachepolicy", early_cachepolicy); #define PTE_SET_FN(_name, pteop) \ static int pte_set_##_name(pte_t *ptep, pgtable_t token, unsigned long addr, \ void *data) \ { \ pte_t pte = pteop(*ptep); \ \ set_pte(ptep, pte); \ return 0; \ } \ #define SET_MEMORY_FN(_name, callback) \ int set_memory_##_name(unsigned long addr, int numpages) \ { \ unsigned long start = addr; \ unsigned long size = PAGE_SIZE*numpages; \ unsigned long end = start + size; \ \ if (start < MODULES_VADDR || start >= MODULES_END) \ return -EINVAL;\ \ if (end < MODULES_VADDR || end >= MODULES_END) \ return -EINVAL; \ \ apply_to_page_range(&init_mm, start, size, callback, NULL); \ flush_tlb_kernel_range(start, end); \ return 0;\ } PTE_SET_FN(ro, pte_wrprotect) PTE_SET_FN(rw, pte_mkwrite) PTE_SET_FN(x, pte_mkexec) PTE_SET_FN(nx, pte_mknexec) SET_MEMORY_FN(ro, pte_set_ro) EXPORT_SYMBOL(set_memory_ro); SET_MEMORY_FN(rw, pte_set_rw) EXPORT_SYMBOL(set_memory_rw); SET_MEMORY_FN(x, pte_set_x) EXPORT_SYMBOL(set_memory_x); SET_MEMORY_FN(nx, pte_set_nx) EXPORT_SYMBOL(set_memory_nx); /* * Adjust the PMD section entries according to the CPU in use. */ Loading