efi: Get and store the secure boot status
Get the firmware's secure-boot status in the kernel boot wrapper and stash it somewhere that the main kernel image can find. The efi_get_secureboot() function is extracted from the ARM stub and (a) generalised so that it can be called from x86 and (b) made to use efi_call_runtime() so that it can be run in mixed-mode. For x86, it is stored in boot_params and can be overridden by the boot loader or kexec. This allows secure-boot mode to be passed on to a new kernel. Suggested-by: Lukas Wunner <lukas@wunner.de> Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Matt Fleming <matt@codeblueprint.co.uk> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: linux-efi@vger.kernel.org Link: http://lkml.kernel.org/r/1486380166-31868-5-git-send-email-ard.biesheuvel@linaro.org [ Small readability edits. ] Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:

committed by
Ingo Molnar

parent
e58910cdc9
commit
de8cb45862
@@ -20,52 +20,6 @@
|
||||
|
||||
bool __nokaslr;
|
||||
|
||||
static 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 };
|
||||
static efi_char16_t const sm_var_name[] = {
|
||||
'S', 'e', 't', 'u', 'p', 'M', 'o', 'd', 'e', 0 };
|
||||
|
||||
efi_guid_t var_guid = EFI_GLOBAL_VARIABLE_GUID;
|
||||
efi_get_variable_t *f_getvar = sys_table_arg->runtime->get_variable;
|
||||
u8 val;
|
||||
unsigned long size = sizeof(val);
|
||||
efi_status_t status;
|
||||
|
||||
status = f_getvar((efi_char16_t *)sb_var_name, (efi_guid_t *)&var_guid,
|
||||
NULL, &size, &val);
|
||||
|
||||
if (status != EFI_SUCCESS)
|
||||
goto out_efi_err;
|
||||
|
||||
if (val == 0)
|
||||
return 0;
|
||||
|
||||
status = f_getvar((efi_char16_t *)sm_var_name, (efi_guid_t *)&var_guid,
|
||||
NULL, &size, &val);
|
||||
|
||||
if (status != EFI_SUCCESS)
|
||||
goto out_efi_err;
|
||||
|
||||
if (val == 1)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
|
||||
out_efi_err:
|
||||
switch (status) {
|
||||
case EFI_NOT_FOUND:
|
||||
return 0;
|
||||
case EFI_DEVICE_ERROR:
|
||||
return -EIO;
|
||||
case EFI_SECURITY_VIOLATION:
|
||||
return -EACCES;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
efi_status_t efi_open_volume(efi_system_table_t *sys_table_arg,
|
||||
void *__image, void **__fh)
|
||||
{
|
||||
@@ -157,7 +111,7 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table,
|
||||
efi_guid_t loaded_image_proto = LOADED_IMAGE_PROTOCOL_GUID;
|
||||
unsigned long reserve_addr = 0;
|
||||
unsigned long reserve_size = 0;
|
||||
int secure_boot = 0;
|
||||
enum efi_secureboot_mode secure_boot;
|
||||
struct screen_info *si;
|
||||
|
||||
/* Check if we were booted by the EFI firmware */
|
||||
@@ -227,19 +181,14 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table,
|
||||
pr_efi_err(sys_table, "Failed to parse EFI cmdline options\n");
|
||||
|
||||
secure_boot = efi_get_secureboot(sys_table);
|
||||
if (secure_boot > 0)
|
||||
pr_efi(sys_table, "UEFI Secure Boot is enabled.\n");
|
||||
|
||||
if (secure_boot < 0) {
|
||||
pr_efi_err(sys_table,
|
||||
"could not determine UEFI Secure Boot status.\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Unauthenticated device tree data is a security hazard, so
|
||||
* ignore 'dtb=' unless UEFI Secure Boot is disabled.
|
||||
* Unauthenticated device tree data is a security hazard, so ignore
|
||||
* 'dtb=' unless UEFI Secure Boot is disabled. We assume that secure
|
||||
* boot is enabled if we can't determine its state.
|
||||
*/
|
||||
if (secure_boot != 0 && strstr(cmdline_ptr, "dtb=")) {
|
||||
if (secure_boot != efi_secureboot_mode_disabled &&
|
||||
strstr(cmdline_ptr, "dtb=")) {
|
||||
pr_efi(sys_table, "Ignoring DTB from command line.\n");
|
||||
} else {
|
||||
status = handle_cmdline_files(sys_table, image, cmdline_ptr,
|
||||
|
Reference in New Issue
Block a user