module: Move extra signature support out of core code
authorAaron Tomlin <atomlin@redhat.com>
Tue, 22 Mar 2022 14:03:37 +0000 (14:03 +0000)
committerLuis Chamberlain <mcgrof@kernel.org>
Tue, 5 Apr 2022 15:43:04 +0000 (08:43 -0700)
No functional change.

This patch migrates additional module signature check
code from core module code into kernel/module/signing.c.

Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Aaron Tomlin <atomlin@redhat.com>
Signed-off-by: Luis Chamberlain <mcgrof@kernel.org>
include/linux/module.h
kernel/module/internal.h
kernel/module/main.c
kernel/module/signing.c

index 7ec9715..5e2059f 100644 (file)
@@ -672,7 +672,6 @@ static inline bool is_livepatch_module(struct module *mod)
 #endif
 }
 
-bool is_module_sig_enforced(void);
 void set_module_sig_enforced(void);
 
 #else /* !CONFIG_MODULES... */
@@ -799,10 +798,6 @@ static inline bool module_requested_async_probing(struct module *module)
        return false;
 }
 
-static inline bool is_module_sig_enforced(void)
-{
-       return false;
-}
 
 static inline void set_module_sig_enforced(void)
 {
@@ -854,11 +849,18 @@ static inline bool retpoline_module_ok(bool has_retpoline)
 #endif
 
 #ifdef CONFIG_MODULE_SIG
+bool is_module_sig_enforced(void);
+
 static inline bool module_sig_ok(struct module *module)
 {
        return module->sig_ok;
 }
 #else  /* !CONFIG_MODULE_SIG */
+static inline bool is_module_sig_enforced(void)
+{
+       return false;
+}
+
 static inline bool module_sig_ok(struct module *module)
 {
        return true;
index a6895bb..d6f646a 100644 (file)
@@ -158,3 +158,12 @@ static inline int module_enforce_rwx_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
        return 0;
 }
 #endif /* CONFIG_STRICT_MODULE_RWX */
+
+#ifdef CONFIG_MODULE_SIG
+int module_sig_check(struct load_info *info, int flags);
+#else /* !CONFIG_MODULE_SIG */
+static inline int module_sig_check(struct load_info *info, int flags)
+{
+       return 0;
+}
+#endif /* !CONFIG_MODULE_SIG */
index d55a2a8..c349c91 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/vmalloc.h>
 #include <linux/elf.h>
 #include <linux/proc_fs.h>
-#include <linux/security.h>
 #include <linux/seq_file.h>
 #include <linux/syscalls.h>
 #include <linux/fcntl.h>
@@ -127,28 +126,6 @@ static void module_assert_mutex_or_preempt(void)
 #endif
 }
 
-#ifdef CONFIG_MODULE_SIG
-static bool sig_enforce = IS_ENABLED(CONFIG_MODULE_SIG_FORCE);
-module_param(sig_enforce, bool_enable_only, 0644);
-
-void set_module_sig_enforced(void)
-{
-       sig_enforce = true;
-}
-#else
-#define sig_enforce false
-#endif
-
-/*
- * Export sig_enforce kernel cmdline parameter to allow other subsystems rely
- * on that instead of directly to CONFIG_MODULE_SIG_FORCE config.
- */
-bool is_module_sig_enforced(void)
-{
-       return sig_enforce;
-}
-EXPORT_SYMBOL(is_module_sig_enforced);
-
 /* Block module loading/unloading? */
 int modules_disabled = 0;
 core_param(nomodule, modules_disabled, bint, 0);
@@ -2569,70 +2546,6 @@ 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)
-{
-       int err = -ENODATA;
-       const unsigned long markerlen = sizeof(MODULE_SIG_STRING) - 1;
-       const char *reason;
-       const void *mod = info->hdr;
-       bool mangled_module = flags & (MODULE_INIT_IGNORE_MODVERSIONS |
-                                      MODULE_INIT_IGNORE_VERMAGIC);
-       /*
-        * Do not allow mangled modules as a module with version information
-        * removed is no longer the module that was signed.
-        */
-       if (!mangled_module &&
-           info->len > markerlen &&
-           memcmp(mod + info->len - markerlen, MODULE_SIG_STRING, markerlen) == 0) {
-               /* We truncate the module to discard the signature */
-               info->len -= markerlen;
-               err = mod_verify_sig(mod, info);
-               if (!err) {
-                       info->sig_ok = true;
-                       return 0;
-               }
-       }
-
-       /*
-        * We don't permit modules to be loaded into the trusted kernels
-        * without a valid signature on them, but if we're not enforcing,
-        * certain errors are non-fatal.
-        */
-       switch (err) {
-       case -ENODATA:
-               reason = "unsigned module";
-               break;
-       case -ENOPKG:
-               reason = "module with unsupported crypto";
-               break;
-       case -ENOKEY:
-               reason = "module with unavailable key";
-               break;
-
-       default:
-               /*
-                * All other errors are fatal, including lack of memory,
-                * unparseable signatures, and signature check failures --
-                * even if signatures aren't required.
-                */
-               return err;
-       }
-
-       if (is_module_sig_enforced()) {
-               pr_notice("Loading of %s is rejected\n", reason);
-               return -EKEYREJECTED;
-       }
-
-       return security_locked_down(LOCKDOWN_MODULE_SIGNATURE);
-}
-#else /* !CONFIG_MODULE_SIG */
-static int module_sig_check(struct load_info *info, int flags)
-{
-       return 0;
-}
-#endif /* !CONFIG_MODULE_SIG */
-
 static int validate_section_offset(struct load_info *info, Elf_Shdr *shdr)
 {
 #if defined(CONFIG_64BIT)
index 8aeb6d2..85c8999 100644 (file)
 #include <linux/module_signature.h>
 #include <linux/string.h>
 #include <linux/verification.h>
+#include <linux/security.h>
 #include <crypto/public_key.h>
+#include <uapi/linux/module.h>
 #include "internal.h"
 
+static bool sig_enforce = IS_ENABLED(CONFIG_MODULE_SIG_FORCE);
+module_param(sig_enforce, bool_enable_only, 0644);
+
+/*
+ * Export sig_enforce kernel cmdline parameter to allow other subsystems rely
+ * on that instead of directly to CONFIG_MODULE_SIG_FORCE config.
+ */
+bool is_module_sig_enforced(void)
+{
+       return sig_enforce;
+}
+EXPORT_SYMBOL(is_module_sig_enforced);
+
+void set_module_sig_enforced(void)
+{
+       sig_enforce = true;
+}
+
 /*
  * Verify the signature on a module.
  */
@@ -43,3 +63,60 @@ int mod_verify_sig(const void *mod, struct load_info *info)
                                      VERIFYING_MODULE_SIGNATURE,
                                      NULL, NULL);
 }
+
+int module_sig_check(struct load_info *info, int flags)
+{
+       int err = -ENODATA;
+       const unsigned long markerlen = sizeof(MODULE_SIG_STRING) - 1;
+       const char *reason;
+       const void *mod = info->hdr;
+       bool mangled_module = flags & (MODULE_INIT_IGNORE_MODVERSIONS |
+                                      MODULE_INIT_IGNORE_VERMAGIC);
+       /*
+        * Do not allow mangled modules as a module with version information
+        * removed is no longer the module that was signed.
+        */
+       if (!mangled_module &&
+           info->len > markerlen &&
+           memcmp(mod + info->len - markerlen, MODULE_SIG_STRING, markerlen) == 0) {
+               /* We truncate the module to discard the signature */
+               info->len -= markerlen;
+               err = mod_verify_sig(mod, info);
+               if (!err) {
+                       info->sig_ok = true;
+                       return 0;
+               }
+       }
+
+       /*
+        * We don't permit modules to be loaded into the trusted kernels
+        * without a valid signature on them, but if we're not enforcing,
+        * certain errors are non-fatal.
+        */
+       switch (err) {
+       case -ENODATA:
+               reason = "unsigned module";
+               break;
+       case -ENOPKG:
+               reason = "module with unsupported crypto";
+               break;
+       case -ENOKEY:
+               reason = "module with unavailable key";
+               break;
+
+       default:
+               /*
+                * All other errors are fatal, including lack of memory,
+                * unparseable signatures, and signature check failures --
+                * even if signatures aren't required.
+                */
+               return err;
+       }
+
+       if (is_module_sig_enforced()) {
+               pr_notice("Loading of %s is rejected\n", reason);
+               return -EKEYREJECTED;
+       }
+
+       return security_locked_down(LOCKDOWN_MODULE_SIGNATURE);
+}