From da4e35cc8d99491fb80102d03675f7f07d0b0326 Mon Sep 17 00:00:00 2001 From: Linn Crosetto Date: Tue, 30 Aug 2016 11:54:38 -0600 Subject: [PATCH] arm64: add kernel config option to set securelevel when in Secure Boot mode Add a kernel configuration option to enable securelevel, to restrict userspace's ability to modify the running kernel when UEFI Secure Boot is enabled. Based on the x86 patch by Matthew Garrett. Determine the state of Secure Boot in the EFI stub and pass this to the kernel using the FDT. Signed-off-by: Linn Crosetto Gbp-Pq: Topic features/all/securelevel Gbp-Pq: Name arm64-add-kernel-config-option-to-set-securelevel-wh.patch --- arch/arm64/Kconfig | 13 +++++++++++++ drivers/firmware/efi/arm-init.c | 7 +++++++ drivers/firmware/efi/efi.c | 3 ++- drivers/firmware/efi/libstub/arm-stub.c | 2 +- drivers/firmware/efi/libstub/efistub.h | 1 + drivers/firmware/efi/libstub/fdt.c | 7 +++++++ include/linux/efi.h | 1 + 7 files changed, 32 insertions(+), 2 deletions(-) diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index bc3f00f586f1..49008b9590ae 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -972,6 +972,19 @@ config EFI allow the kernel to be booted as an EFI application. This is only useful on systems that have UEFI firmware. +config EFI_SECURE_BOOT_SECURELEVEL + def_bool n + depends on SECURITY_SECURELEVEL + depends on EFI + prompt "Automatically set securelevel when UEFI Secure Boot is enabled" + ---help--- + 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 the kernel restrict any userspace + mechanism that could insert untrusted code into the kernel. + Say Y here to automatically enable securelevel enforcement + when a system boots with UEFI Secure Boot enabled. + config DMI bool "Enable support for SMBIOS (DMI) tables" depends on EFI diff --git a/drivers/firmware/efi/arm-init.c b/drivers/firmware/efi/arm-init.c index c49d50e68aee..df57f6af8bc1 100644 --- a/drivers/firmware/efi/arm-init.c +++ b/drivers/firmware/efi/arm-init.c @@ -21,6 +21,7 @@ #include #include #include +#include #include @@ -243,6 +244,12 @@ void __init efi_init(void) "Unexpected EFI_MEMORY_DESCRIPTOR version %ld", efi.memmap.desc_version); +#ifdef CONFIG_EFI_SECURE_BOOT_SECURELEVEL + if (params.secure_boot > 0) { + set_securelevel(1); + } +#endif + if (uefi_init() < 0) return; diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index 7dd2e2d37231..87e7db08ac2a 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -580,7 +580,8 @@ static __initdata struct params fdt_params[] = { UEFI_PARAM("MemMap Address", "linux,uefi-mmap-start", mmap), UEFI_PARAM("MemMap Size", "linux,uefi-mmap-size", mmap_size), UEFI_PARAM("MemMap Desc. Size", "linux,uefi-mmap-desc-size", desc_size), - UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver) + UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver), + UEFI_PARAM("Secure Boot Enabled", "linux,uefi-secure-boot", secure_boot) }; static __initdata struct params xen_fdt_params[] = { diff --git a/drivers/firmware/efi/libstub/arm-stub.c b/drivers/firmware/efi/libstub/arm-stub.c index d1cb612ecbc9..61ad972f0f8b 100644 --- a/drivers/firmware/efi/libstub/arm-stub.c +++ b/drivers/firmware/efi/libstub/arm-stub.c @@ -20,7 +20,7 @@ bool __nokaslr; -static int efi_get_secureboot(efi_system_table_t *sys_table_arg) +int efi_get_secureboot(efi_system_table_t *sys_table_arg) { static efi_char16_t const sb_var_name[] = { 'S', 'e', 'c', 'u', 'r', 'e', 'B', 'o', 'o', 't', 0 }; diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h index ee49cd23ee63..97a329a7c252 100644 --- a/drivers/firmware/efi/libstub/efistub.h +++ b/drivers/firmware/efi/libstub/efistub.h @@ -62,4 +62,5 @@ efi_status_t efi_random_alloc(efi_system_table_t *sys_table_arg, efi_status_t check_platform_features(efi_system_table_t *sys_table_arg); +int efi_get_secureboot(efi_system_table_t *sys_table_arg); #endif diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c index a6a93116a8f0..dc786dcdb3dd 100644 --- a/drivers/firmware/efi/libstub/fdt.c +++ b/drivers/firmware/efi/libstub/fdt.c @@ -139,6 +139,13 @@ efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt, return efi_status; } } + + fdt_val32 = cpu_to_fdt32(efi_get_secureboot(sys_table)); + status = fdt_setprop(fdt, node, "linux,uefi-secure-boot", + &fdt_val32, sizeof(fdt_val32)); + if (status) + goto fdt_set_fail; + return EFI_SUCCESS; fdt_set_fail: diff --git a/include/linux/efi.h b/include/linux/efi.h index 7c299443c71d..a0ea5ebccbd2 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -696,6 +696,7 @@ struct efi_fdt_params { u32 mmap_size; u32 desc_size; u32 desc_ver; + u32 secure_boot; }; typedef struct { -- 2.30.2