From: David Howells <dhowells@redhat.com>
Date: Wed, 8 Nov 2017 15:11:32 +0000
Subject: [04/29] Enforce module signatures if the kernel is locked down
Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=1616ef1deccf5fdb525643a6b3efae34946a148d

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>
[bwh: Adjust context to apply after commits 2c8fd268f418
 "module: Do not access sig_enforce directly" and 5fdc7db6448a
 "module: setup load info before module_sig_check()"]
---
 kernel/module.c | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

Index: linux/kernel/module.c
===================================================================
--- linux.orig/kernel/module.c
+++ linux/kernel/module.c
@@ -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"
 
@@ -2784,7 +2785,8 @@ static inline void kmemleak_load_module(
 #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;
@@ -2808,13 +2810,16 @@ static int module_sig_check(struct load_
 	}
 
 	/* Not having a signature is only an error if we're strict. */
-	if (err == -ENOKEY && !is_module_sig_enforced())
+	if (err == -ENOKEY && !is_module_sig_enforced() &&
+	    (!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;
 }
@@ -3662,7 +3667,7 @@ static int unknown_module_param_cb(char
 /* 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 = 0;
@@ -3681,7 +3686,7 @@ static int load_module(struct load_info
 		goto free_copy;
 	}
 
-	err = module_sig_check(info, flags);
+	err = module_sig_check(info, flags, can_do_ima_check);
 	if (err)
 		goto free_copy;
 
@@ -3876,7 +3881,7 @@ SYSCALL_DEFINE3(init_module, void __user
 	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)
@@ -3903,7 +3908,7 @@ SYSCALL_DEFINE3(finit_module, int, fd, c
 	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)
