Re: [PATCH v2] module: Harden STRICT_MODULE_RWX

From: Jessica Yu
Date: Wed Apr 08 2020 - 11:32:58 EST


+++ Peter Zijlstra [03/04/20 19:13 +0200]:

We're very close to enforcing W^X memory, refuse to load modules that
violate this principle per construction.

Signed-off-by: Peter Zijlstra (Intel) <peterz@xxxxxxxxxxxxx>
---
kernel/module.c | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)

--- a/kernel/module.c
+++ b/kernel/module.c
@@ -2044,9 +2044,29 @@ static void module_enable_x(const struct
frob_text(&mod->core_layout, set_memory_x);
frob_text(&mod->init_layout, set_memory_x);
}
+
+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;
+}

Just to clarify, did we want to enforce this only when
CONFIG_STRICT_MODULE_RWX=y? Because here it's still in the
CONFIG_ARCH_HAS_STRICT_MODULE_RWX block.

Unfortunately, when we add module_enforce_rwx_sections() in the
CONFIG_STRICT_MODULE_RWX block, we'll need two empty stubs, one for
!CONFIG_ARCH_HAS_STRICT_MODULE_RWX and one for !CONFIG_STRICT_MODULE_RWX.

This is because the CONFIG_STRICT_MODULE_RWX block is currently nested
within ARCH_HAS_STRICT_MODULE_RWX :/

That unholy nested ifdef mess needs to be fixed. I will post a patch
shortly that gets rid of this nesting and you could rebase on top of
it if you want to move module_enforce_rwx_sections() under
CONFIG_STRICT_MODULE_RWX. Then you'll only need to provide one empty
stub for !CONFIG_STRICT_MODULE_RWX.

Thanks,

Jessica