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
diff --git a/Makefile b/Makefile
index 6eafedd..72af8e4 100644
--- a/Makefile
+++ b/Makefile
@@ -1507,9 +1507,9 @@
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 ab88d2a..f4e6111 100644
--- a/certs/Kconfig
+++ b/certs/Kconfig
@@ -4,7 +4,7 @@
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 b6db52e..359239a 100644
--- a/certs/Makefile
+++ b/certs/Makefile
@@ -33,6 +33,16 @@
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 8f29058..e1645e6 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 @@
#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 0c9a479..692365d 100644
--- a/certs/system_keyring.c
+++ b/certs/system_keyring.c
@@ -28,6 +28,7 @@
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 @@
*/
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 875e002..6acd3cf 100644
--- a/include/keys/system_keyring.h
+++ b/include/keys/system_keyring.h
@@ -16,9 +16,16 @@
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 9acb776..b71bf0c 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -2182,7 +2182,7 @@
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 @@
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 @@
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 250fb08..3b06a01 100644
--- a/security/integrity/digsig.c
+++ b/security/integrity/digsig.c
@@ -111,6 +111,8 @@
} 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 0ba0184..fca8a94 100644
--- a/security/integrity/iint.c
+++ b/security/integrity/iint.c
@@ -160,7 +160,7 @@
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 b85d9e4..906c1d8 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -482,7 +482,7 @@
}
/**
- * 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 @@
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 @@
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 @@
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 4f8cb15..fd5d46e 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -599,6 +599,7 @@
rc = ima_filter_rule_match(secid, rule->lsm[i].type,
Audit_equal,
rule->lsm[i].rule);
+ break;
default:
break;
}
@@ -836,6 +837,7 @@
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 e22e510..4e081e6 100644
--- a/security/integrity/ima/ima_template.c
+++ b/security/integrity/ima/ima_template.c
@@ -494,8 +494,8 @@
}
}
- 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;