Merge tag 'integrity-v5.13' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 1 May 2021 22:32:18 +0000 (15:32 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 1 May 2021 22:32:18 +0000 (15:32 -0700)
Pull IMA updates from Mimi Zohar:
 "In addition to loading the kernel module signing key onto the builtin
  keyring, load it onto the IMA keyring as well.

  Also six trivial changes and bug fixes"

* tag 'integrity-v5.13' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity:
  ima: ensure IMA_APPRAISE_MODSIG has necessary dependencies
  ima: Fix fall-through warnings for Clang
  integrity: Add declarations to init_once void arguments.
  ima: Fix function name error in comment.
  ima: enable loading of build time generated key on .ima keyring
  ima: enable signing of modules with build time generated key
  keys: cleanup build time module signing keys
  ima: Fix the error code for restoring the PCR value
  ima: without an IMA policy loaded, return quickly

12 files changed:
Makefile
certs/Kconfig
certs/Makefile
certs/system_certificates.S
certs/system_keyring.c
include/keys/system_keyring.h
init/Kconfig
security/integrity/digsig.c
security/integrity/iint.c
security/integrity/ima/ima_main.c
security/integrity/ima/ima_policy.c
security/integrity/ima/ima_template.c

index 6eafedd..72af8e4 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1507,9 +1507,9 @@ MRPROPER_FILES += include/config include/generated          \
                  debian snap tar-install \
                  .config .config.old .version \
                  Module.symvers \
-                 signing_key.pem signing_key.priv signing_key.x509     \
-                 x509.genkey extra_certificates signing_key.x509.keyid \
-                 signing_key.x509.signer vmlinux-gdb.py \
+                 certs/signing_key.pem certs/signing_key.x509 \
+                 certs/x509.genkey \
+                 vmlinux-gdb.py \
                  *.spec
 
 # Directories & files removed with 'make distclean'
index ab88d2a..f4e6111 100644 (file)
@@ -4,7 +4,7 @@ menu "Certificates for signature checking"
 config MODULE_SIG_KEY
        string "File name or PKCS#11 URI of module signing key"
        default "certs/signing_key.pem"
-       depends on MODULE_SIG
+       depends on MODULE_SIG || (IMA_APPRAISE_MODSIG && MODULES)
        help
          Provide the file name of a private key/certificate in PEM format,
          or a PKCS#11 URI according to RFC7512. The file should contain, or
index b6db52e..359239a 100644 (file)
@@ -33,6 +33,16 @@ endif # CONFIG_SYSTEM_TRUSTED_KEYRING
 clean-files := x509_certificate_list .x509.list x509_revocation_list
 
 ifeq ($(CONFIG_MODULE_SIG),y)
+       SIGN_KEY = y
+endif
+
+ifeq ($(CONFIG_IMA_APPRAISE_MODSIG),y)
+ifeq ($(CONFIG_MODULES),y)
+       SIGN_KEY = y
+endif
+endif
+
+ifdef SIGN_KEY
 ###############################################################################
 #
 # If module signing is requested, say by allyesconfig, but a key has not been
index 8f29058..e1645e6 100644 (file)
@@ -8,9 +8,12 @@
        .globl system_certificate_list
 system_certificate_list:
 __cert_list_start:
-#ifdef CONFIG_MODULE_SIG
+__module_cert_start:
+#if defined(CONFIG_MODULE_SIG) || (defined(CONFIG_IMA_APPRAISE_MODSIG) \
+                              && defined(CONFIG_MODULES))
        .incbin "certs/signing_key.x509"
 #endif
+__module_cert_end:
        .incbin "certs/x509_certificate_list"
 __cert_list_end:
 
@@ -35,3 +38,12 @@ system_certificate_list_size:
 #else
        .long __cert_list_end - __cert_list_start
 #endif
+
+       .align 8
+       .globl module_cert_size
+module_cert_size:
+#ifdef CONFIG_64BIT
+       .quad __module_cert_end - __module_cert_start
+#else
+       .long __module_cert_end - __module_cert_start
+#endif
index 0c9a479..692365d 100644 (file)
@@ -28,6 +28,7 @@ static struct key *platform_trusted_keys;
 
 extern __initconst const u8 system_certificate_list[];
 extern __initconst const unsigned long system_certificate_list_size;
+extern __initconst const unsigned long module_cert_size;
 
 /**
  * restrict_link_to_builtin_trusted - Restrict keyring addition by built in CA
@@ -133,15 +134,35 @@ static __init int system_trusted_keyring_init(void)
  */
 device_initcall(system_trusted_keyring_init);
 
+__init int load_module_cert(struct key *keyring)
+{
+       if (!IS_ENABLED(CONFIG_IMA_APPRAISE_MODSIG))
+               return 0;
+
+       pr_notice("Loading compiled-in module X.509 certificates\n");
+
+       return load_certificate_list(system_certificate_list, module_cert_size, keyring);
+}
+
 /*
  * Load the compiled-in list of X.509 certificates.
  */
 static __init int load_system_certificate_list(void)
 {
+       const u8 *p;
+       unsigned long size;
+
        pr_notice("Loading compiled-in X.509 certificates\n");
 
-       return load_certificate_list(system_certificate_list, system_certificate_list_size,
-                                    builtin_trusted_keys);
+#ifdef CONFIG_MODULE_SIG
+       p = system_certificate_list;
+       size = system_certificate_list_size;
+#else
+       p = system_certificate_list + module_cert_size;
+       size = system_certificate_list_size - module_cert_size;
+#endif
+
+       return load_certificate_list(p, size, builtin_trusted_keys);
 }
 late_initcall(load_system_certificate_list);
 
index 875e002..6acd3cf 100644 (file)
@@ -16,9 +16,16 @@ extern int restrict_link_by_builtin_trusted(struct key *keyring,
                                            const struct key_type *type,
                                            const union key_payload *payload,
                                            struct key *restriction_key);
+extern __init int load_module_cert(struct key *keyring);
 
 #else
 #define restrict_link_by_builtin_trusted restrict_link_reject
+
+static inline __init int load_module_cert(struct key *keyring)
+{
+       return 0;
+}
+
 #endif
 
 #ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
index 9acb776..b71bf0c 100644 (file)
@@ -2182,7 +2182,7 @@ config MODULE_SIG_FORCE
 config MODULE_SIG_ALL
        bool "Automatically sign all modules"
        default y
-       depends on MODULE_SIG
+       depends on MODULE_SIG || IMA_APPRAISE_MODSIG
        help
          Sign all modules during make modules_install. Without this option,
          modules must be signed manually, using the scripts/sign-file tool.
@@ -2192,7 +2192,7 @@ comment "Do not forget to sign required modules with scripts/sign-file"
 
 choice
        prompt "Which hash algorithm should modules be signed with?"
-       depends on MODULE_SIG
+       depends on MODULE_SIG || IMA_APPRAISE_MODSIG
        help
          This determines which sort of hashing algorithm will be used during
          signature generation.  This algorithm _must_ be built into the kernel
@@ -2224,7 +2224,7 @@ endchoice
 
 config MODULE_SIG_HASH
        string
-       depends on MODULE_SIG
+       depends on MODULE_SIG || IMA_APPRAISE_MODSIG
        default "sha1" if MODULE_SIG_SHA1
        default "sha224" if MODULE_SIG_SHA224
        default "sha256" if MODULE_SIG_SHA256
index 250fb08..3b06a01 100644 (file)
@@ -111,6 +111,8 @@ static int __init __integrity_init_keyring(const unsigned int id,
        } else {
                if (id == INTEGRITY_KEYRING_PLATFORM)
                        set_platform_trusted_keys(keyring[id]);
+               if (id == INTEGRITY_KEYRING_IMA)
+                       load_module_cert(keyring[id]);
        }
 
        return err;
index 0ba0184..fca8a94 100644 (file)
@@ -160,7 +160,7 @@ void integrity_inode_free(struct inode *inode)
 
 static void init_once(void *foo)
 {
-       struct integrity_iint_cache *iint = foo;
+       struct integrity_iint_cache *iint = (struct integrity_iint_cache *) foo;
 
        memset(iint, 0, sizeof(*iint));
        iint->ima_file_status = INTEGRITY_UNKNOWN;
index b85d9e4..906c1d8 100644 (file)
@@ -482,7 +482,7 @@ int ima_bprm_check(struct linux_binprm *bprm)
 }
 
 /**
- * ima_path_check - based on policy, collect/store measurement.
+ * ima_file_check - based on policy, collect/store measurement.
  * @file: pointer to the file to be measured
  * @mask: contains MAY_READ, MAY_WRITE, MAY_EXEC or MAY_APPEND
  *
@@ -606,6 +606,9 @@ void ima_post_create_tmpfile(struct user_namespace *mnt_userns,
        struct integrity_iint_cache *iint;
        int must_appraise;
 
+       if (!ima_policy_flag || !S_ISREG(inode->i_mode))
+               return;
+
        must_appraise = ima_must_appraise(mnt_userns, inode, MAY_ACCESS,
                                          FILE_CHECK);
        if (!must_appraise)
@@ -636,6 +639,9 @@ void ima_post_path_mknod(struct user_namespace *mnt_userns,
        struct inode *inode = dentry->d_inode;
        int must_appraise;
 
+       if (!ima_policy_flag || !S_ISREG(inode->i_mode))
+               return;
+
        must_appraise = ima_must_appraise(mnt_userns, inode, MAY_ACCESS,
                                          FILE_CHECK);
        if (!must_appraise)
@@ -780,6 +786,7 @@ int ima_load_data(enum kernel_load_data_id id, bool contents)
                        pr_err("impossible to appraise a module without a file descriptor. sig_enforce kernel parameter might help\n");
                        return -EACCES; /* INTEGRITY_UNKNOWN */
                }
+               break;
        default:
                break;
        }
index 4f8cb15..fd5d46e 100644 (file)
@@ -599,6 +599,7 @@ static bool ima_match_rules(struct ima_rule_entry *rule,
                        rc = ima_filter_rule_match(secid, rule->lsm[i].type,
                                                   Audit_equal,
                                                   rule->lsm[i].rule);
+                       break;
                default:
                        break;
                }
@@ -836,6 +837,7 @@ void __init ima_init_policy(void)
                add_rules(default_measurement_rules,
                          ARRAY_SIZE(default_measurement_rules),
                          IMA_DEFAULT_POLICY);
+               break;
        default:
                break;
        }
index e22e510..4e081e6 100644 (file)
@@ -494,8 +494,8 @@ int ima_restore_measurement_list(loff_t size, void *buf)
                        }
                }
 
-               entry->pcr = !ima_canonical_fmt ? *(hdr[HDR_PCR].data) :
-                            le32_to_cpu(*(hdr[HDR_PCR].data));
+               entry->pcr = !ima_canonical_fmt ? *(u32 *)(hdr[HDR_PCR].data) :
+                            le32_to_cpu(*(u32 *)(hdr[HDR_PCR].data));
                ret = ima_restore_measurement_entry(entry);
                if (ret < 0)
                        break;