Otherwise the kernel does not know its state and cannot enable various security features depending on UEFI Secure Boot.
Signed-off-by: Ignat Korchagin <ig...@cloudflare.com> Signed-off-by: Daniel Kiper <daniel.ki...@oracle.com> --- grub-core/loader/i386/linux.c | 86 ++++++++++++++++++++++++++++++++++++++++++- include/grub/i386/linux.h | 14 ++++++- 2 files changed, 97 insertions(+), 3 deletions(-) diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c index ac1fae72e..952eb1191 100644 --- a/grub-core/loader/i386/linux.c +++ b/grub-core/loader/i386/linux.c @@ -397,6 +397,87 @@ grub_linux_boot_mmap_fill (grub_uint64_t addr, grub_uint64_t size, return 0; } +#ifdef GRUB_MACHINE_EFI +/* + * Determine whether we're in secure boot mode. + * + * Please keep the logic in sync with the Linux kernel, + * drivers/firmware/efi/libstub/secureboot.c:efi_get_secureboot(). + */ +static grub_uint8_t +grub_efi_get_secureboot (void) +{ + grub_efi_guid_t efi_variable_guid = GRUB_EFI_GLOBAL_VARIABLE_GUID; + grub_efi_guid_t efi_shim_lock_guid = GRUB_EFI_SHIM_LOCK_GUID; + grub_efi_status_t status; + grub_efi_uint32_t attr = 0; + grub_size_t size = 0; + grub_uint8_t *secboot = NULL; + grub_uint8_t *setupmode = NULL; + grub_uint8_t *moksbstate = NULL; + grub_uint8_t secureboot = GRUB_LINUX_EFI_SECUREBOOT_MODE_UNKNOWN; + const char *secureboot_str = "UNKNOWN"; + + status = grub_efi_get_variable ("SecureBoot", &efi_variable_guid, + &size, (void **) &secboot); + + if (status == GRUB_EFI_NOT_FOUND) + { + secureboot = GRUB_LINUX_EFI_SECUREBOOT_MODE_DISABLED; + goto out; + } + + if (status != GRUB_EFI_SUCCESS) + goto out; + + status = grub_efi_get_variable ("SetupMode", &efi_variable_guid, + &size, (void **) &setupmode); + + if (status != GRUB_EFI_SUCCESS) + goto out; + + if ((*secboot == 0) || (*setupmode == 1)) + { + secureboot = GRUB_LINUX_EFI_SECUREBOOT_MODE_DISABLED; + goto out; + } + + /* + * See if a user has put the shim into insecure mode. If so, and if the + * variable doesn't have the runtime attribute set, we might as well + * honor that. + */ + status = grub_efi_get_variable_with_attributes ("MokSBState", &efi_shim_lock_guid, + &size, (void **) &moksbstate, &attr); + + /* If it fails, we don't care why. Default to secure. */ + if (status != GRUB_EFI_SUCCESS) + { + secureboot = GRUB_LINUX_EFI_SECUREBOOT_MODE_ENABLED; + goto out; + } + + if (!(attr & GRUB_EFI_VARIABLE_RUNTIME_ACCESS) && *moksbstate == 1) + secureboot = GRUB_LINUX_EFI_SECUREBOOT_MODE_DISABLED; + + secureboot = GRUB_LINUX_EFI_SECUREBOOT_MODE_ENABLED; + + out: + grub_free (moksbstate); + grub_free (setupmode); + grub_free (secboot); + + if (secureboot == GRUB_LINUX_EFI_SECUREBOOT_MODE_DISABLED) + secureboot_str = "Disabled"; + else if (secureboot == GRUB_LINUX_EFI_SECUREBOOT_MODE_ENABLED) + secureboot_str = "Enabled"; + + grub_dprintf ("linux", "UEFI Secure Boot state: %s\n", secureboot_str); + + return secureboot; +} +#endif + static grub_err_t grub_linux_boot (void) { @@ -579,6 +660,9 @@ grub_linux_boot (void) grub_efi_uintn_t efi_desc_size; grub_size_t efi_mmap_target; grub_efi_uint32_t efi_desc_version; + + ctx.params->secure_boot = grub_efi_get_secureboot (); + err = grub_efi_finish_boot_services (&efi_mmap_size, efi_mmap_buf, NULL, &efi_desc_size, &efi_desc_version); if (err) @@ -790,7 +874,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), linux_params.code32_start = prot_mode_target + lh.code32_start - GRUB_LINUX_BZIMAGE_ADDR; linux_params.kernel_alignment = (1 << align); - linux_params.ps_mouse = linux_params.padding10 = 0; + linux_params.ps_mouse = linux_params.padding11 = 0; linux_params.type_of_loader = GRUB_LINUX_BOOT_LOADER_TYPE; /* These two are used (instead of cmd_line_ptr) by older versions of Linux, diff --git a/include/grub/i386/linux.h b/include/grub/i386/linux.h index ce30e7fb0..6aea73ddb 100644 --- a/include/grub/i386/linux.h +++ b/include/grub/i386/linux.h @@ -49,6 +49,12 @@ /* Maximum number of MBR signatures to store. */ #define EDD_MBR_SIG_MAX 16 +/* Possible values for Linux secure_boot kernel parameter. */ +#define GRUB_LINUX_EFI_SECUREBOOT_MODE_UNSET 0 +#define GRUB_LINUX_EFI_SECUREBOOT_MODE_UNKNOWN 1 +#define GRUB_LINUX_EFI_SECUREBOOT_MODE_DISABLED 2 +#define GRUB_LINUX_EFI_SECUREBOOT_MODE_ENABLED 3 + #ifdef __x86_64__ #define GRUB_LINUX_EFI_SIGNATURE \ @@ -275,7 +281,11 @@ struct linux_kernel_params grub_uint8_t mmap_size; /* 1e8 */ - grub_uint8_t padding9[0x1f1 - 0x1e9]; + grub_uint8_t padding9[0x1ec - 0x1e9]; + + grub_uint8_t secure_boot; /* 1ec */ + + grub_uint8_t padding10[0x1f1 - 0x1ed]; /* Linux setup header copy - BEGIN. */ grub_uint8_t setup_sects; /* The size of the setup in sectors */ @@ -286,7 +296,7 @@ struct linux_kernel_params grub_uint16_t vid_mode; /* Video mode control */ grub_uint16_t root_dev; /* Default root device number */ - grub_uint8_t padding10; /* 1fe */ + grub_uint8_t padding11; /* 1fe */ grub_uint8_t ps_mouse; /* 1ff */ grub_uint16_t jump; /* Jump instruction */ -- 2.11.0 _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel