~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/kernel/module/signing.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 /* Module signature checker
  3  *
  4  * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
  5  * Written by David Howells (dhowells@redhat.com)
  6  */
  7 
  8 #include <linux/kernel.h>
  9 #include <linux/errno.h>
 10 #include <linux/module.h>
 11 #include <linux/module_signature.h>
 12 #include <linux/string.h>
 13 #include <linux/verification.h>
 14 #include <linux/security.h>
 15 #include <crypto/public_key.h>
 16 #include <uapi/linux/module.h>
 17 #include "internal.h"
 18 
 19 #undef MODULE_PARAM_PREFIX
 20 #define MODULE_PARAM_PREFIX "module."
 21 
 22 static bool sig_enforce = IS_ENABLED(CONFIG_MODULE_SIG_FORCE);
 23 module_param(sig_enforce, bool_enable_only, 0644);
 24 
 25 /*
 26  * Export sig_enforce kernel cmdline parameter to allow other subsystems rely
 27  * on that instead of directly to CONFIG_MODULE_SIG_FORCE config.
 28  */
 29 bool is_module_sig_enforced(void)
 30 {
 31         return sig_enforce;
 32 }
 33 EXPORT_SYMBOL(is_module_sig_enforced);
 34 
 35 void set_module_sig_enforced(void)
 36 {
 37         sig_enforce = true;
 38 }
 39 
 40 /*
 41  * Verify the signature on a module.
 42  */
 43 int mod_verify_sig(const void *mod, struct load_info *info)
 44 {
 45         struct module_signature ms;
 46         size_t sig_len, modlen = info->len;
 47         int ret;
 48 
 49         pr_devel("==>%s(,%zu)\n", __func__, modlen);
 50 
 51         if (modlen <= sizeof(ms))
 52                 return -EBADMSG;
 53 
 54         memcpy(&ms, mod + (modlen - sizeof(ms)), sizeof(ms));
 55 
 56         ret = mod_check_sig(&ms, modlen, "module");
 57         if (ret)
 58                 return ret;
 59 
 60         sig_len = be32_to_cpu(ms.sig_len);
 61         modlen -= sig_len + sizeof(ms);
 62         info->len = modlen;
 63 
 64         return verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len,
 65                                       VERIFY_USE_SECONDARY_KEYRING,
 66                                       VERIFYING_MODULE_SIGNATURE,
 67                                       NULL, NULL);
 68 }
 69 
 70 int module_sig_check(struct load_info *info, int flags)
 71 {
 72         int err = -ENODATA;
 73         const unsigned long markerlen = sizeof(MODULE_SIG_STRING) - 1;
 74         const char *reason;
 75         const void *mod = info->hdr;
 76         bool mangled_module = flags & (MODULE_INIT_IGNORE_MODVERSIONS |
 77                                        MODULE_INIT_IGNORE_VERMAGIC);
 78         /*
 79          * Do not allow mangled modules as a module with version information
 80          * removed is no longer the module that was signed.
 81          */
 82         if (!mangled_module &&
 83             info->len > markerlen &&
 84             memcmp(mod + info->len - markerlen, MODULE_SIG_STRING, markerlen) == 0) {
 85                 /* We truncate the module to discard the signature */
 86                 info->len -= markerlen;
 87                 err = mod_verify_sig(mod, info);
 88                 if (!err) {
 89                         info->sig_ok = true;
 90                         return 0;
 91                 }
 92         }
 93 
 94         /*
 95          * We don't permit modules to be loaded into the trusted kernels
 96          * without a valid signature on them, but if we're not enforcing,
 97          * certain errors are non-fatal.
 98          */
 99         switch (err) {
100         case -ENODATA:
101                 reason = "unsigned module";
102                 break;
103         case -ENOPKG:
104                 reason = "module with unsupported crypto";
105                 break;
106         case -ENOKEY:
107                 reason = "module with unavailable key";
108                 break;
109 
110         default:
111                 /*
112                  * All other errors are fatal, including lack of memory,
113                  * unparseable signatures, and signature check failures --
114                  * even if signatures aren't required.
115                  */
116                 return err;
117         }
118 
119         if (is_module_sig_enforced()) {
120                 pr_notice("Loading of %s is rejected\n", reason);
121                 return -EKEYREJECTED;
122         }
123 
124         return security_locked_down(LOCKDOWN_MODULE_SIGNATURE);
125 }
126 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php