From: Ben Hutchings Date: Tue, 10 Sep 2019 10:54:28 +0000 (+0100) Subject: efi: Lock down the kernel if booted in secure boot mode X-Git-Tag: archive/raspbian/6.1.135-1+rpi1^2~64 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=f3d3cd241b25627d8953e50044ee3517777f6c4f;p=linux.git 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 [Salvatore Bonaccorso: After fixing https://bugs.debian.org/956197 the help text for LOCK_DOWN_IN_EFI_SECURE_BOOT needs to be adjusted to mention that lockdown is triggered in integrity mode] Signed-off-by: Salvatore Bonaccorso Gbp-Pq: Topic features/all/lockdown Gbp-Pq: Name efi-lock-down-the-kernel-if-booted-in-secure-boot-mo.patch --- diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 5c2bc32778d..9d9e7d6d0e2 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -1032,6 +1032,8 @@ void __init setup_arch(char **cmdline_p) if (efi_enabled(EFI_BOOT)) efi_init(); + efi_set_secure_boot(boot_params.secure_boot); + x86_init.resources.dmi_setup(); /* @@ -1202,8 +1204,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 c33c95f409e..8a75beffc07 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -481,6 +481,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) @@ -1381,6 +1382,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..4175b50b1e6 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 integrity mode if EFI Secure Boot is set. diff --git a/security/lockdown/lockdown.c b/security/lockdown/lockdown.c index a79b985e917..b1493ff44a9 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;