arm64: Add CONFIG_DEBUG_SET_MODULE_RONX support
PATCH 1/1 arm64: Add CONFIG_DEBUG_SET_MODULE_RONX support
In a similar fashion to other architecture, add the infrastructure and Kconfig to enable DEBUG_SET_MODULE_RONX support. When enabled, module ranges will be marked read-only/no-execute as appropriate.
--- arch/arm64/Kconfig.debug | 11 +++++++++ arch/arm64/include/asm/cacheflush.h | 4 +++ arch/arm64/include/asm/pgtable.h | 12 ++++++++++ arch/arm64/mm/mmu.c | 42 +++++++++++++++++++++++++++++++++++ 4 files changed, 69 insertions(+), 0 deletions(-)
arch/arm64/Kconfig.debug +11 -0
@@ -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
@@ -150,4 +150,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 +12 -0
@@ -188,6 +188,18 @@ static inline pte_t pte_mkspecial(pte_t pte)return pte; } +static inline pte_t pte_mkexec (pte_t pte) +{ +pte_val (pte) &= ~PTE_PXN ; +return pte; +} + +static inline pte_t pte_mknexec (pte_t pte) +{ +pte_val (pte) |=PTE_PXN ; +return pte; +} +static inline void set_pte (pte_t *ptep,pte_t pte) { *ptep = pte;
arch/arm64/mm/mmu.c +42 -0
48 lines not on this page · raw message
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
Catalin Marinas
maintainerPATCH 1/1 arm64: Add CONFIG_DEBUG_SET_MODULE_RONX support
Hi Laura,
Quoted 17 lines · Laura Abbott
arch/arm64/mm/mmu.c +17
-0+#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; \ +\
arch/arm64/mm/mmu.c static int __init early_cachepolicy(char *p) · line 151
Quoted 10 lines
arch/arm64/mm/mmu.c +10
-0+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 ;\ +}
The code seems correct but I don't really like this macro expansion. We changed the pte_mk* functions already to inline functions, so we should do the same with these set_memory_*() functions. Similar to s390, we could have a change_module_page_attr() or have two set/clear functions like x86 that just change the pte attribute (I think the latter allows us to no longer define pte_mkexec etc).
Thanks.
Signature · 1 line
Catalin