Enforce module signatures if the kernel is locked down
authorDavid Howells <dhowells@redhat.com>
Wed, 8 Nov 2017 15:11:32 +0000 (15:11 +0000)
committerBastian Blank <waldi@debian.org>
Fri, 22 Jun 2018 09:50:22 +0000 (10:50 +0100)
If the kernel is locked down, require that all modules have valid
signatures that we can verify or that IMA can validate the file.

Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: "Lee, Chun-Yi" <jlee@suse.com>
Reviewed-by: James Morris <james.l.morris@oracle.com>
Gbp-Pq: Topic features/all/lockdown
Gbp-Pq: Name 0004-Enforce-module-signatures-if-the-kernel-is-locked-do.patch

kernel/module.c

index bbb45c038321f3e6cd111ea9af30208adb0d211c..5cfdd1c8b184a06f91754f778e6414de946eb5fc 100644 (file)
@@ -64,6 +64,7 @@
 #include <linux/bsearch.h>
 #include <linux/dynamic_debug.h>
 #include <linux/audit.h>
+#include <linux/ima.h>
 #include <uapi/linux/module.h>
 #include "module-internal.h"
 
@@ -2766,7 +2767,8 @@ static inline void kmemleak_load_module(const struct module *mod,
 #endif
 
 #ifdef CONFIG_MODULE_SIG
-static int module_sig_check(struct load_info *info, int flags)
+static int module_sig_check(struct load_info *info, int flags,
+                           bool can_do_ima_check)
 {
        int err = -ENOKEY;
        const unsigned long markerlen = sizeof(MODULE_SIG_STRING) - 1;
@@ -2790,13 +2792,16 @@ static int module_sig_check(struct load_info *info, int flags)
        }
 
        /* Not having a signature is only an error if we're strict. */
-       if (err == -ENOKEY && !sig_enforce)
+       if (err == -ENOKEY && !sig_enforce &&
+           (!can_do_ima_check || !is_ima_appraise_enabled()) &&
+           !kernel_is_locked_down("Loading of unsigned modules"))
                err = 0;
 
        return err;
 }
 #else /* !CONFIG_MODULE_SIG */
-static int module_sig_check(struct load_info *info, int flags)
+static int module_sig_check(struct load_info *info, int flags,
+                           bool can_do_ima_check)
 {
        return 0;
 }
@@ -3656,13 +3661,13 @@ static int unknown_module_param_cb(char *param, char *val, const char *modname,
 /* Allocate and load the module: note that size of section 0 is always
    zero, and we rely on this for optional sections. */
 static int load_module(struct load_info *info, const char __user *uargs,
-                      int flags)
+                      int flags, bool can_do_ima_check)
 {
        struct module *mod;
        long err;
        char *after_dashes;
 
-       err = module_sig_check(info, flags);
+       err = module_sig_check(info, flags, can_do_ima_check);
        if (err)
                goto free_copy;
 
@@ -3851,7 +3856,7 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,
        if (err)
                return err;
 
-       return load_module(&info, uargs, 0);
+       return load_module(&info, uargs, 0, false);
 }
 
 SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags)
@@ -3878,7 +3883,7 @@ SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags)
        info.hdr = hdr;
        info.len = size;
 
-       return load_module(&info, uargs, flags);
+       return load_module(&info, uargs, flags, true);
 }
 
 static inline int within(unsigned long addr, void *start, unsigned long size)