From 59637d5e1693451b03d2979ffbe9d40423ef05d7 Mon Sep 17 00:00:00 2001 From: Mimi Zohar Date: Fri, 9 Nov 2018 00:53:40 -0500 Subject: [PATCH 01/19] integrity: support new struct public_key_signature encoding field On systems with IMA-appraisal enabled with a policy requiring file signatures, the "good" signature values are stored on the filesystem as extended attributes (security.ima). Signature verification failure would normally be limited to just a particular file (eg. executable), but during boot signature verification failure could result in a system hang. Defining and requiring a new public_key_signature field requires all callers of asymmetric signature verification to be updated to reflect the change. This patch updates the integrity asymmetric_verify() caller. Fixes: 82f94f24475c ("KEYS: Provide software public key query function [ver #2]") Signed-off-by: Mimi Zohar Cc: David Howells Acked-by: Denis Kenzior --- security/integrity/digsig_asymmetric.c | 1 + 1 file changed, 1 insertion(+) diff --git a/security/integrity/digsig_asymmetric.c b/security/integrity/digsig_asymmetric.c index 6dc075144508..d775e03fbbcc 100644 --- a/security/integrity/digsig_asymmetric.c +++ b/security/integrity/digsig_asymmetric.c @@ -106,6 +106,7 @@ int asymmetric_verify(struct key *keyring, const char *sig, pks.pkey_algo = "rsa"; pks.hash_algo = hash_algo_name[hdr->hash_algo]; + pks.encoding = "pkcs1"; pks.digest = (u8 *)data; pks.digest_size = datalen; pks.s = hdr->sig; From 0914ade209c452cff6a29b1c0ae6fff3167fa1d0 Mon Sep 17 00:00:00 2001 From: Nayna Jain Date: Tue, 9 Oct 2018 23:00:33 +0530 Subject: [PATCH 02/19] x86/ima: define arch_ima_get_secureboot Distros are concerned about totally disabling the kexec_load syscall. As a compromise, the kexec_load syscall will only be disabled when CONFIG_KEXEC_VERIFY_SIG is configured and the system is booted with secureboot enabled. This patch defines the new arch specific function called arch_ima_get_secureboot() to retrieve the secureboot state of the system. Signed-off-by: Nayna Jain Suggested-by: Seth Forshee Cc: David Howells Cc: Eric Biederman Cc: Peter Jones Cc: Vivek Goyal Cc: Dave Young Signed-off-by: Mimi Zohar --- arch/x86/kernel/Makefile | 2 ++ arch/x86/kernel/ima_arch.c | 17 +++++++++++++++++ include/linux/ima.h | 9 +++++++++ 3 files changed, 28 insertions(+) create mode 100644 arch/x86/kernel/ima_arch.c diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 8824d01c0c35..f0910a1e1db7 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -150,3 +150,5 @@ ifeq ($(CONFIG_X86_64),y) obj-$(CONFIG_MMCONF_FAM10H) += mmconf-fam10h_64.o obj-y += vsmp_64.o endif + +obj-$(CONFIG_IMA) += ima_arch.o diff --git a/arch/x86/kernel/ima_arch.c b/arch/x86/kernel/ima_arch.c new file mode 100644 index 000000000000..bb5a88d2b271 --- /dev/null +++ b/arch/x86/kernel/ima_arch.c @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2018 IBM Corporation + */ +#include +#include + +extern struct boot_params boot_params; + +bool arch_ima_get_secureboot(void) +{ + if (efi_enabled(EFI_BOOT) && + (boot_params.secure_boot == efi_secureboot_mode_enabled)) + return true; + else + return false; +} diff --git a/include/linux/ima.h b/include/linux/ima.h index 97914a2833d1..948135fb60f1 100644 --- a/include/linux/ima.h +++ b/include/linux/ima.h @@ -30,6 +30,15 @@ extern void ima_post_path_mknod(struct dentry *dentry); extern void ima_add_kexec_buffer(struct kimage *image); #endif +#ifdef CONFIG_X86 +extern bool arch_ima_get_secureboot(void); +#else +static inline bool arch_ima_get_secureboot(void) +{ + return false; +} +#endif + #else static inline int ima_bprm_check(struct linux_binprm *bprm) { From b5ca117365d960fe5e4fe272bcc8142c28769383 Mon Sep 17 00:00:00 2001 From: Nayna Jain Date: Tue, 9 Oct 2018 23:00:34 +0530 Subject: [PATCH 03/19] ima: prevent kexec_load syscall based on runtime secureboot flag When CONFIG_KEXEC_VERIFY_SIG is enabled, the kexec_file_load syscall requires the kexec'd kernel image to be signed. Distros are concerned about totally disabling the kexec_load syscall. As a compromise, the kexec_load syscall will only be disabled when CONFIG_KEXEC_VERIFY_SIG is configured and the system is booted with secureboot enabled. This patch disables the kexec_load syscall only for systems booted with secureboot enabled. [zohar@linux.ibm.com: add missing mesage on kexec_load failure] Signed-off-by: Nayna Jain Cc: David Howells Cc: Eric Biederman Cc: Peter Jones Cc: Vivek Goyal Cc: Dave Young Signed-off-by: Mimi Zohar --- security/integrity/ima/ima_main.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 1b88d58e1325..df0b2ee49fa2 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -505,20 +505,26 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size, */ int ima_load_data(enum kernel_load_data_id id) { - bool sig_enforce; + bool ima_enforce, sig_enforce; - if ((ima_appraise & IMA_APPRAISE_ENFORCE) != IMA_APPRAISE_ENFORCE) - return 0; + ima_enforce = + (ima_appraise & IMA_APPRAISE_ENFORCE) == IMA_APPRAISE_ENFORCE; switch (id) { case LOADING_KEXEC_IMAGE: - if (ima_appraise & IMA_APPRAISE_KEXEC) { + if (IS_ENABLED(CONFIG_KEXEC_VERIFY_SIG) + && arch_ima_get_secureboot()) { + pr_err("impossible to appraise a kernel image without a file descriptor; try using kexec_file_load syscall.\n"); + return -EACCES; + } + + if (ima_enforce && (ima_appraise & IMA_APPRAISE_KEXEC)) { pr_err("impossible to appraise a kernel image without a file descriptor; try using kexec_file_load syscall.\n"); return -EACCES; /* INTEGRITY_UNKNOWN */ } break; case LOADING_FIRMWARE: - if (ima_appraise & IMA_APPRAISE_FIRMWARE) { + if (ima_enforce && (ima_appraise & IMA_APPRAISE_FIRMWARE)) { pr_err("Prevent firmware sysfs fallback loading.\n"); return -EACCES; /* INTEGRITY_UNKNOWN */ } @@ -526,7 +532,8 @@ int ima_load_data(enum kernel_load_data_id id) case LOADING_MODULE: sig_enforce = is_module_sig_enforced(); - if (!sig_enforce && (ima_appraise & IMA_APPRAISE_MODULES)) { + if (ima_enforce && (!sig_enforce + && (ima_appraise & IMA_APPRAISE_MODULES))) { pr_err("impossible to appraise a module without a file descriptor. sig_enforce kernel parameter might help\n"); return -EACCES; /* INTEGRITY_UNKNOWN */ } From c52657d93b0530449233979514a08cf9fe5c24bc Mon Sep 17 00:00:00 2001 From: Nayna Jain Date: Tue, 9 Oct 2018 23:00:35 +0530 Subject: [PATCH 04/19] ima: refactor ima_init_policy() This patch removes the code duplication in ima_init_policy() by defining a new function named add_rules(). The new function adds the rules to the initial IMA policy, the custom policy or both based on the policy mask (IMA_DEFAULT_POLICY, IMA_CUSTOM_POLICY). Signed-off-by: Nayna Jain Signed-off-by: Mimi Zohar --- security/integrity/ima/ima_policy.c | 97 +++++++++++++++++------------ 1 file changed, 56 insertions(+), 41 deletions(-) diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index 8c9499867c91..1e30d09a56db 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -58,6 +58,8 @@ enum lsm_rule_types { LSM_OBJ_USER, LSM_OBJ_ROLE, LSM_OBJ_TYPE, enum policy_types { ORIGINAL_TCB = 1, DEFAULT_TCB }; +enum policy_rule_list { IMA_DEFAULT_POLICY = 1, IMA_CUSTOM_POLICY }; + struct ima_rule_entry { struct list_head list; int action; @@ -473,6 +475,32 @@ static int ima_appraise_flag(enum ima_hooks func) return 0; } +static void add_rules(struct ima_rule_entry *entries, int count, + enum policy_rule_list policy_rule) +{ + int i = 0; + + for (i = 0; i < count; i++) { + struct ima_rule_entry *entry; + + if (policy_rule & IMA_DEFAULT_POLICY) + list_add_tail(&entries[i].list, &ima_default_rules); + + if (policy_rule & IMA_CUSTOM_POLICY) { + entry = kmemdup(&entries[i], sizeof(*entry), + GFP_KERNEL); + if (!entry) + continue; + + list_add_tail(&entry->list, &ima_policy_rules); + } + if (entries[i].action == APPRAISE) + temp_ima_appraise |= ima_appraise_flag(entries[i].func); + if (entries[i].func == POLICY_CHECK) + temp_ima_appraise |= IMA_APPRAISE_POLICY; + } +} + /** * ima_init_policy - initialize the default measure rules. * @@ -481,28 +509,23 @@ static int ima_appraise_flag(enum ima_hooks func) */ void __init ima_init_policy(void) { - int i, measure_entries, appraise_entries, secure_boot_entries; + int build_appraise_entries; - /* if !ima_policy set entries = 0 so we load NO default rules */ - measure_entries = ima_policy ? ARRAY_SIZE(dont_measure_rules) : 0; - appraise_entries = ima_use_appraise_tcb ? - ARRAY_SIZE(default_appraise_rules) : 0; - secure_boot_entries = ima_use_secure_boot ? - ARRAY_SIZE(secure_boot_rules) : 0; - - for (i = 0; i < measure_entries; i++) - list_add_tail(&dont_measure_rules[i].list, &ima_default_rules); + /* if !ima_policy, we load NO default rules */ + if (ima_policy) + add_rules(dont_measure_rules, ARRAY_SIZE(dont_measure_rules), + IMA_DEFAULT_POLICY); switch (ima_policy) { case ORIGINAL_TCB: - for (i = 0; i < ARRAY_SIZE(original_measurement_rules); i++) - list_add_tail(&original_measurement_rules[i].list, - &ima_default_rules); + add_rules(original_measurement_rules, + ARRAY_SIZE(original_measurement_rules), + IMA_DEFAULT_POLICY); break; case DEFAULT_TCB: - for (i = 0; i < ARRAY_SIZE(default_measurement_rules); i++) - list_add_tail(&default_measurement_rules[i].list, - &ima_default_rules); + add_rules(default_measurement_rules, + ARRAY_SIZE(default_measurement_rules), + IMA_DEFAULT_POLICY); default: break; } @@ -511,38 +534,30 @@ void __init ima_init_policy(void) * Insert the builtin "secure_boot" policy rules requiring file * signatures, prior to any other appraise rules. */ - for (i = 0; i < secure_boot_entries; i++) { - list_add_tail(&secure_boot_rules[i].list, &ima_default_rules); - temp_ima_appraise |= - ima_appraise_flag(secure_boot_rules[i].func); - } + if (ima_use_secure_boot) + add_rules(secure_boot_rules, ARRAY_SIZE(secure_boot_rules), + IMA_DEFAULT_POLICY); /* * Insert the build time appraise rules requiring file signatures * for both the initial and custom policies, prior to other appraise - * rules. + * rules. As the secure boot rules includes all of the build time + * rules, include either one or the other set of rules, but not both. */ - for (i = 0; i < ARRAY_SIZE(build_appraise_rules); i++) { - struct ima_rule_entry *entry; - - if (!secure_boot_entries) - list_add_tail(&build_appraise_rules[i].list, - &ima_default_rules); - - entry = kmemdup(&build_appraise_rules[i], sizeof(*entry), - GFP_KERNEL); - if (entry) - list_add_tail(&entry->list, &ima_policy_rules); - build_ima_appraise |= - ima_appraise_flag(build_appraise_rules[i].func); + build_appraise_entries = ARRAY_SIZE(build_appraise_rules); + if (build_appraise_entries) { + if (ima_use_secure_boot) + add_rules(build_appraise_rules, build_appraise_entries, + IMA_CUSTOM_POLICY); + else + add_rules(build_appraise_rules, build_appraise_entries, + IMA_DEFAULT_POLICY | IMA_CUSTOM_POLICY); } - for (i = 0; i < appraise_entries; i++) { - list_add_tail(&default_appraise_rules[i].list, - &ima_default_rules); - if (default_appraise_rules[i].func == POLICY_CHECK) - temp_ima_appraise |= IMA_APPRAISE_POLICY; - } + if (ima_use_appraise_tcb) + add_rules(default_appraise_rules, + ARRAY_SIZE(default_appraise_rules), + IMA_DEFAULT_POLICY); ima_rules = &ima_default_rules; ima_update_policy_flag(); From 6191706246de99ff2fac4b6f157f20205a0943cd Mon Sep 17 00:00:00 2001 From: Nayna Jain Date: Tue, 9 Oct 2018 23:00:36 +0530 Subject: [PATCH 05/19] ima: add support for arch specific policies Builtin IMA policies can be enabled on the boot command line, and replaced with a custom policy, normally during early boot in the initramfs. Build time IMA policy rules were recently added. These rules are automatically enabled on boot and persist after loading a custom policy. There is a need for yet another type of policy, an architecture specific policy, which is derived at runtime during kernel boot, based on the runtime secure boot flags. Like the build time policy rules, these rules persist after loading a custom policy. This patch adds support for loading an architecture specific IMA policy. Signed-off-by: Nayna Jain Co-Developed-by: Mimi Zohar Signed-off-by: Mimi Zohar --- include/linux/ima.h | 5 ++ security/integrity/ima/ima_policy.c | 72 ++++++++++++++++++++++++++++- 2 files changed, 75 insertions(+), 2 deletions(-) diff --git a/include/linux/ima.h b/include/linux/ima.h index 948135fb60f1..62c5241b0899 100644 --- a/include/linux/ima.h +++ b/include/linux/ima.h @@ -39,6 +39,11 @@ static inline bool arch_ima_get_secureboot(void) } #endif +static inline const char * const *arch_get_ima_policy(void) +{ + return NULL; +} + #else static inline int ima_bprm_check(struct linux_binprm *bprm) { diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index 1e30d09a56db..b20770704b6c 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "ima.h" @@ -195,6 +196,9 @@ static struct ima_rule_entry secure_boot_rules[] __ro_after_init = { .flags = IMA_FUNC | IMA_DIGSIG_REQUIRED}, }; +/* An array of architecture specific rules */ +struct ima_rule_entry *arch_policy_entry __ro_after_init; + static LIST_HEAD(ima_default_rules); static LIST_HEAD(ima_policy_rules); static LIST_HEAD(ima_temp_rules); @@ -501,6 +505,49 @@ static void add_rules(struct ima_rule_entry *entries, int count, } } +static int ima_parse_rule(char *rule, struct ima_rule_entry *entry); + +static int __init ima_init_arch_policy(void) +{ + const char * const *arch_rules; + const char * const *rules; + int arch_entries = 0; + int i = 0; + + arch_rules = arch_get_ima_policy(); + if (!arch_rules) + return arch_entries; + + /* Get number of rules */ + for (rules = arch_rules; *rules != NULL; rules++) + arch_entries++; + + arch_policy_entry = kcalloc(arch_entries + 1, + sizeof(*arch_policy_entry), GFP_KERNEL); + if (!arch_policy_entry) + return 0; + + /* Convert each policy string rules to struct ima_rule_entry format */ + for (rules = arch_rules, i = 0; *rules != NULL; rules++) { + char rule[255]; + int result; + + result = strlcpy(rule, *rules, sizeof(rule)); + + INIT_LIST_HEAD(&arch_policy_entry[i].list); + result = ima_parse_rule(rule, &arch_policy_entry[i]); + if (result) { + pr_warn("Skipping unknown architecture policy rule: %s\n", + rule); + memset(&arch_policy_entry[i], 0, + sizeof(*arch_policy_entry)); + continue; + } + i++; + } + return i; +} + /** * ima_init_policy - initialize the default measure rules. * @@ -509,7 +556,7 @@ static void add_rules(struct ima_rule_entry *entries, int count, */ void __init ima_init_policy(void) { - int build_appraise_entries; + int build_appraise_entries, arch_entries; /* if !ima_policy, we load NO default rules */ if (ima_policy) @@ -530,9 +577,22 @@ void __init ima_init_policy(void) break; } + /* + * Based on runtime secure boot flags, insert arch specific measurement + * and appraise rules requiring file signatures for both the initial + * and custom policies, prior to other appraise rules. + * (Highest priority) + */ + arch_entries = ima_init_arch_policy(); + if (!arch_entries) + pr_info("No architecture policies found\n"); + else + add_rules(arch_policy_entry, arch_entries, + IMA_DEFAULT_POLICY | IMA_CUSTOM_POLICY); + /* * Insert the builtin "secure_boot" policy rules requiring file - * signatures, prior to any other appraise rules. + * signatures, prior to other appraise rules. */ if (ima_use_secure_boot) add_rules(secure_boot_rules, ARRAY_SIZE(secure_boot_rules), @@ -591,6 +651,14 @@ void ima_update_policy(void) if (ima_rules != policy) { ima_policy_flag = 0; ima_rules = policy; + + /* + * IMA architecture specific policy rules are specified + * as strings and converted to an array of ima_entry_rules + * on boot. After loading a custom policy, free the + * architecture specific rules stored as an array. + */ + kfree(arch_policy_entry); } ima_update_policy_flag(); } From d958083a8f6408e76850bc7394976050d7e43173 Mon Sep 17 00:00:00 2001 From: Eric Richter Date: Tue, 9 Oct 2018 23:00:37 +0530 Subject: [PATCH 06/19] x86/ima: define arch_get_ima_policy() for x86 On x86, there are two methods of verifying a kexec'ed kernel image signature being loaded via the kexec_file_load syscall - an architecture specific implementaton or a IMA KEXEC_KERNEL_CHECK appraisal rule. Neither of these methods verify the kexec'ed kernel image signature being loaded via the kexec_load syscall. Secure boot enabled systems require kexec images to be signed. Therefore, this patch loads an IMA KEXEC_KERNEL_CHECK policy rule on secure boot enabled systems not configured with CONFIG_KEXEC_VERIFY_SIG enabled. When IMA_APPRAISE_BOOTPARAM is configured, different IMA appraise modes (eg. fix, log) can be specified on the boot command line, allowing unsigned or invalidly signed kernel images to be kexec'ed. This patch permits enabling IMA_APPRAISE_BOOTPARAM or IMA_ARCH_POLICY, but not both. Signed-off-by: Eric Richter Signed-off-by: Nayna Jain Cc: David Howells Cc: Eric Biederman Cc: Peter Jones Cc: Vivek Goyal Cc: Dave Young Signed-off-by: Mimi Zohar --- arch/x86/kernel/ima_arch.c | 16 ++++++++++++++++ include/linux/ima.h | 3 ++- security/integrity/ima/Kconfig | 10 +++++++++- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/ima_arch.c b/arch/x86/kernel/ima_arch.c index bb5a88d2b271..6c248616ee57 100644 --- a/arch/x86/kernel/ima_arch.c +++ b/arch/x86/kernel/ima_arch.c @@ -15,3 +15,19 @@ bool arch_ima_get_secureboot(void) else return false; } + +/* secureboot arch rules */ +static const char * const sb_arch_rules[] = { +#if !IS_ENABLED(CONFIG_KEXEC_VERIFY_SIG) + "appraise func=KEXEC_KERNEL_CHECK appraise_type=imasig", +#endif /* CONFIG_KEXEC_VERIFY_SIG */ + "measure func=KEXEC_KERNEL_CHECK", + NULL +}; + +const char * const *arch_get_ima_policy(void) +{ + if (IS_ENABLED(CONFIG_IMA_ARCH_POLICY) && arch_ima_get_secureboot()) + return sb_arch_rules; + return NULL; +} diff --git a/include/linux/ima.h b/include/linux/ima.h index 62c5241b0899..5ab9134d4fd7 100644 --- a/include/linux/ima.h +++ b/include/linux/ima.h @@ -32,17 +32,18 @@ extern void ima_add_kexec_buffer(struct kimage *image); #ifdef CONFIG_X86 extern bool arch_ima_get_secureboot(void); +extern const char * const *arch_get_ima_policy(void); #else static inline bool arch_ima_get_secureboot(void) { return false; } -#endif static inline const char * const *arch_get_ima_policy(void) { return NULL; } +#endif #else static inline int ima_bprm_check(struct linux_binprm *bprm) diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig index 13b446328dda..a18f8c6d13b5 100644 --- a/security/integrity/ima/Kconfig +++ b/security/integrity/ima/Kconfig @@ -157,6 +157,14 @@ config IMA_APPRAISE If unsure, say N. +config IMA_ARCH_POLICY + bool "Enable loading an IMA architecture specific policy" + depends on KEXEC_VERIFY_SIG || IMA_APPRAISE && INTEGRITY_ASYMMETRIC_KEYS + default n + help + This option enables loading an IMA architecture specific policy + based on run time secure boot flags. + config IMA_APPRAISE_BUILD_POLICY bool "IMA build time configured policy rules" depends on IMA_APPRAISE && INTEGRITY_ASYMMETRIC_KEYS @@ -217,7 +225,7 @@ config IMA_APPRAISE_REQUIRE_POLICY_SIGS config IMA_APPRAISE_BOOTPARAM bool "ima_appraise boot parameter" - depends on IMA_APPRAISE + depends on IMA_APPRAISE && !IMA_ARCH_POLICY default y help This option enables the different "ima_appraise=" modes From 4264f27a0815c46dfda9c9dd6d5f4abc1df04415 Mon Sep 17 00:00:00 2001 From: Stefan Berger Date: Fri, 19 Oct 2018 06:17:58 -0400 Subject: [PATCH 07/19] docs: Extend trusted keys documentation for TPM 2.0 Extend the documentation for trusted keys with documentation for how to set up a key for a TPM 2.0 so it can be used with a TPM 2.0 as well. Signed-off-by: Stefan Berger Reviewed-by: Mimi Zohar Reviewed-by: Dave Jiang Acked-by: Dan Williams Acked-by: Jerry Snitselaar Signed-off-by: Mimi Zohar --- .../security/keys/trusted-encrypted.rst | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/Documentation/security/keys/trusted-encrypted.rst b/Documentation/security/keys/trusted-encrypted.rst index 3bb24e09a332..6ec6bb2ac497 100644 --- a/Documentation/security/keys/trusted-encrypted.rst +++ b/Documentation/security/keys/trusted-encrypted.rst @@ -18,10 +18,33 @@ integrity verifications match. A loaded Trusted Key can be updated with new when the kernel and initramfs are updated. The same key can have many saved blobs under different PCR values, so multiple boots are easily supported. +TPM 1.2 +------- + By default, trusted keys are sealed under the SRK, which has the default authorization value (20 zeros). This can be set at takeownership time with the trouser's utility: "tpm_takeownership -u -z". +TPM 2.0 +------- + +The user must first create a storage key and make it persistent, so the key is +available after reboot. This can be done using the following commands. + +With the IBM TSS 2 stack:: + + #> tsscreateprimary -hi o -st + Handle 80000000 + #> tssevictcontrol -hi o -ho 80000000 -hp 81000001 + +Or with the Intel TSS 2 stack:: + + #> tpm2_createprimary --hierarchy o -G rsa2048 -o key.ctxt + [...] + handle: 0x800000FF + #> tpm2_evictcontrol -c key.ctxt -p 0x81000001 + persistentHandle: 0x81000001 + Usage:: keyctl add trusted name "new keylen [options]" ring @@ -30,7 +53,9 @@ Usage:: keyctl print keyid options: - keyhandle= ascii hex value of sealing key default 0x40000000 (SRK) + keyhandle= ascii hex value of sealing key + TPM 1.2: default 0x40000000 (SRK) + TPM 2.0: no default; must be passed every time keyauth= ascii hex auth for sealing key default 0x00...i (40 ascii zeros) blobauth= ascii hex auth for sealed data default 0x00... @@ -84,6 +109,10 @@ Examples of trusted and encrypted key usage: Create and save a trusted key named "kmk" of length 32 bytes:: +Note: When using a TPM 2.0 with a persistent key with handle 0x81000001, +append 'keyhandle=0x81000001' to statements between quotes, such as +"new 32 keyhandle=0x81000001". + $ keyctl add trusted kmk "new 32" @u 440502848 From 399574c64eaf94e82b7cf056978d7e68748c0f1d Mon Sep 17 00:00:00 2001 From: Mimi Zohar Date: Sun, 18 Nov 2018 04:08:12 -0500 Subject: [PATCH 08/19] x86/ima: retry detecting secure boot mode The secure boot mode may not be detected on boot for some reason (eg. buggy firmware). This patch attempts one more time to detect the secure boot mode. Signed-off-by: Mimi Zohar --- arch/x86/kernel/Makefile | 2 ++ arch/x86/kernel/ima_arch.c | 46 ++++++++++++++++++++++++++++++++++++-- include/linux/ima.h | 2 +- 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index f0910a1e1db7..eb51b0e1189c 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -151,4 +151,6 @@ ifeq ($(CONFIG_X86_64),y) obj-y += vsmp_64.o endif +ifdef CONFIG_EFI obj-$(CONFIG_IMA) += ima_arch.o +endif diff --git a/arch/x86/kernel/ima_arch.c b/arch/x86/kernel/ima_arch.c index 6c248616ee57..e47cd9390ab4 100644 --- a/arch/x86/kernel/ima_arch.c +++ b/arch/x86/kernel/ima_arch.c @@ -7,10 +7,52 @@ extern struct boot_params boot_params; +static enum efi_secureboot_mode get_sb_mode(void) +{ + efi_char16_t efi_SecureBoot_name[] = L"SecureBoot"; + efi_guid_t efi_variable_guid = EFI_GLOBAL_VARIABLE_GUID; + efi_status_t status; + unsigned long size; + u8 secboot; + + size = sizeof(secboot); + + /* Get variable contents into buffer */ + status = efi.get_variable(efi_SecureBoot_name, &efi_variable_guid, + NULL, &size, &secboot); + if (status == EFI_NOT_FOUND) { + pr_info("ima: secureboot mode disabled\n"); + return efi_secureboot_mode_disabled; + } + + if (status != EFI_SUCCESS) { + pr_info("ima: secureboot mode unknown\n"); + return efi_secureboot_mode_unknown; + } + + if (secboot == 0) { + pr_info("ima: secureboot mode disabled\n"); + return efi_secureboot_mode_disabled; + } + + pr_info("ima: secureboot mode enabled\n"); + return efi_secureboot_mode_enabled; +} + bool arch_ima_get_secureboot(void) { - if (efi_enabled(EFI_BOOT) && - (boot_params.secure_boot == efi_secureboot_mode_enabled)) + static enum efi_secureboot_mode sb_mode; + static bool initialized; + + if (!initialized && efi_enabled(EFI_BOOT)) { + sb_mode = boot_params.secure_boot; + + if (sb_mode == efi_secureboot_mode_unset) + sb_mode = get_sb_mode(); + initialized = true; + } + + if (sb_mode == efi_secureboot_mode_enabled) return true; else return false; diff --git a/include/linux/ima.h b/include/linux/ima.h index 5ab9134d4fd7..b5e16b8c50b7 100644 --- a/include/linux/ima.h +++ b/include/linux/ima.h @@ -30,7 +30,7 @@ extern void ima_post_path_mknod(struct dentry *dentry); extern void ima_add_kexec_buffer(struct kimage *image); #endif -#ifdef CONFIG_X86 +#if defined(CONFIG_X86) && defined(CONFIG_EFI) extern bool arch_ima_get_secureboot(void); extern const char * const *arch_get_ima_policy(void); #else From 060190fbe676268a04a80d5f4b426fc3db9c2401 Mon Sep 17 00:00:00 2001 From: Mimi Zohar Date: Wed, 14 Nov 2018 17:24:13 -0500 Subject: [PATCH 09/19] ima: don't measure/appraise files on efivarfs Update the builtin IMA policies specified on the boot command line (eg. ima_policy="tcb|appraise_tcb") to permit accessing efivar files. Signed-off-by: Mimi Zohar --- security/integrity/ima/ima_policy.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index b20770704b6c..d17a23b5c91d 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -107,7 +107,8 @@ static struct ima_rule_entry dont_measure_rules[] __ro_after_init = { .flags = IMA_FSMAGIC}, {.action = DONT_MEASURE, .fsmagic = CGROUP2_SUPER_MAGIC, .flags = IMA_FSMAGIC}, - {.action = DONT_MEASURE, .fsmagic = NSFS_MAGIC, .flags = IMA_FSMAGIC} + {.action = DONT_MEASURE, .fsmagic = NSFS_MAGIC, .flags = IMA_FSMAGIC}, + {.action = DONT_MEASURE, .fsmagic = EFIVARFS_MAGIC, .flags = IMA_FSMAGIC} }; static struct ima_rule_entry original_measurement_rules[] __ro_after_init = { @@ -150,6 +151,7 @@ static struct ima_rule_entry default_appraise_rules[] __ro_after_init = { {.action = DONT_APPRAISE, .fsmagic = SELINUX_MAGIC, .flags = IMA_FSMAGIC}, {.action = DONT_APPRAISE, .fsmagic = SMACK_MAGIC, .flags = IMA_FSMAGIC}, {.action = DONT_APPRAISE, .fsmagic = NSFS_MAGIC, .flags = IMA_FSMAGIC}, + {.action = DONT_APPRAISE, .fsmagic = EFIVARFS_MAGIC, .flags = IMA_FSMAGIC}, {.action = DONT_APPRAISE, .fsmagic = CGROUP_SUPER_MAGIC, .flags = IMA_FSMAGIC}, {.action = DONT_APPRAISE, .fsmagic = CGROUP2_SUPER_MAGIC, .flags = IMA_FSMAGIC}, #ifdef CONFIG_IMA_WRITE_POLICY From a802ed0dd9c2607cc219574e881062d43ea3b7e0 Mon Sep 17 00:00:00 2001 From: Mimi Zohar Date: Wed, 14 Nov 2018 12:30:19 -0500 Subject: [PATCH 10/19] selftests/ima: kexec_load syscall test The kernel CONFIG_KEXEC_VERIFY_SIG option is limited to verifying a kernel image's signature, when loaded via the kexec_file_load syscall. There is no method for verifying a kernel image's signature loaded via the kexec_load syscall. This test verifies loading the kernel image via the kexec_load syscall fails when the kernel CONFIG_KEXEC_VERIFY_SIG option is enabled on systems with secureboot enabled[1]. [1] Detecting secureboot enabled is architecture specific. Signed-off-by: Mimi Zohar --- tools/testing/selftests/Makefile | 1 + tools/testing/selftests/ima/Makefile | 11 ++++ tools/testing/selftests/ima/config | 4 ++ .../testing/selftests/ima/test_kexec_load.sh | 54 +++++++++++++++++++ 4 files changed, 70 insertions(+) create mode 100644 tools/testing/selftests/ima/Makefile create mode 100644 tools/testing/selftests/ima/config create mode 100755 tools/testing/selftests/ima/test_kexec_load.sh diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index f1fe492c8e17..552c447af03d 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -13,6 +13,7 @@ TARGETS += firmware TARGETS += ftrace TARGETS += futex TARGETS += gpio +TARGETS += ima TARGETS += intel_pstate TARGETS += ipc TARGETS += kcmp diff --git a/tools/testing/selftests/ima/Makefile b/tools/testing/selftests/ima/Makefile new file mode 100644 index 000000000000..0b3adf5444b6 --- /dev/null +++ b/tools/testing/selftests/ima/Makefile @@ -0,0 +1,11 @@ +# Makefile for kexec_load + +uname_M := $(shell uname -m 2>/dev/null || echo not) +ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/) + +ifeq ($(ARCH),x86) +TEST_PROGS := test_kexec_load.sh + +include ../lib.mk + +endif diff --git a/tools/testing/selftests/ima/config b/tools/testing/selftests/ima/config new file mode 100644 index 000000000000..6bc86d4d9bb4 --- /dev/null +++ b/tools/testing/selftests/ima/config @@ -0,0 +1,4 @@ +CONFIG_IMA_APPRAISE +CONFIG_IMA_ARCH_POLICY +CONFIG_SECURITYFS +CONFIG_KEXEC_VERIFY_SIG diff --git a/tools/testing/selftests/ima/test_kexec_load.sh b/tools/testing/selftests/ima/test_kexec_load.sh new file mode 100755 index 000000000000..1c10093fb526 --- /dev/null +++ b/tools/testing/selftests/ima/test_kexec_load.sh @@ -0,0 +1,54 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0+ +# Loading a kernel image via the kexec_load syscall should fail +# when the kerne is CONFIG_KEXEC_VERIFY_SIG enabled and the system +# is booted in secureboot mode. + +TEST="$0" +EFIVARFS="/sys/firmware/efi/efivars" +rc=0 + +# Kselftest framework requirement - SKIP code is 4. +ksft_skip=4 + +# kexec requires root privileges +if [ $UID != 0 ]; then + echo "$TEST: must be run as root" >&2 + exit $ksft_skip +fi + +# Make sure that efivars is mounted in the normal location +if ! grep -q "^\S\+ $EFIVARFS efivarfs" /proc/mounts; then + echo "$TEST: efivars is not mounted on $EFIVARFS" >&2 + exit $ksft_skip +fi + +# Get secureboot mode +file="$EFIVARFS/SecureBoot-*" +if [ ! -e $file ]; then + echo "$TEST: unknown secureboot mode" >&2 + exit $ksft_skip +fi +secureboot=`hexdump $file | awk '{print substr($4,length($4),1)}'` + +# kexec_load should fail in secure boot mode +KERNEL_IMAGE="/boot/vmlinuz-`uname -r`" +kexec -l $KERNEL_IMAGE &>> /dev/null +if [ $? == 0 ]; then + kexec -u + if [ "$secureboot" == "1" ]; then + echo "$TEST: kexec_load succeeded [FAIL]" + rc=1 + else + echo "$TEST: kexec_load succeeded [PASS]" + fi +else + if [ "$secureboot" == "1" ]; then + echo "$TEST: kexec_load failed [PASS]" + else + echo "$TEST: kexec_load failed [FAIL]" + rc=1 + fi +fi + +exit $rc From 9dc92c45177ab70e20ae94baa2f2e558da63a9c7 Mon Sep 17 00:00:00 2001 From: Nayna Jain Date: Sun, 9 Dec 2018 01:56:59 +0530 Subject: [PATCH 11/19] integrity: Define a trusted platform keyring On secure boot enabled systems, a verified kernel may need to kexec additional kernels. For example, it may be used as a bootloader needing to kexec a target kernel or it may need to kexec a crashdump kernel. In such cases, it may want to verify the signature of the next kernel image. It is further possible that the kernel image is signed with third party keys which are stored as platform or firmware keys in the 'db' variable. The kernel, however, can not directly verify these platform keys, and an administrator may therefore not want to trust them for arbitrary usage. In order to differentiate platform keys from other keys and provide the necessary separation of trust, the kernel needs an additional keyring to store platform keys. This patch creates the new keyring called ".platform" to isolate keys provided by platform from keys by kernel. These keys are used to facilitate signature verification during kexec. Since the scope of this keyring is only the platform/firmware keys, it cannot be updated from userspace. This keyring can be enabled by setting CONFIG_INTEGRITY_PLATFORM_KEYRING. Signed-off-by: Nayna Jain Reviewed-by: Mimi Zohar Acked-by: Serge Hallyn Reviewed-by: James Morris Reviewed-by: Thiago Jung Bauermann Signed-off-by: Mimi Zohar --- security/integrity/Kconfig | 11 +++++ security/integrity/Makefile | 1 + security/integrity/digsig.c | 49 +++++++++++++------ security/integrity/integrity.h | 3 +- .../platform_certs/platform_keyring.c | 35 +++++++++++++ 5 files changed, 82 insertions(+), 17 deletions(-) create mode 100644 security/integrity/platform_certs/platform_keyring.c diff --git a/security/integrity/Kconfig b/security/integrity/Kconfig index da9565891738..4b4d2aeef539 100644 --- a/security/integrity/Kconfig +++ b/security/integrity/Kconfig @@ -51,6 +51,17 @@ config INTEGRITY_TRUSTED_KEYRING .evm keyrings be signed by a key on the system trusted keyring. +config INTEGRITY_PLATFORM_KEYRING + bool "Provide keyring for platform/firmware trusted keys" + depends on INTEGRITY_ASYMMETRIC_KEYS + depends on SYSTEM_BLACKLIST_KEYRING + depends on EFI + help + Provide a separate, distinct keyring for platform trusted keys, which + the kernel automatically populates during initialization from values + provided by the platform for verifying the kexec'ed kerned image + and, possibly, the initramfs signature. + config INTEGRITY_AUDIT bool "Enables integrity auditing support " depends on AUDIT diff --git a/security/integrity/Makefile b/security/integrity/Makefile index 04d6e462b079..046ffc1bb42d 100644 --- a/security/integrity/Makefile +++ b/security/integrity/Makefile @@ -9,6 +9,7 @@ integrity-y := iint.o integrity-$(CONFIG_INTEGRITY_AUDIT) += integrity_audit.o integrity-$(CONFIG_INTEGRITY_SIGNATURE) += digsig.o integrity-$(CONFIG_INTEGRITY_ASYMMETRIC_KEYS) += digsig_asymmetric.o +integrity-$(CONFIG_INTEGRITY_PLATFORM_KEYRING) += platform_certs/platform_keyring.o subdir-$(CONFIG_IMA) += ima obj-$(CONFIG_IMA) += ima/ diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c index 5eacba858e4b..4a22730e0cc6 100644 --- a/security/integrity/digsig.c +++ b/security/integrity/digsig.c @@ -35,6 +35,7 @@ static const char * const keyring_name[INTEGRITY_KEYRING_MAX] = { ".ima", #endif "_module", + ".platform", }; #ifdef CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY @@ -73,12 +74,39 @@ int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, return -EOPNOTSUPP; } -int __init integrity_init_keyring(const unsigned int id) +static int __integrity_init_keyring(const unsigned int id, key_perm_t perm, + struct key_restriction *restriction) { const struct cred *cred = current_cred(); - struct key_restriction *restriction; int err = 0; + keyring[id] = keyring_alloc(keyring_name[id], KUIDT_INIT(0), + KGIDT_INIT(0), cred, perm, + KEY_ALLOC_NOT_IN_QUOTA, + restriction, NULL); + if (IS_ERR(keyring[id])) { + err = PTR_ERR(keyring[id]); + pr_info("Can't allocate %s keyring (%d)\n", + keyring_name[id], err); + keyring[id] = NULL; + } + + return err; +} + +int __init integrity_init_keyring(const unsigned int id) +{ + struct key_restriction *restriction; + key_perm_t perm; + + perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW + | KEY_USR_READ | KEY_USR_SEARCH; + + if (id == INTEGRITY_KEYRING_PLATFORM) { + restriction = NULL; + goto out; + } + if (!IS_ENABLED(CONFIG_INTEGRITY_TRUSTED_KEYRING)) return 0; @@ -87,21 +115,10 @@ int __init integrity_init_keyring(const unsigned int id) return -ENOMEM; restriction->check = restrict_link_to_ima; + perm |= KEY_USR_WRITE; - keyring[id] = keyring_alloc(keyring_name[id], KUIDT_INIT(0), - KGIDT_INIT(0), cred, - ((KEY_POS_ALL & ~KEY_POS_SETATTR) | - KEY_USR_VIEW | KEY_USR_READ | - KEY_USR_WRITE | KEY_USR_SEARCH), - KEY_ALLOC_NOT_IN_QUOTA, - restriction, NULL); - if (IS_ERR(keyring[id])) { - err = PTR_ERR(keyring[id]); - pr_info("Can't allocate %s keyring (%d)\n", - keyring_name[id], err); - keyring[id] = NULL; - } - return err; +out: + return __integrity_init_keyring(id, perm, restriction); } int __init integrity_load_x509(const unsigned int id, const char *path) diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h index e60473b13a8d..c2332a44799e 100644 --- a/security/integrity/integrity.h +++ b/security/integrity/integrity.h @@ -142,7 +142,8 @@ int integrity_kernel_read(struct file *file, loff_t offset, #define INTEGRITY_KEYRING_EVM 0 #define INTEGRITY_KEYRING_IMA 1 #define INTEGRITY_KEYRING_MODULE 2 -#define INTEGRITY_KEYRING_MAX 3 +#define INTEGRITY_KEYRING_PLATFORM 3 +#define INTEGRITY_KEYRING_MAX 4 extern struct dentry *integrity_dir; diff --git a/security/integrity/platform_certs/platform_keyring.c b/security/integrity/platform_certs/platform_keyring.c new file mode 100644 index 000000000000..79f80af5b470 --- /dev/null +++ b/security/integrity/platform_certs/platform_keyring.c @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Platform keyring for firmware/platform keys + * + * Copyright IBM Corporation, 2018 + * Author(s): Nayna Jain + */ + +#include +#include +#include +#include +#include +#include +#include "../integrity.h" + +/* + * Create the trusted keyrings. + */ +static __init int platform_keyring_init(void) +{ + int rc; + + rc = integrity_init_keyring(INTEGRITY_KEYRING_PLATFORM); + if (rc) + return rc; + + pr_notice("Platform Keyring initialized\n"); + return 0; +} + +/* + * Must be initialised before we try and load the keys into the keyring. + */ +device_initcall(platform_keyring_init); From 60740accf78494e166ec76bdc39b7d75fc2fe1c7 Mon Sep 17 00:00:00 2001 From: Nayna Jain Date: Sun, 9 Dec 2018 01:57:00 +0530 Subject: [PATCH 12/19] integrity: Load certs to the platform keyring The patch refactors integrity_load_x509(), making it a wrapper for a new function named integrity_add_key(). This patch also defines a new function named integrity_load_cert() for loading the platform keys. Signed-off-by: Nayna Jain Reviewed-by: Mimi Zohar Acked-by: Serge Hallyn Reviewed-by: James Morris Reviewed-by: Thiago Jung Bauermann Signed-off-by: Mimi Zohar --- security/integrity/digsig.c | 67 ++++++++++++------- security/integrity/integrity.h | 20 ++++++ .../platform_certs/platform_keyring.c | 23 +++++++ 3 files changed, 86 insertions(+), 24 deletions(-) diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c index 4a22730e0cc6..71c3200521d6 100644 --- a/security/integrity/digsig.c +++ b/security/integrity/digsig.c @@ -82,8 +82,7 @@ static int __integrity_init_keyring(const unsigned int id, key_perm_t perm, keyring[id] = keyring_alloc(keyring_name[id], KUIDT_INIT(0), KGIDT_INIT(0), cred, perm, - KEY_ALLOC_NOT_IN_QUOTA, - restriction, NULL); + KEY_ALLOC_NOT_IN_QUOTA, restriction, NULL); if (IS_ERR(keyring[id])) { err = PTR_ERR(keyring[id]); pr_info("Can't allocate %s keyring (%d)\n", @@ -121,16 +120,38 @@ out: return __integrity_init_keyring(id, perm, restriction); } -int __init integrity_load_x509(const unsigned int id, const char *path) +int __init integrity_add_key(const unsigned int id, const void *data, + off_t size, key_perm_t perm) { key_ref_t key; - void *data; - loff_t size; - int rc; + int rc = 0; if (!keyring[id]) return -EINVAL; + key = key_create_or_update(make_key_ref(keyring[id], 1), "asymmetric", + NULL, data, size, perm, + KEY_ALLOC_NOT_IN_QUOTA); + if (IS_ERR(key)) { + rc = PTR_ERR(key); + pr_err("Problem loading X.509 certificate %d\n", rc); + } else { + pr_notice("Loaded X.509 cert '%s'\n", + key_ref_to_ptr(key)->description); + key_ref_put(key); + } + + return rc; + +} + +int __init integrity_load_x509(const unsigned int id, const char *path) +{ + void *data; + loff_t size; + int rc; + key_perm_t perm; + rc = kernel_read_file_from_path(path, &data, &size, 0, READING_X509_CERTIFICATE); if (rc < 0) { @@ -138,23 +159,21 @@ int __init integrity_load_x509(const unsigned int id, const char *path) return rc; } - key = key_create_or_update(make_key_ref(keyring[id], 1), - "asymmetric", - NULL, - data, - size, - ((KEY_POS_ALL & ~KEY_POS_SETATTR) | - KEY_USR_VIEW | KEY_USR_READ), - KEY_ALLOC_NOT_IN_QUOTA); - if (IS_ERR(key)) { - rc = PTR_ERR(key); - pr_err("Problem loading X.509 certificate (%d): %s\n", - rc, path); - } else { - pr_notice("Loaded X.509 cert '%s': %s\n", - key_ref_to_ptr(key)->description, path); - key_ref_put(key); - } + perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW | KEY_USR_READ; + + pr_info("Loading X.509 certificate: %s\n", path); + rc = integrity_add_key(id, (const void *)data, size, perm); + vfree(data); - return 0; + return rc; +} + +int __init integrity_load_cert(const unsigned int id, const char *source, + const void *data, size_t len, key_perm_t perm) +{ + if (!data) + return -EINVAL; + + pr_info("Loading X.509 certificate: %s\n", source); + return integrity_add_key(id, data, len, perm); } diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h index c2332a44799e..3517d2852a07 100644 --- a/security/integrity/integrity.h +++ b/security/integrity/integrity.h @@ -154,6 +154,8 @@ int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, int __init integrity_init_keyring(const unsigned int id); int __init integrity_load_x509(const unsigned int id, const char *path); +int __init integrity_load_cert(const unsigned int id, const char *source, + const void *data, size_t len, key_perm_t perm); #else static inline int integrity_digsig_verify(const unsigned int id, @@ -167,6 +169,14 @@ static inline int integrity_init_keyring(const unsigned int id) { return 0; } + +static inline int __init integrity_load_cert(const unsigned int id, + const char *source, + const void *data, size_t len, + key_perm_t perm) +{ + return 0; +} #endif /* CONFIG_INTEGRITY_SIGNATURE */ #ifdef CONFIG_INTEGRITY_ASYMMETRIC_KEYS @@ -223,3 +233,13 @@ integrity_audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, int type) } #endif + +#ifdef CONFIG_INTEGRITY_PLATFORM_KEYRING +void __init add_to_platform_keyring(const char *source, const void *data, + size_t len); +#else +static inline void __init add_to_platform_keyring(const char *source, + const void *data, size_t len) +{ +} +#endif diff --git a/security/integrity/platform_certs/platform_keyring.c b/security/integrity/platform_certs/platform_keyring.c index 79f80af5b470..bcafd7387729 100644 --- a/security/integrity/platform_certs/platform_keyring.c +++ b/security/integrity/platform_certs/platform_keyring.c @@ -14,6 +14,29 @@ #include #include "../integrity.h" +/** + * add_to_platform_keyring - Add to platform keyring without validation. + * @source: Source of key + * @data: The blob holding the key + * @len: The length of the data blob + * + * Add a key to the platform keyring without checking its trust chain. This + * is available only during kernel initialisation. + */ +void __init add_to_platform_keyring(const char *source, const void *data, + size_t len) +{ + key_perm_t perm; + int rc; + + perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW; + + rc = integrity_load_cert(INTEGRITY_KEYRING_PLATFORM, source, data, len, + perm); + if (rc) + pr_info("Error adding keys to platform keyring %s\n", source); +} + /* * Create the trusted keyrings. */ From 5c126ba22f894427cc770240faa1bf6b02ce7aca Mon Sep 17 00:00:00 2001 From: Dave Howells Date: Sun, 9 Dec 2018 01:57:01 +0530 Subject: [PATCH 13/19] efi: Add EFI signature data types Add the data types that are used for containing hashes, keys and certificates for cryptographic verification along with their corresponding type GUIDs. Signed-off-by: David Howells Acked-by: Nayna Jain Acked-by: Serge Hallyn Reviewed-by: James Morris Signed-off-by: Mimi Zohar --- include/linux/efi.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/include/linux/efi.h b/include/linux/efi.h index 845174e113ce..3d3de1673b15 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -663,6 +663,10 @@ void efi_native_runtime_setup(void); #define EFI_IMAGE_SECURITY_DATABASE_GUID EFI_GUID(0xd719b2cb, 0x3d3a, 0x4596, 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f) #define EFI_SHIM_LOCK_GUID EFI_GUID(0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23) +#define EFI_CERT_SHA256_GUID EFI_GUID(0xc1c41626, 0x504c, 0x4092, 0xac, 0xa9, 0x41, 0xf9, 0x36, 0x93, 0x43, 0x28) +#define EFI_CERT_X509_GUID EFI_GUID(0xa5c059a1, 0x94e4, 0x4aa7, 0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72) +#define EFI_CERT_X509_SHA256_GUID EFI_GUID(0x3bd2a492, 0x96c0, 0x4079, 0xb4, 0x20, 0xfc, 0xf9, 0x8e, 0xf1, 0x03, 0xed) + /* * This GUID is used to pass to the kernel proper the struct screen_info * structure that was populated by the stub based on the GOP protocol instance @@ -934,6 +938,27 @@ typedef struct { efi_memory_desc_t entry[0]; } efi_memory_attributes_table_t; +typedef struct { + efi_guid_t signature_owner; + u8 signature_data[]; +} efi_signature_data_t; + +typedef struct { + efi_guid_t signature_type; + u32 signature_list_size; + u32 signature_header_size; + u32 signature_size; + u8 signature_header[]; + /* efi_signature_data_t signatures[][] */ +} efi_signature_list_t; + +typedef u8 efi_sha256_hash_t[32]; + +typedef struct { + efi_sha256_hash_t to_be_signed_hash; + efi_time_t time_of_revocation; +} efi_cert_x509_sha256_t; + /* * All runtime access to EFI goes through this structure: */ From 0bc9ae395b3f3b6557f0c5f0a0b0cd2fd5c00a04 Mon Sep 17 00:00:00 2001 From: Dave Howells Date: Sun, 9 Dec 2018 01:57:02 +0530 Subject: [PATCH 14/19] efi: Add an EFI signature blob parser Add a function to parse an EFI signature blob looking for elements of interest. A list is made up of a series of sublists, where all the elements in a sublist are of the same type, but sublists can be of different types. For each sublist encountered, the function pointed to by the get_handler_for_guid argument is called with the type specifier GUID and returns either a pointer to a function to handle elements of that type or NULL if the type is not of interest. If the sublist is of interest, each element is passed to the handler function in turn. Signed-off-by: David Howells Signed-off-by: Nayna Jain Acked-by: Serge Hallyn Signed-off-by: Mimi Zohar --- include/linux/efi.h | 9 ++ security/integrity/Makefile | 3 +- .../integrity/platform_certs/efi_parser.c | 108 ++++++++++++++++++ 3 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 security/integrity/platform_certs/efi_parser.c diff --git a/include/linux/efi.h b/include/linux/efi.h index 3d3de1673b15..d916311f2a51 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -1141,6 +1141,15 @@ extern int efi_memattr_apply_permissions(struct mm_struct *mm, char * __init efi_md_typeattr_format(char *buf, size_t size, const efi_memory_desc_t *md); + +typedef void (*efi_element_handler_t)(const char *source, + const void *element_data, + size_t element_size); +extern int __init parse_efi_signature_list( + const char *source, + const void *data, size_t size, + efi_element_handler_t (*get_handler_for_guid)(const efi_guid_t *)); + /** * efi_range_is_wc - check the WC bit on an address range * @start: starting kvirt address diff --git a/security/integrity/Makefile b/security/integrity/Makefile index 046ffc1bb42d..6ee9058866cd 100644 --- a/security/integrity/Makefile +++ b/security/integrity/Makefile @@ -9,7 +9,8 @@ integrity-y := iint.o integrity-$(CONFIG_INTEGRITY_AUDIT) += integrity_audit.o integrity-$(CONFIG_INTEGRITY_SIGNATURE) += digsig.o integrity-$(CONFIG_INTEGRITY_ASYMMETRIC_KEYS) += digsig_asymmetric.o -integrity-$(CONFIG_INTEGRITY_PLATFORM_KEYRING) += platform_certs/platform_keyring.o +integrity-$(CONFIG_INTEGRITY_PLATFORM_KEYRING) += platform_certs/platform_keyring.o \ + platform_certs/efi_parser.o subdir-$(CONFIG_IMA) += ima obj-$(CONFIG_IMA) += ima/ diff --git a/security/integrity/platform_certs/efi_parser.c b/security/integrity/platform_certs/efi_parser.c new file mode 100644 index 000000000000..18f01f36fe6a --- /dev/null +++ b/security/integrity/platform_certs/efi_parser.c @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* EFI signature/key/certificate list parser + * + * Copyright (C) 2012, 2016 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + */ + +#define pr_fmt(fmt) "EFI: "fmt +#include +#include +#include +#include + +/** + * parse_efi_signature_list - Parse an EFI signature list for certificates + * @source: The source of the key + * @data: The data blob to parse + * @size: The size of the data blob + * @get_handler_for_guid: Get the handler func for the sig type (or NULL) + * + * Parse an EFI signature list looking for elements of interest. A list is + * made up of a series of sublists, where all the elements in a sublist are of + * the same type, but sublists can be of different types. + * + * For each sublist encountered, the @get_handler_for_guid function is called + * with the type specifier GUID and returns either a pointer to a function to + * handle elements of that type or NULL if the type is not of interest. + * + * If the sublist is of interest, each element is passed to the handler + * function in turn. + * + * Error EBADMSG is returned if the list doesn't parse correctly and 0 is + * returned if the list was parsed correctly. No error can be returned from + * the @get_handler_for_guid function or the element handler function it + * returns. + */ +int __init parse_efi_signature_list( + const char *source, + const void *data, size_t size, + efi_element_handler_t (*get_handler_for_guid)(const efi_guid_t *)) +{ + efi_element_handler_t handler; + unsigned int offs = 0; + + pr_devel("-->%s(,%zu)\n", __func__, size); + + while (size > 0) { + const efi_signature_data_t *elem; + efi_signature_list_t list; + size_t lsize, esize, hsize, elsize; + + if (size < sizeof(list)) + return -EBADMSG; + + memcpy(&list, data, sizeof(list)); + pr_devel("LIST[%04x] guid=%pUl ls=%x hs=%x ss=%x\n", + offs, + list.signature_type.b, list.signature_list_size, + list.signature_header_size, list.signature_size); + + lsize = list.signature_list_size; + hsize = list.signature_header_size; + esize = list.signature_size; + elsize = lsize - sizeof(list) - hsize; + + if (lsize > size) { + pr_devel("<--%s() = -EBADMSG [overrun @%x]\n", + __func__, offs); + return -EBADMSG; + } + + if (lsize < sizeof(list) || + lsize - sizeof(list) < hsize || + esize < sizeof(*elem) || + elsize < esize || + elsize % esize != 0) { + pr_devel("- bad size combo @%x\n", offs); + return -EBADMSG; + } + + handler = get_handler_for_guid(&list.signature_type); + if (!handler) { + data += lsize; + size -= lsize; + offs += lsize; + continue; + } + + data += sizeof(list) + hsize; + size -= sizeof(list) + hsize; + offs += sizeof(list) + hsize; + + for (; elsize > 0; elsize -= esize) { + elem = data; + + pr_devel("ELEM[%04x]\n", offs); + handler(source, + &elem->signature_data, + esize - sizeof(*elem)); + + data += esize; + size -= esize; + offs += esize; + } + } + + return 0; +} From 15ea0e1e3e185040bed6119f815096f2e4326242 Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Thu, 13 Dec 2018 01:37:56 +0530 Subject: [PATCH 15/19] efi: Import certificates from UEFI Secure Boot Secure Boot stores a list of allowed certificates in the 'db' variable. This patch imports those certificates into the platform keyring. The shim UEFI bootloader has a similar certificate list stored in the 'MokListRT' variable. We import those as well. Secure Boot also maintains a list of disallowed certificates in the 'dbx' variable. We load those certificates into the system blacklist keyring and forbid any kernel signed with those from loading. [zohar@linux.ibm.com: dropped Josh's original patch description] Signed-off-by: Josh Boyer Signed-off-by: David Howells Signed-off-by: Nayna Jain Acked-by: Serge Hallyn Signed-off-by: Mimi Zohar --- security/integrity/Makefile | 5 +- security/integrity/platform_certs/load_uefi.c | 169 ++++++++++++++++++ 2 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 security/integrity/platform_certs/load_uefi.c diff --git a/security/integrity/Makefile b/security/integrity/Makefile index 6ee9058866cd..86df9aba8c0f 100644 --- a/security/integrity/Makefile +++ b/security/integrity/Makefile @@ -10,7 +10,10 @@ integrity-$(CONFIG_INTEGRITY_AUDIT) += integrity_audit.o integrity-$(CONFIG_INTEGRITY_SIGNATURE) += digsig.o integrity-$(CONFIG_INTEGRITY_ASYMMETRIC_KEYS) += digsig_asymmetric.o integrity-$(CONFIG_INTEGRITY_PLATFORM_KEYRING) += platform_certs/platform_keyring.o \ - platform_certs/efi_parser.o + platform_certs/efi_parser.o \ + platform_certs/load_uefi.o +obj-$(CONFIG_LOAD_UEFI_KEYS) += platform_certs/load_uefi.o +$(obj)/load_uefi.o: KBUILD_CFLAGS += -fshort-wchar subdir-$(CONFIG_IMA) += ima obj-$(CONFIG_IMA) += ima/ diff --git a/security/integrity/platform_certs/load_uefi.c b/security/integrity/platform_certs/load_uefi.c new file mode 100644 index 000000000000..8ceafa58d98c --- /dev/null +++ b/security/integrity/platform_certs/load_uefi.c @@ -0,0 +1,169 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#include +#include +#include +#include +#include +#include +#include "../integrity.h" + +static efi_guid_t efi_cert_x509_guid __initdata = EFI_CERT_X509_GUID; +static efi_guid_t efi_cert_x509_sha256_guid __initdata = + EFI_CERT_X509_SHA256_GUID; +static efi_guid_t efi_cert_sha256_guid __initdata = EFI_CERT_SHA256_GUID; + +/* + * Get a certificate list blob from the named EFI variable. + */ +static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid, + unsigned long *size) +{ + efi_status_t status; + unsigned long lsize = 4; + unsigned long tmpdb[4]; + void *db; + + status = efi.get_variable(name, guid, NULL, &lsize, &tmpdb); + if (status != EFI_BUFFER_TOO_SMALL) { + pr_err("Couldn't get size: 0x%lx\n", status); + return NULL; + } + + db = kmalloc(lsize, GFP_KERNEL); + if (!db) + return NULL; + + status = efi.get_variable(name, guid, NULL, &lsize, db); + if (status != EFI_SUCCESS) { + kfree(db); + pr_err("Error reading db var: 0x%lx\n", status); + return NULL; + } + + *size = lsize; + return db; +} + +/* + * Blacklist a hash. + */ +static __init void uefi_blacklist_hash(const char *source, const void *data, + size_t len, const char *type, + size_t type_len) +{ + char *hash, *p; + + hash = kmalloc(type_len + len * 2 + 1, GFP_KERNEL); + if (!hash) + return; + p = memcpy(hash, type, type_len); + p += type_len; + bin2hex(p, data, len); + p += len * 2; + *p = 0; + + mark_hash_blacklisted(hash); + kfree(hash); +} + +/* + * Blacklist an X509 TBS hash. + */ +static __init void uefi_blacklist_x509_tbs(const char *source, + const void *data, size_t len) +{ + uefi_blacklist_hash(source, data, len, "tbs:", 4); +} + +/* + * Blacklist the hash of an executable. + */ +static __init void uefi_blacklist_binary(const char *source, + const void *data, size_t len) +{ + uefi_blacklist_hash(source, data, len, "bin:", 4); +} + +/* + * Return the appropriate handler for particular signature list types found in + * the UEFI db and MokListRT tables. + */ +static __init efi_element_handler_t get_handler_for_db(const efi_guid_t * + sig_type) +{ + if (efi_guidcmp(*sig_type, efi_cert_x509_guid) == 0) + return add_to_platform_keyring; + return 0; +} + +/* + * Return the appropriate handler for particular signature list types found in + * the UEFI dbx and MokListXRT tables. + */ +static __init efi_element_handler_t get_handler_for_dbx(const efi_guid_t * + sig_type) +{ + if (efi_guidcmp(*sig_type, efi_cert_x509_sha256_guid) == 0) + return uefi_blacklist_x509_tbs; + if (efi_guidcmp(*sig_type, efi_cert_sha256_guid) == 0) + return uefi_blacklist_binary; + return 0; +} + +/* + * Load the certs contained in the UEFI databases + */ +static int __init load_uefi_certs(void) +{ + efi_guid_t secure_var = EFI_IMAGE_SECURITY_DATABASE_GUID; + efi_guid_t mok_var = EFI_SHIM_LOCK_GUID; + void *db = NULL, *dbx = NULL, *mok = NULL; + unsigned long dbsize = 0, dbxsize = 0, moksize = 0; + int rc = 0; + + if (!efi.get_variable) + return false; + + /* Get db, MokListRT, and dbx. They might not exist, so it isn't + * an error if we can't get them. + */ + db = get_cert_list(L"db", &secure_var, &dbsize); + if (!db) { + pr_err("Couldn't get UEFI db list\n"); + } else { + rc = parse_efi_signature_list("UEFI:db", + db, dbsize, get_handler_for_db); + if (rc) + pr_err("Couldn't parse db signatures: %d\n", rc); + kfree(db); + } + + mok = get_cert_list(L"MokListRT", &mok_var, &moksize); + if (!mok) { + pr_info("Couldn't get UEFI MokListRT\n"); + } else { + rc = parse_efi_signature_list("UEFI:MokListRT", + mok, moksize, get_handler_for_db); + if (rc) + pr_err("Couldn't parse MokListRT signatures: %d\n", rc); + kfree(mok); + } + + dbx = get_cert_list(L"dbx", &secure_var, &dbxsize); + if (!dbx) { + pr_info("Couldn't get UEFI dbx list\n"); + } else { + rc = parse_efi_signature_list("UEFI:dbx", + dbx, dbxsize, + get_handler_for_dbx); + if (rc) + pr_err("Couldn't parse dbx signatures: %d\n", rc); + kfree(dbx); + } + + return rc; +} +late_initcall(load_uefi_certs); From 386b49f51dc24d1f9139eb11f49aa075eeb35363 Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Sun, 9 Dec 2018 01:57:04 +0530 Subject: [PATCH 16/19] efi: Allow the "db" UEFI variable to be suppressed If a user tells shim to not use the certs/hashes in the UEFI db variable for verification purposes, shim will set a UEFI variable called MokIgnoreDB. Have the uefi import code look for this and ignore the db variable if it is found. [zohar@linux.ibm.com: removed reference to "secondary" keyring comment] Signed-off-by: Josh Boyer Signed-off-by: David Howells Acked-by: Nayna Jain Acked-by: Serge Hallyn Reviewed-by: James Morris Signed-off-by: Mimi Zohar --- security/integrity/platform_certs/load_uefi.c | 45 ++++++++++++++----- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/security/integrity/platform_certs/load_uefi.c b/security/integrity/platform_certs/load_uefi.c index 8ceafa58d98c..81b19c52832b 100644 --- a/security/integrity/platform_certs/load_uefi.c +++ b/security/integrity/platform_certs/load_uefi.c @@ -15,6 +15,26 @@ static efi_guid_t efi_cert_x509_sha256_guid __initdata = EFI_CERT_X509_SHA256_GUID; static efi_guid_t efi_cert_sha256_guid __initdata = EFI_CERT_SHA256_GUID; +/* + * Look to see if a UEFI variable called MokIgnoreDB exists and return true if + * it does. + * + * This UEFI variable is set by the shim if a user tells the shim to not use + * the certs/hashes in the UEFI db variable for verification purposes. If it + * is set, we should ignore the db variable also and the true return indicates + * this. + */ +static __init bool uefi_check_ignore_db(void) +{ + efi_status_t status; + unsigned int db = 0; + unsigned long size = sizeof(db); + efi_guid_t guid = EFI_SHIM_LOCK_GUID; + + status = efi.get_variable(L"MokIgnoreDB", &guid, NULL, &size, &db); + return status == EFI_SUCCESS; +} + /* * Get a certificate list blob from the named EFI variable. */ @@ -114,7 +134,9 @@ static __init efi_element_handler_t get_handler_for_dbx(const efi_guid_t * } /* - * Load the certs contained in the UEFI databases + * Load the certs contained in the UEFI databases into the platform trusted + * keyring and the UEFI blacklisted X.509 cert SHA256 hashes into the blacklist + * keyring. */ static int __init load_uefi_certs(void) { @@ -130,15 +152,18 @@ static int __init load_uefi_certs(void) /* Get db, MokListRT, and dbx. They might not exist, so it isn't * an error if we can't get them. */ - db = get_cert_list(L"db", &secure_var, &dbsize); - if (!db) { - pr_err("Couldn't get UEFI db list\n"); - } else { - rc = parse_efi_signature_list("UEFI:db", - db, dbsize, get_handler_for_db); - if (rc) - pr_err("Couldn't parse db signatures: %d\n", rc); - kfree(db); + if (!uefi_check_ignore_db()) { + db = get_cert_list(L"db", &secure_var, &dbsize); + if (!db) { + pr_err("MODSIGN: Couldn't get UEFI db list\n"); + } else { + rc = parse_efi_signature_list("UEFI:db", + db, dbsize, get_handler_for_db); + if (rc) + pr_err("Couldn't parse db signatures: %d\n", + rc); + kfree(db); + } } mok = get_cert_list(L"MokListRT", &mok_var, &moksize); From d7cecb676dd364b28a5a8f5e4a30ce2e9cfdfcc3 Mon Sep 17 00:00:00 2001 From: Nayna Jain Date: Sun, 9 Dec 2018 01:57:05 +0530 Subject: [PATCH 17/19] ima: Support platform keyring for kernel appraisal On secure boot enabled systems, the bootloader verifies the kernel image and possibly the initramfs signatures based on a set of keys. A soft reboot(kexec) of the system, with the same kernel image and initramfs, requires access to the original keys to verify the signatures. This patch allows IMA-appraisal access to those original keys, now loaded on the platform keyring, needed for verifying the kernel image and initramfs signatures. [zohar@linux.ibm.com: only use platform keyring if it's enabled (Thiago)] Signed-off-by: Nayna Jain Reviewed-by: Mimi Zohar Acked-by: Serge Hallyn Reviewed-by: James Morris Reviewed-by: Thiago Jung Bauermann Signed-off-by: Mimi Zohar --- security/integrity/ima/ima_appraise.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c index deec1804a00a..f6ac405daabb 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c @@ -289,12 +289,22 @@ int ima_appraise_measurement(enum ima_hooks func, case EVM_IMA_XATTR_DIGSIG: set_bit(IMA_DIGSIG, &iint->atomic_flags); rc = integrity_digsig_verify(INTEGRITY_KEYRING_IMA, - (const char *)xattr_value, rc, + (const char *)xattr_value, + xattr_len, iint->ima_hash->digest, iint->ima_hash->length); if (rc == -EOPNOTSUPP) { status = INTEGRITY_UNKNOWN; - } else if (rc) { + break; + } + if (IS_ENABLED(CONFIG_INTEGRITY_PLATFORM_KEYRING) && rc && + func == KEXEC_KERNEL_CHECK) + rc = integrity_digsig_verify(INTEGRITY_KEYRING_PLATFORM, + (const char *)xattr_value, + xattr_len, + iint->ima_hash->digest, + iint->ima_hash->length); + if (rc) { cause = "invalid-signature"; status = INTEGRITY_FAIL; } else { From eed9de3b4f47114f440980203ca27c5fab70f529 Mon Sep 17 00:00:00 2001 From: Nikolay Borisov Date: Tue, 11 Dec 2018 10:31:40 +0200 Subject: [PATCH 18/19] ima: Use inode_is_open_for_write Use the aptly named function rather than open coding the check. No functional changes. Signed-off-by: Nikolay Borisov Signed-off-by: Mimi Zohar --- security/integrity/ima/ima_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index df0b2ee49fa2..bd9bd5f88206 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -103,7 +103,7 @@ static void ima_rdwr_violation_check(struct file *file, } else { if (must_measure) set_bit(IMA_MUST_MEASURE, &iint->atomic_flags); - if ((atomic_read(&inode->i_writecount) > 0) && must_measure) + if (inode_is_open_for_write(inode) && must_measure) send_writers = true; } From c7f7e58fcbf33589f11bfde0506e076a00627e59 Mon Sep 17 00:00:00 2001 From: Thiago Jung Bauermann Date: Wed, 12 Dec 2018 23:39:09 -0200 Subject: [PATCH 19/19] integrity: Remove references to module keyring From what I can tell, it has never been used. Mimi: This was introduced prior to Rusty's decision to use appended signatures for kernel modules. Signed-off-by: Thiago Jung Bauermann Acked-by: Mimi Zohar Signed-off-by: James Morris --- security/integrity/digsig.c | 1 - security/integrity/integrity.h | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c index 71c3200521d6..f45d6edecf99 100644 --- a/security/integrity/digsig.c +++ b/security/integrity/digsig.c @@ -34,7 +34,6 @@ static const char * const keyring_name[INTEGRITY_KEYRING_MAX] = { ".evm", ".ima", #endif - "_module", ".platform", }; diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h index 3517d2852a07..7de59f44cba3 100644 --- a/security/integrity/integrity.h +++ b/security/integrity/integrity.h @@ -141,9 +141,8 @@ int integrity_kernel_read(struct file *file, loff_t offset, #define INTEGRITY_KEYRING_EVM 0 #define INTEGRITY_KEYRING_IMA 1 -#define INTEGRITY_KEYRING_MODULE 2 -#define INTEGRITY_KEYRING_PLATFORM 3 -#define INTEGRITY_KEYRING_MAX 4 +#define INTEGRITY_KEYRING_PLATFORM 2 +#define INTEGRITY_KEYRING_MAX 3 extern struct dentry *integrity_dir;