From: Linn Crosetto Date: Tue, 30 Aug 2016 17:54:38 +0000 (-0600) Subject: arm64: add kernel config option to set securelevel when in Secure Boot mode X-Git-Tag: archive/raspbian/4.9.51-1+rpi1~8^2~43 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=29703e8676b137516312c331fa205a9fa8a43886;p=linux-4.9.git 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 --- diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index cf57a7799a0f..3cd5e227058d 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -987,6 +987,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 8efe13075c92..6089026e9d23 100644 --- a/drivers/firmware/efi/arm-init.c +++ b/drivers/firmware/efi/arm-init.c @@ -21,6 +21,7 @@ #include #include #include +#include #include @@ -244,6 +245,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 a4944e22f294..29c7c6ac7d11 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -584,7 +584,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 fac67992bede..99433afad54a 100644 --- a/drivers/firmware/efi/libstub/efistub.h +++ b/drivers/firmware/efi/libstub/efistub.h @@ -54,4 +54,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 260c4b4b492e..5d458baeb872 100644 --- a/drivers/firmware/efi/libstub/fdt.c +++ b/drivers/firmware/efi/libstub/fdt.c @@ -134,6 +134,13 @@ static 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 b020dd370d32..566fa48b90f9 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -717,6 +717,7 @@ struct efi_fdt_params { u32 mmap_size; u32 desc_size; u32 desc_ver; + u32 secure_boot; }; typedef struct {