From 5d5f5231b008fa5e6299a76f9ae92a6da035c4f0 Mon Sep 17 00:00:00 2001 From: Ricardo Neri Date: Fri, 27 Mar 2015 08:26:08 -0700 Subject: [PATCH] efi: chainloader: use shim to load and verify an image Upstream-Status: Inappropriate [embedded specific] The grub chainloader module uses the UEFI LoadImage service to load a chainloaded binary. However, if such binary is not signed by the UEFI certification authority, LoadImage will fail. Under shim, we can use Machine-Owned Keys (MOKs) to verify an image. Thus, in case LoadImage fails due to a security violation we rely on the shim verification service. If successful, the image is parsed and loaded. Signed-off-by: Ricardo Neri --- grub-core/loader/efi/chainloader.c | 49 ++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c index d192e2d..121af25 100644 --- a/grub-core/loader/efi/chainloader.c +++ b/grub-core/loader/efi/chainloader.c @@ -761,6 +761,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), char *filename; void *boot_image = 0; grub_efi_handle_t dev_handle = 0; + struct grub_shim_pe_coff_loader_image_context context; if (argc == 0) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); @@ -892,23 +893,53 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), if (status != GRUB_EFI_SUCCESS) { if (status == GRUB_EFI_OUT_OF_RESOURCES) - grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of resources"); + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of resources"); + goto fail; + } + /* try with shim */ + else if (status == GRUB_EFI_SECURITY_VIOLATION) + { + status = grub_shim_load_image (address, size, &context); + if (status != GRUB_EFI_SUCCESS) + { + grub_error (GRUB_ERR_BAD_OS, "shim cannot load image"); + goto fail; + } + } else - grub_error (GRUB_ERR_BAD_OS, "cannot load image"); - - goto fail; + { + grub_error (GRUB_ERR_BAD_OS, "cannot load image"); + goto fail; + } } - /* LoadImage does not set a device handler when the image is - loaded from memory, so it is necessary to set it explicitly here. - This is a mess. */ - loaded_image = grub_efi_get_loaded_image (image_handle); + /* if we use shim, the UEFI load_image failed, thus, we borrow + * grub_efi_image_handle and restore it later + */ + if (shim_used) + /* if we use shim, the UEFI load_image failed, thus, we borrow + grub_efi_image_handle and restore it later */ + loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle); + else + /* LoadImage does not set a device handler when the image is + loaded from memory, so it is necessary to set it explicitly here. + This is a mess. */ + loaded_image = grub_efi_get_loaded_image (image_handle); + if (! loaded_image) { grub_error (GRUB_ERR_BAD_OS, "no loaded image available"); goto fail; } - loaded_image->device_handle = dev_handle; + if (shim_used) + { + grub_memcpy(&shim_li_bak, loaded_image, sizeof(shim_li_bak)); + loaded_image->image_base = (void *)shim_buffer; + loaded_image->image_size = context.image_size; + } + else + loaded_image->device_handle = dev_handle; if (argc > 1) { -- 2.17.1