aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArd Biesheuvel <ardb@kernel.org>2023-06-30 22:24:14 +0200
committerArd Biesheuvel <ardb@kernel.org>2023-06-30 22:24:14 +0200
commitfdcac7b0e5a73e21823c5d553144025756289632 (patch)
tree379288d5a065e433439979f41075f7bcf900484e
parent9f7a47ba2263ab0de5f7b57edac95187c5767e7c (diff)
downloadgrub-shim-loader-protocol.tar.gz
efi: Prefer shim image loader protocol if it existsshim-loader-protocol
shim has all the facilities to load and authenticate PE images against MOK or the system firmware's cert store, but only exposes its verification routine via the shim lock protocol, leaving it to loaders such as GRUB to implement PE loading from scratch when booting Linux via its EFI stub. Now that shim exposes load/startimage equivalents, let's use these and boot in EFI mode in cases where shim is active. Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
-rw-r--r--grub-core/loader/efi/linux.c21
-rw-r--r--include/grub/efi/api.h31
2 files changed, 47 insertions, 5 deletions
diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
index fb4d12e3f..99921537b 100644
--- a/grub-core/loader/efi/linux.c
+++ b/grub-core/loader/efi/linux.c
@@ -54,6 +54,9 @@ static bool initrd_use_loadfile2 = false;
static grub_guid_t load_file2_guid = GRUB_EFI_LOAD_FILE2_PROTOCOL_GUID;
static grub_guid_t device_path_guid = GRUB_EFI_DEVICE_PATH_GUID;
+static grub_guid_t shim_image_loader_guid = GRUB_SHIM_IMAGE_LOADER_GUID;
+
+static grub_efi_shim_image_loader_protocol_t *shim_image_loader = NULL;
static initrd_media_device_path_t initrd_lf2_device_path = {
{
@@ -184,7 +187,7 @@ grub_arch_efi_linux_boot_image (grub_addr_t addr, grub_size_t size, char *args)
{
grub_efi_memory_mapped_device_path_t *mempath;
grub_efi_handle_t image_handle;
- grub_efi_boot_services_t *b;
+ grub_efi_shim_image_loader_protocol_t *b;
grub_efi_status_t status;
grub_efi_loaded_image_t *loaded_image;
int len;
@@ -204,7 +207,7 @@ grub_arch_efi_linux_boot_image (grub_addr_t addr, grub_size_t size, char *args)
mempath[1].header.subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
mempath[1].header.length = sizeof (grub_efi_device_path_t);
- b = grub_efi_system_table->boot_services;
+ b = shim_image_loader;
status = b->load_image (0, grub_efi_image_handle,
(grub_efi_device_path_t *) mempath,
(void *) addr, size, &image_handle);
@@ -459,10 +462,12 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
grub_dl_ref (my_mod);
- if (grub_is_shim_lock_enabled () == true)
+ shim_image_loader = grub_efi_locate_protocol (&shim_image_loader_guid, 0);
+
+ if (grub_is_shim_lock_enabled () == true && shim_image_loader == NULL)
{
#if defined(__i386__) || defined(__x86_64__)
- grub_dprintf ("linux", "shim_lock enabled, falling back to legacy Linux kernel loader\n");
+ grub_dprintf ("linux", "shim_lock enabled but no shim image loader installed, falling back to legacy Linux kernel loader\n");
err = grub_cmd_linux_x86_legacy (cmd, argc, argv);
@@ -471,10 +476,16 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
else
goto fail;
#else
- grub_dprintf ("linux", "shim_lock enabled, trying Linux kernel EFI stub loader\n");
+ grub_dprintf ("linux", "shim_lock enabled but no shim image loader installed, trying Linux kernel EFI stub loader\n");
#endif
}
+ if (shim_image_loader == NULL)
+ {
+ shim_image_loader =
+ (grub_efi_shim_image_loader_protocol_t *)&grub_efi_system_table->boot_services->load_image;
+ }
+
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 f3c50ed5d..309433796 100644
--- a/include/grub/efi/api.h
+++ b/include/grub/efi/api.h
@@ -379,6 +379,11 @@
{0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f } \
}
+#define GRUB_SHIM_IMAGE_LOADER_GUID \
+ { 0x1f492041, 0xfadb, 0x4e59, \
+ { 0x9e, 0x57, 0x7c, 0xaf, 0xe7, 0x3a, 0x55, 0xab } \
+ }
+
struct grub_efi_sal_system_table
{
grub_uint32_t signature;
@@ -1781,6 +1786,32 @@ struct grub_efi_shim_lock_protocol
};
typedef struct grub_efi_shim_lock_protocol grub_efi_shim_lock_protocol_t;
+struct grub_efi_shim_image_loader_protocol
+{
+ 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_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_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);
+};
+typedef struct grub_efi_shim_image_loader_protocol grub_efi_shim_image_loader_protocol_t;
+
typedef grub_guid_t grub_efi_rng_algorithm_t;
struct grub_efi_rng_protocol