From: Russell Currey <rus...@russell.cc> To enable strict module RWX on powerpc, set:
CONFIG_STRICT_MODULE_RWX=y You should also have CONFIG_STRICT_KERNEL_RWX=y set to have any real security benefit. ARCH_HAS_STRICT_MODULE_RWX is set to require ARCH_HAS_STRICT_KERNEL_RWX. This is due to a quirk in arch/Kconfig and arch/powerpc/Kconfig that makes STRICT_MODULE_RWX *on by default* in configurations where STRICT_KERNEL_RWX is *unavailable*. Since this doesn't make much sense, and module RWX without kernel RWX doesn't make much sense, having the same dependencies as kernel RWX works around this problem. With STRICT_MODULE_RWX, now make module_alloc() allocate pages with KERNEL_PAGE protection rather than KERNEL_PAGE_EXEC. Book32s/32 processors with a hash mmu (i.e. 604 core) can not set memory protection on a page by page basis so do not enable. Signed-off-by: Russell Currey <rus...@russell.cc> [jpn: - predicate on !PPC_BOOK3S_604 - make module_alloc() use PAGE_KERNEL protection] Signed-off-by: Jordan Niethe <jniet...@gmail.com> --- v10: - Predicate on !PPC_BOOK3S_604 - Make module_alloc() use PAGE_KERNEL protection --- arch/powerpc/Kconfig | 1 + arch/powerpc/kernel/module.c | 11 ++++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 4498a27ac9db..97c0c3540bfd 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -137,6 +137,7 @@ config PPC select ARCH_HAS_SCALED_CPUTIME if VIRT_CPU_ACCOUNTING_NATIVE && PPC_BOOK3S_64 select ARCH_HAS_SET_MEMORY select ARCH_HAS_STRICT_KERNEL_RWX if ((PPC_BOOK3S_64 || PPC32) && !HIBERNATION) + select ARCH_HAS_STRICT_MODULE_RWX if ARCH_HAS_STRICT_KERNEL_RWX && !PPC_BOOK3S_604 select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST select ARCH_HAS_UACCESS_FLUSHCACHE select ARCH_HAS_COPY_MC if PPC64 diff --git a/arch/powerpc/kernel/module.c b/arch/powerpc/kernel/module.c index f1fb58389d58..d086f5534fac 100644 --- a/arch/powerpc/kernel/module.c +++ b/arch/powerpc/kernel/module.c @@ -90,7 +90,12 @@ int module_finalize(const Elf_Ehdr *hdr, void *module_alloc(unsigned long size) { - return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END, GFP_KERNEL, - PAGE_KERNEL_EXEC, VM_FLUSH_RESET_PERMS, NUMA_NO_NODE, - __builtin_return_address(0)); + pgprot_t prot = PAGE_KERNEL_EXEC; + + if (IS_ENABLED(CONFIG_STRICT_MODULE_RWX)) + prot = PAGE_KERNEL; + + return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END, + GFP_KERNEL, prot, VM_FLUSH_RESET_PERMS, + NUMA_NO_NODE, __builtin_return_address(0)); } -- 2.25.1