From fb3f7d2bdb3b52da94da77deab4c162f39a89e57 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Mon, 9 Sep 2013 15:49:46 -0700 Subject: [PATCH] Add option to automatically set securelevel when in Secure Boot mode Orabug: 21539498 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 prevent userspace from inserting untrusted kernel code at runtime. Add a configuration option that enforces this automatically when enabled. Signed-off-by: Matthew Garrett Signed-off-by: Santosh Shilimkar --- Documentation/x86/zero-page.txt | 2 ++ arch/x86/Kconfig | 13 ++++++++++ arch/x86/boot/compressed/eboot.c | 36 +++++++++++++++++++++++++++ arch/x86/include/uapi/asm/bootparam.h | 3 ++- arch/x86/kernel/setup.c | 7 ++++++ security/Kconfig | 2 +- 6 files changed, 61 insertions(+), 2 deletions(-) diff --git a/Documentation/x86/zero-page.txt b/Documentation/x86/zero-page.txt index 82fbdbc1e0b0..a811210ad486 100644 --- a/Documentation/x86/zero-page.txt +++ b/Documentation/x86/zero-page.txt @@ -30,6 +30,8 @@ Offset Proto Name Meaning 1E9/001 ALL eddbuf_entries Number of entries in eddbuf (below) 1EA/001 ALL edd_mbr_sig_buf_entries Number of entries in edd_mbr_sig_buffer (below) +1EB/001 ALL kbd_status Numlock is enabled +1EC/001 ALL secure_boot Secure boot is enabled in the firmware 1EF/001 ALL sentinel Used to detect broken bootloaders 290/040 ALL edd_mbr_sig_buffer EDD MBR signatures 2D0/A00 ALL e820_map E820 memory map table diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 226d5696e1d1..b1f4cf38ad43 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1697,6 +1697,19 @@ config EFI_MIXED If unsure, say N. +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 SECCOMP def_bool y prompt "Enable seccomp to safely compute untrusted bytecode" diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index 48304b89b601..81c6a5c298a1 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "../string.h" #include "eboot.h" @@ -1375,6 +1376,37 @@ free_mem_map: return status; } +static int get_secure_boot(void) +{ + u8 sb, setup; + unsigned long datasize = sizeof(sb); + efi_guid_t var_guid = EFI_GLOBAL_VARIABLE_GUID; + efi_status_t status; + + status = efi_call_phys(sys_table->runtime->get_variable, + L"SecureBoot", &var_guid, NULL, &datasize, &sb); + + if (status != EFI_SUCCESS) + return 0; + + if (sb == 0) + return 0; + + + status = efi_call_phys(sys_table->runtime->get_variable, + L"SetupMode", &var_guid, NULL, &datasize, + &setup); + + if (status != EFI_SUCCESS) + return 0; + + if (setup == 1) + return 0; + + return 1; +} + + /* * On success we return a pointer to a boot_params structure, and NULL * on failure. @@ -1408,6 +1440,10 @@ struct boot_params *efi_main(struct efi_config *c, else setup_boot_services32(efi_early); + sanitize_boot_params(boot_params); + + boot_params->secure_boot = get_secure_boot(); + setup_graphics(boot_params); setup_efi_pci(boot_params); diff --git a/arch/x86/include/uapi/asm/bootparam.h b/arch/x86/include/uapi/asm/bootparam.h index ab456dc233b5..74ba4083e7ce 100644 --- a/arch/x86/include/uapi/asm/bootparam.h +++ b/arch/x86/include/uapi/asm/bootparam.h @@ -134,7 +134,8 @@ struct boot_params { __u8 eddbuf_entries; /* 0x1e9 */ __u8 edd_mbr_sig_buf_entries; /* 0x1ea */ __u8 kbd_status; /* 0x1eb */ - __u8 _pad5[3]; /* 0x1ec */ + __u8 secure_boot; /* 0x1ec */ + __u8 _pad5[2]; /* 0x1ed */ /* * The sentinel is set to a nonzero value (0xff) in header.S. * diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index d74ac33290ae..673ba9c92bdb 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -50,6 +50,7 @@ #include #include #include +#include #include #include @@ -1156,6 +1157,12 @@ void __init setup_arch(char **cmdline_p) io_delay_init(); +#ifdef CONFIG_EFI_SECURE_BOOT_SECURELEVEL + if (boot_params.secure_boot) { + set_securelevel(1); + } +#endif + /* * Parse the ACPI tables for possible boot-time SMP configuration. */ diff --git a/security/Kconfig b/security/Kconfig index 9542281b6e16..ccc0213d29cc 100644 --- a/security/Kconfig +++ b/security/Kconfig @@ -72,7 +72,7 @@ config SECURITY_PATH If you are unsure how to answer this question, answer N. config SECURITY_SECURELEVEL - bool "Securelevel kernel restriction interface" + bool "Securelevel kernel restriction interface" depends on SECURITY help This enables support for adding a set of additional kernel security -- 2.50.1