diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2021-05-01 15:32:18 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2021-05-01 15:32:18 -0700 |
commit | e6f0bf09f0669b3c2cd77fa906830123279a0a21 (patch) | |
tree | 57aed6ff25d40e31f129b934403c7fac7a8cc8c8 | |
parent | 10a3efd0fee5e881b1866cf45950808575cb0f24 (diff) | |
parent | 781a5739489949fd0f32432a9da17f7ddbccf1cc (diff) |
Merge tag 'integrity-v5.13' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity
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
-rw-r--r-- | Makefile | 6 | ||||
-rw-r--r-- | certs/Kconfig | 2 | ||||
-rw-r--r-- | certs/Makefile | 10 | ||||
-rw-r--r-- | certs/system_certificates.S | 14 | ||||
-rw-r--r-- | certs/system_keyring.c | 25 | ||||
-rw-r--r-- | include/keys/system_keyring.h | 7 | ||||
-rw-r--r-- | init/Kconfig | 6 | ||||
-rw-r--r-- | security/integrity/digsig.c | 2 | ||||
-rw-r--r-- | security/integrity/iint.c | 2 | ||||
-rw-r--r-- | security/integrity/ima/ima_main.c | 9 | ||||
-rw-r--r-- | security/integrity/ima/ima_policy.c | 2 | ||||
-rw-r--r-- | security/integrity/ima/ima_template.c | 4 |
12 files changed, 75 insertions, 14 deletions
@@ -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' diff --git a/certs/Kconfig b/certs/Kconfig index ab88d2a7f3c7..f4e61116f94e 100644 --- a/certs/Kconfig +++ b/certs/Kconfig @@ -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 diff --git a/certs/Makefile b/certs/Makefile index b6db52ebf0be..359239a0ee9e 100644 --- a/certs/Makefile +++ b/certs/Makefile @@ -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 diff --git a/certs/system_certificates.S b/certs/system_certificates.S index 8f29058adf93..e1645e6f4d97 100644 --- a/certs/system_certificates.S +++ b/certs/system_certificates.S @@ -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 diff --git a/certs/system_keyring.c b/certs/system_keyring.c index 0c9a4795e847..692365dee2bd 100644 --- a/certs/system_keyring.c +++ b/certs/system_keyring.c @@ -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); diff --git a/include/keys/system_keyring.h b/include/keys/system_keyring.h index 875e002a4180..6acd3cf13a18 100644 --- a/include/keys/system_keyring.h +++ b/include/keys/system_keyring.h @@ -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 diff --git a/init/Kconfig b/init/Kconfig index 9acb7762e971..b71bf0cf5688 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -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 diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c index 250fb0836156..3b06a01bd0fd 100644 --- a/security/integrity/digsig.c +++ b/security/integrity/digsig.c @@ -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; diff --git a/security/integrity/iint.c b/security/integrity/iint.c index 0ba01847e836..fca8a9409e4a 100644 --- a/security/integrity/iint.c +++ b/security/integrity/iint.c @@ -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; diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index b85d9e429426..906c1d8e0b71 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -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; } diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index 4f8cb155e4fd..fd5d46e511f1 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -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; } diff --git a/security/integrity/ima/ima_template.c b/security/integrity/ima/ima_template.c index e22e510ae92d..4e081e650047 100644 --- a/security/integrity/ima/ima_template.c +++ b/security/integrity/ima/ima_template.c @@ -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; |