efi: Lock down the kernel if booted in secure boot mode
authorBen Hutchings <ben@decadent.org.uk>
Tue, 10 Sep 2019 10:54:28 +0000 (11:54 +0100)
committerSalvatore Bonaccorso <carnil@debian.org>
Wed, 16 Jul 2025 07:13:16 +0000 (09:13 +0200)
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 <ben@decadent.org.uk>
[Salvatore Bonaccorso: After fixing https://bugs.debian.org/956197 the
help text for LOCK_DOWN_IN_EFI_SECURE_BOOT was adjusted to mention that
lockdown is triggered in integrity mode (https://bugs.debian.org/1025417)]
Signed-off-by: Salvatore Bonaccorso <carnil@debian.org>
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
drivers/firmware/efi/secureboot.c
include/linux/security.h
security/lockdown/Kconfig
security/lockdown/lockdown.c

index 876ac9855f4fc667324a4906700fa56bc9699b2e..93844a247d8810e6a29fbe5952ee8faacf0fde7b 100644 (file)
@@ -904,6 +904,8 @@ void __init setup_arch(char **cmdline_p)
        if (efi_enabled(EFI_BOOT))
                efi_init();
 
+       efi_set_secure_boot(boot_params.secure_boot);
+
        reserve_ibft_region();
        x86_init.resources.dmi_setup();
 
@@ -1070,8 +1072,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();
index b6620669e32bc53f95865e08e0e77e7dceafb0e2..8f2554291fb1fe456f2fbcc09758ebe1c2085c43 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/efi.h>
 #include <linux/kernel.h>
 #include <linux/printk.h>
+#include <linux/security.h>
 
 /*
  * 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:
index 2ec8f3014757cd78ef0d961e77f42db409db3b1c..46bb1a2d5b347db67954fdaf938154c58d019750 100644 (file)
@@ -522,6 +522,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);
 int lsm_fill_user_ctx(struct lsm_ctx __user *uctx, u32 *uctx_len,
                      void *val, size_t val_len, u64 id, u64 flags);
 int security_bdev_alloc(struct block_device *bdev);
@@ -1504,6 +1505,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;
+}
 static inline int lsm_fill_user_ctx(struct lsm_ctx __user *uctx,
                                    u32 *uctx_len, void *val, size_t val_len,
                                    u64 id, u64 flags)
index e84ddf48401010bcc0829a32db58e6f12bfdedcb..4175b50b1e6e18191eaf7253294c6387fcf929d8 100644 (file)
@@ -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.
index f2bdbd55aa2bc3797963d2b4d3ece14a822b8466..f043e70851cf4fddfe442fbe4b4725b0477f2ea5 100644 (file)
@@ -24,7 +24,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;