From a11720ecda5e88ca846afda4e102feb18efb877e Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 10 Sep 2019 11:54:28 +0100 Subject: [PATCH] efi: Lock down the kernel if booted in secure boot mode Based on an earlier patch by David Howells, who wrote the following description: > UEFI Secure Boot provides a mechanism for ensuring that the firmware will > only load signed bootloaders and kernels. Certain use cases may also > require that all kernel modules also be signed. Add a configuration option > that to lock down the kernel - which includes requiring validly signed > modules - if the kernel is secure-booted. Signed-off-by: Ben Hutchings Gbp-Pq: Topic features/all/lockdown Gbp-Pq: Name efi-lock-down-the-kernel-if-booted-in-secure-boot-mo.patch --- arch/x86/kernel/setup.c | 4 ++-- drivers/firmware/efi/secureboot.c | 5 +++++ include/linux/security.h | 6 ++++++ security/lockdown/Kconfig | 15 +++++++++++++++ security/lockdown/lockdown.c | 2 +- 5 files changed, 29 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 7c28c450ef2..7d937735dc0 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -980,6 +980,8 @@ void __init setup_arch(char **cmdline_p) if (efi_enabled(EFI_BOOT)) efi_init(); + efi_set_secure_boot(boot_params.secure_boot); + dmi_setup(); /* @@ -1132,8 +1134,6 @@ void __init setup_arch(char **cmdline_p) /* Allocate bigger log buffer */ setup_log_buf(1); - efi_set_secure_boot(boot_params.secure_boot); - reserve_initrd(); acpi_table_upgrade(); diff --git a/drivers/firmware/efi/secureboot.c b/drivers/firmware/efi/secureboot.c index b6620669e32..8f2554291fb 100644 --- a/drivers/firmware/efi/secureboot.c +++ b/drivers/firmware/efi/secureboot.c @@ -15,6 +15,7 @@ #include #include #include +#include /* * Decide what to do when UEFI secure boot mode is enabled. @@ -28,6 +29,10 @@ void __init efi_set_secure_boot(enum efi_secureboot_mode mode) break; case efi_secureboot_mode_enabled: set_bit(EFI_SECURE_BOOT, &efi.flags); +#ifdef CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT + lock_kernel_down("EFI Secure Boot", + LOCKDOWN_INTEGRITY_MAX); +#endif pr_info("Secure boot enabled\n"); break; default: diff --git a/include/linux/security.h b/include/linux/security.h index e9b4b541061..b135ec7105b 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -459,6 +459,7 @@ int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen); int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen); int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen); int security_locked_down(enum lockdown_reason what); +int lock_kernel_down(const char *where, enum lockdown_reason level); #else /* CONFIG_SECURITY */ static inline int call_blocking_lsm_notifier(enum lsm_event event, void *data) @@ -1312,6 +1313,11 @@ static inline int security_locked_down(enum lockdown_reason what) { return 0; } +static inline int +lock_kernel_down(const char *where, enum lockdown_reason level) +{ + return -EOPNOTSUPP; +} #endif /* CONFIG_SECURITY */ #if defined(CONFIG_SECURITY) && defined(CONFIG_WATCH_QUEUE) diff --git a/security/lockdown/Kconfig b/security/lockdown/Kconfig index e84ddf48401..628a87dd1b6 100644 --- a/security/lockdown/Kconfig +++ b/security/lockdown/Kconfig @@ -45,3 +45,18 @@ config LOCK_DOWN_KERNEL_FORCE_CONFIDENTIALITY disabled. endchoice + +config LOCK_DOWN_IN_EFI_SECURE_BOOT + bool "Lock down the kernel in EFI Secure Boot mode" + default n + depends on SECURITY_LOCKDOWN_LSM + depends on EFI + select SECURITY_LOCKDOWN_LSM_EARLY + help + UEFI Secure Boot provides a mechanism for ensuring that the firmware + will only load signed bootloaders and kernels. Secure boot mode may + be determined from EFI variables provided by the system firmware if + not indicated by the boot parameters. + + Enabling this option results in kernel lockdown being + triggered in confidentiality mode if EFI Secure Boot is set. diff --git a/security/lockdown/lockdown.c b/security/lockdown/lockdown.c index 87cbdc64d27..f669cc680fc 100644 --- a/security/lockdown/lockdown.c +++ b/security/lockdown/lockdown.c @@ -23,7 +23,7 @@ static const enum lockdown_reason lockdown_levels[] = {LOCKDOWN_NONE, /* * Put the kernel into lock-down mode. */ -static int lock_kernel_down(const char *where, enum lockdown_reason level) +int lock_kernel_down(const char *where, enum lockdown_reason level) { if (kernel_locked_down >= level) return -EPERM; -- 2.30.2