From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Mate Kukri Date: Wed, 12 Jun 2024 16:57:12 +0100 Subject: [PATCH] efi: Use shim's loader protocol for EFI image verification and loading Signed-off-by: Mate Kukri --- grub-core/kern/efi/sb.c | 39 ++++++++++++++------------------------- grub-core/loader/efi/linux.c | 16 ---------------- include/grub/efi/api.h | 5 +++++ include/grub/efi/efi.h | 19 ++++++++++++------- include/grub/efi/sb.h | 3 --- 5 files changed, 31 insertions(+), 51 deletions(-) diff --git a/grub-core/kern/efi/sb.c b/grub-core/kern/efi/sb.c index 8d3e413608b..d3de3959989 100644 --- a/grub-core/kern/efi/sb.c +++ b/grub-core/kern/efi/sb.c @@ -31,8 +31,9 @@ #include static grub_guid_t shim_lock_guid = GRUB_EFI_SHIM_LOCK_GUID; +static grub_guid_t shim_loader_guid = GRUB_EFI_SHIM_IMAGE_LOADER_GUID; -static bool shim_lock_enabled = false; +static grub_efi_loader_t *shim_loader = NULL; /* * Determine whether we're in secure boot mode. @@ -95,14 +96,6 @@ grub_efi_get_secureboot (void) if (!(attr & GRUB_EFI_VARIABLE_RUNTIME_ACCESS) && *moksbstate == 1) { secureboot = GRUB_EFI_SECUREBOOT_MODE_DISABLED; - /* - * TODO: Replace this all with shim's LoadImage protocol, delegating policy to it. - * - * We need to set shim_lock_enabled here because we disabled secure boot - * validation *inside* shim but not in the firmware, so we set this variable - * here to trigger that code path, whereas the actual verifier is not enabled. - */ - shim_lock_enabled = true; goto out; } @@ -183,14 +176,16 @@ shim_lock_verifier_init (grub_file_t io __attribute__ ((unused)), static grub_err_t shim_lock_verifier_write (void *context __attribute__ ((unused)), void *buf, grub_size_t size) { - grub_efi_shim_lock_protocol_t *sl = grub_efi_locate_protocol (&shim_lock_guid, 0); + grub_efi_handle_t image_handle; - if (!sl) - return grub_error (GRUB_ERR_ACCESS_DENIED, N_("shim_lock protocol not found")); + if (!shim_loader) + return grub_error (GRUB_ERR_ACCESS_DENIED, N_("shim loader protocol not found")); - if (sl->verify (buf, size) != GRUB_EFI_SUCCESS) + if (shim_loader->load_image (false, grub_efi_image_handle, NULL, buf, size, &image_handle) != GRUB_EFI_SUCCESS) return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad shim signature")); + shim_loader->unload_image(image_handle); + return GRUB_ERR_NONE; } @@ -205,11 +200,10 @@ void grub_shim_lock_verifier_setup (void) { struct grub_module_header *header; - grub_efi_shim_lock_protocol_t *sl = - grub_efi_locate_protocol (&shim_lock_guid, 0); + shim_loader = grub_efi_locate_protocol (&shim_loader_guid, 0); - /* shim_lock is missing, check if GRUB image is built with --disable-shim-lock. */ - if (!sl) + /* shim loader protocol is missing, check if GRUB image is built with --disable-shim-lock. */ + if (!shim_loader) { FOR_MODULES (header) { @@ -222,17 +216,12 @@ grub_shim_lock_verifier_setup (void) if (grub_efi_get_secureboot () != GRUB_EFI_SECUREBOOT_MODE_ENABLED) return; + /* register loader */ + grub_efi_register_loader(shim_loader); + /* Enforce shim_lock_verifier. */ grub_verifier_register (&shim_lock_verifier); - shim_lock_enabled = true; - grub_env_set ("shim_lock", "y"); grub_env_export ("shim_lock"); } - -bool -grub_is_shim_lock_enabled (void) -{ - return shim_lock_enabled; -} diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c index fe48001442a..da5dcafad8b 100644 --- a/grub-core/loader/efi/linux.c +++ b/grub-core/loader/efi/linux.c @@ -727,22 +727,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), grub_dl_ref (my_mod); - if (grub_is_shim_lock_enabled () == true) - { -#if defined(__i386__) || defined(__x86_64__) - grub_dprintf ("linux", "shim_lock enabled, falling back to legacy Linux kernel loader\n"); - - err = grub_cmd_linux_x86_legacy (cmd, argc, argv); - - if (err == GRUB_ERR_NONE) - return GRUB_ERR_NONE; - else - goto fail; -#else - grub_dprintf ("linux", "shim_lock enabled, trying Linux kernel EFI stub loader\n"); -#endif - } - if (argc == 0) { grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h index 76c88fbdcb0..da51f57fd4a 100644 --- a/include/grub/efi/api.h +++ b/include/grub/efi/api.h @@ -364,6 +364,11 @@ { 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 } \ } +#define GRUB_EFI_SHIM_IMAGE_LOADER_GUID \ + { 0x1f492041, 0xfadb, 0x4e59, \ + {0x9e, 0x57, 0x7c, 0xaf, 0xe7, 0x3a, 0x55, 0xab } \ + } + #define GRUB_EFI_RNG_PROTOCOL_GUID \ { 0x3152bca5, 0xeade, 0x433d, \ { 0x86, 0x2e, 0xc0, 0x1c, 0xdc, 0x29, 0x1f, 0x44 } \ diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h index 7eed1bd791d..77d067977f6 100644 --- a/include/grub/efi/efi.h +++ b/include/grub/efi/efi.h @@ -220,15 +220,20 @@ EXPORT_FUNC (grub_efi_unload_image) (grub_efi_handle_t image_handle); typedef struct grub_efi_loader { grub_efi_status_t (__grub_efi_api *load_image) (grub_efi_boolean_t boot_policy, - grub_efi_handle_t parent_image_handle, - grub_efi_device_path_t *file_path, - void *source_buffer, - grub_efi_uintn_t source_size, - grub_efi_handle_t *image_handle); + grub_efi_handle_t parent_image_handle, + grub_efi_device_path_t *file_path, + void *source_buffer, + grub_efi_uintn_t source_size, + grub_efi_handle_t *image_handle); grub_efi_status_t (__grub_efi_api *start_image) (grub_efi_handle_t image_handle, - grub_efi_uintn_t *exit_data_size, - grub_efi_char16_t **exit_data); + grub_efi_uintn_t *exit_data_size, + grub_efi_char16_t **exit_data); + + grub_efi_status_t (__grub_efi_api *exit) (grub_efi_handle_t image_handle, + grub_efi_status_t exit_status, + grub_efi_uintn_t exit_data_size, + grub_efi_char16_t *exit_data); grub_efi_status_t (__grub_efi_api *unload_image) (grub_efi_handle_t image_handle); } grub_efi_loader_t; diff --git a/include/grub/efi/sb.h b/include/grub/efi/sb.h index 49a9ad01cc9..bf8d2db5ff2 100644 --- a/include/grub/efi/sb.h +++ b/include/grub/efi/sb.h @@ -31,9 +31,6 @@ extern grub_uint8_t EXPORT_FUNC (grub_efi_get_secureboot) (void); -extern bool -EXPORT_FUNC (grub_is_shim_lock_enabled) (void); - extern void grub_shim_lock_verifier_setup (void); #else