remove the get_sb_mode() from x86/kernel/ima_arch.c and create a common helper ima_get_efi_secureboot() in IMA so that all EFI-based architectures can refer to the same procedure. Signed-off-by: Chester Lin <clin@xxxxxxxx> --- arch/x86/kernel/ima_arch.c | 69 +++++++------------------------- include/linux/ima.h | 10 +++++ security/integrity/ima/Makefile | 1 + security/integrity/ima/ima_efi.c | 26 ++++++++++++ 4 files changed, 51 insertions(+), 55 deletions(-) create mode 100644 security/integrity/ima/ima_efi.c diff --git a/arch/x86/kernel/ima_arch.c b/arch/x86/kernel/ima_arch.c index 7dfb1e808928..2c773532ff0a 100644 --- a/arch/x86/kernel/ima_arch.c +++ b/arch/x86/kernel/ima_arch.c @@ -8,69 +8,28 @@ extern struct boot_params boot_params; -static enum efi_secureboot_mode get_sb_mode(void) -{ - efi_guid_t efi_variable_guid = EFI_GLOBAL_VARIABLE_GUID; - efi_status_t status; - unsigned long size; - u8 secboot, setupmode; - - size = sizeof(secboot); - - if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE)) { - pr_info("ima: secureboot mode unknown, no efi\n"); - return efi_secureboot_mode_unknown; - } - - /* Get variable contents into buffer */ - status = efi.get_variable(L"SecureBoot", &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; - } - - size = sizeof(setupmode); - status = efi.get_variable(L"SetupMode", &efi_variable_guid, - NULL, &size, &setupmode); - - if (status != EFI_SUCCESS) /* ignore unknown SetupMode */ - setupmode = 0; - - if (secboot == 0 || setupmode == 1) { - 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) { - static enum efi_secureboot_mode sb_mode; - static bool initialized; - - if (!initialized && efi_enabled(EFI_BOOT)) { - sb_mode = boot_params.secure_boot; + static bool sb_enabled, initialized; - if (sb_mode == efi_secureboot_mode_unset) - sb_mode = get_sb_mode(); + if (initialized) { + return sb_enabled; + } else if (efi_enabled(EFI_BOOT)) { initialized = true; + + if (boot_params.secure_boot == efi_secureboot_mode_unset) { + sb_enabled = ima_get_efi_secureboot(); + return sb_enabled; + } } - if (sb_mode == efi_secureboot_mode_enabled) - return true; - else - return false; + if (boot_params.secure_boot == efi_secureboot_mode_enabled) + sb_enabled = true; + + return sb_enabled; } -/* secureboot arch rules */ +/* secure and trusted boot arch rules */ static const char * const sb_arch_rules[] = { #if !IS_ENABLED(CONFIG_KEXEC_SIG) "appraise func=KEXEC_KERNEL_CHECK appraise_type=imasig", diff --git a/include/linux/ima.h b/include/linux/ima.h index 8fa7bcfb2da2..9f9699f017be 100644 --- a/include/linux/ima.h +++ b/include/linux/ima.h @@ -50,6 +50,16 @@ static inline const char * const *arch_get_ima_policy(void) } #endif +#if defined(CONFIG_EFI) && defined(CONFIG_IMA_SECURE_AND_OR_TRUSTED_BOOT) +extern bool ima_get_efi_secureboot(void); +#else +static inline bool ima_get_efi_secureboot(void) +{ + return false; +} +#endif + + #else static inline int ima_bprm_check(struct linux_binprm *bprm) { diff --git a/security/integrity/ima/Makefile b/security/integrity/ima/Makefile index 67dabca670e2..32076b3fd292 100644 --- a/security/integrity/ima/Makefile +++ b/security/integrity/ima/Makefile @@ -14,3 +14,4 @@ ima-$(CONFIG_HAVE_IMA_KEXEC) += ima_kexec.o ima-$(CONFIG_IMA_BLACKLIST_KEYRING) += ima_mok.o ima-$(CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS) += ima_asymmetric_keys.o ima-$(CONFIG_IMA_QUEUE_EARLY_BOOT_KEYS) += ima_queue_keys.o +ima-$(CONFIG_EFI) += ima_efi.o diff --git a/security/integrity/ima/ima_efi.c b/security/integrity/ima/ima_efi.c new file mode 100644 index 000000000000..a78f66e19689 --- /dev/null +++ b/security/integrity/ima/ima_efi.c @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2020 SUSE LLC + * + * Author: + * Chester Lin <clin@xxxxxxxx> + */ + +#include <linux/efi.h> +#include <linux/ima.h> + +#ifdef CONFIG_IMA_SECURE_AND_OR_TRUSTED_BOOT +bool ima_get_efi_secureboot(void) +{ + enum efi_secureboot_mode sb_mode; + + if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE)) { + pr_info("ima: secureboot mode unknown, no efi\n"); + return false; + } + + sb_mode = efi_get_secureboot(efi.get_variable); + + return (sb_mode == efi_secureboot_mode_enabled) ? true : false; +} +#endif -- 2.28.0