Merge tag 'modules-for-v5.4-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / kernel / module.c
index 32873bc..ff2d735 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/export.h>
 #include <linux/extable.h>
 #include <linux/moduleloader.h>
+#include <linux/module_signature.h>
 #include <linux/trace_events.h>
 #include <linux/init.h>
 #include <linux/kallsyms.h>
@@ -2838,8 +2839,9 @@ static inline void kmemleak_load_module(const struct module *mod,
 #ifdef CONFIG_MODULE_SIG
 static int module_sig_check(struct load_info *info, int flags)
 {
-       int err = -ENOKEY;
+       int err = -ENODATA;
        const unsigned long markerlen = sizeof(MODULE_SIG_STRING) - 1;
+       const char *reason;
        const void *mod = info->hdr;
 
        /*
@@ -2854,16 +2856,38 @@ static int module_sig_check(struct load_info *info, int flags)
                err = mod_verify_sig(mod, info);
        }
 
-       if (!err) {
+       switch (err) {
+       case 0:
                info->sig_ok = true;
                return 0;
-       }
 
-       /* Not having a signature is only an error if we're strict. */
-       if (err == -ENOKEY && !is_module_sig_enforced())
-               err = 0;
+               /* We don't permit modules to be loaded into trusted kernels
+                * without a valid signature on them, but if we're not
+                * enforcing, certain errors are non-fatal.
+                */
+       case -ENODATA:
+               reason = "Loading of unsigned module";
+               goto decide;
+       case -ENOPKG:
+               reason = "Loading of module with unsupported crypto";
+               goto decide;
+       case -ENOKEY:
+               reason = "Loading of module with unavailable key";
+       decide:
+               if (is_module_sig_enforced()) {
+                       pr_notice("%s is rejected\n", reason);
+                       return -EKEYREJECTED;
+               }
 
-       return err;
+               return security_locked_down(LOCKDOWN_MODULE_SIGNATURE);
+
+               /* All other errors are fatal, including nomem, unparseable
+                * signatures and signature check failures - even if signatures
+                * aren't required.
+                */
+       default:
+               return err;
+       }
 }
 #else /* !CONFIG_MODULE_SIG */
 static int module_sig_check(struct load_info *info, int flags)