From 5c3a7db0c7ec4bbd5bd3f48af9be859a8fa3e532 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Fri, 3 Apr 2020 19:13:03 +0200 Subject: [PATCH] module: Harden STRICT_MODULE_RWX We're very close to enforcing W^X memory, refuse to load modules that violate this principle per construction. [jeyu: move module_enforce_rwx_sections under STRICT_MODULE_RWX as per discussion] Link: http://lore.kernel.org/r/20200403171303.GK20760@hirez.programming.kicks-ass.net Acked-by: Kees Cook Signed-off-by: Peter Zijlstra (Intel) Signed-off-by: Jessica Yu --- kernel/module.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/kernel/module.c b/kernel/module.c index 01d01a489778..70fc20583e66 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -2052,9 +2052,28 @@ static void module_enable_nx(const struct module *mod) frob_writable_data(&mod->init_layout, set_memory_nx); } +static int module_enforce_rwx_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, + char *secstrings, struct module *mod) +{ + const unsigned long shf_wx = SHF_WRITE|SHF_EXECINSTR; + int i; + + for (i = 0; i < hdr->e_shnum; i++) { + if ((sechdrs[i].sh_flags & shf_wx) == shf_wx) + return -ENOEXEC; + } + + return 0; +} + #else /* !CONFIG_STRICT_MODULE_RWX */ /* module_{enable,disable}_ro() stubs are in module.h */ static void module_enable_nx(const struct module *mod) { } +static int module_enforce_rwx_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, + char *secstrings, struct module *mod) +{ + return 0; +} #endif /* CONFIG_STRICT_MODULE_RWX */ #ifdef CONFIG_LIVEPATCH @@ -3385,6 +3404,11 @@ static struct module *layout_and_allocate(struct load_info *info, int flags) if (err < 0) return ERR_PTR(err); + err = module_enforce_rwx_sections(info->hdr, info->sechdrs, + info->secstrings, info->mod); + if (err < 0) + return ERR_PTR(err); + /* We will do a special allocation for per-cpu sections later. */ info->sechdrs[info->index.pcpu].sh_flags &= ~(unsigned long)SHF_ALLOC;