dcavalca / rpms / grub2

Forked from rpms/grub2 3 years ago
Clone

Blame SOURCES/0276-efi-Set-image-base-address-before-jumping-to-the-PE-.patch

c294fc
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
c294fc
From: Javier Martinez Canillas <javierm@redhat.com>
c294fc
Date: Thu, 23 Apr 2020 15:06:46 +0200
c294fc
Subject: [PATCH] efi: Set image base address before jumping to the PE/COFF
c294fc
 entry point
c294fc
c294fc
Upstream GRUB uses the EFI LoadImage() and StartImage() to boot the Linux
c294fc
kernel. But our custom EFI loader that supports Secure Boot instead uses
c294fc
the EFI handover protocol (for x86) or jumping directly to the PE/COFF
c294fc
entry point (for aarch64).
c294fc
c294fc
This is done to allow the bootloader to verify the images using the shim
c294fc
lock protocol to avoid booting untrusted binaries.
c294fc
c294fc
Since the bootloader loads the kernel from the boot media instead of using
c294fc
LoadImage(), it is responsible to set the Loaded Image base address before
c294fc
booting the kernel.
c294fc
c294fc
Otherwise the kernel EFI stub will complain that it was not set correctly
c294fc
and print the following warning message:
c294fc
c294fc
EFI stub: ERROR: FIRMWARE BUG: efi_loaded_image_t::image_base has bogus value
c294fc
c294fc
Resolves: rhbz#1819624
c294fc
c294fc
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
c294fc
---
c294fc
 grub-core/loader/efi/linux.c | 12 ++++++++++++
c294fc
 1 file changed, 12 insertions(+)
c294fc
c294fc
diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
c294fc
index b56ea0bc041..e09f824862b 100644
c294fc
--- a/grub-core/loader/efi/linux.c
c294fc
+++ b/grub-core/loader/efi/linux.c
c294fc
@@ -72,6 +72,7 @@ grub_err_t
c294fc
 grub_efi_linux_boot (void *kernel_addr, grub_off_t handover_offset,
c294fc
 		     void *kernel_params)
c294fc
 {
c294fc
+  grub_efi_loaded_image_t *loaded_image = NULL;
c294fc
   handover_func hf;
c294fc
   int offset = 0;
c294fc
 
c294fc
@@ -79,6 +80,17 @@ grub_efi_linux_boot (void *kernel_addr, grub_off_t handover_offset,
c294fc
   offset = 512;
c294fc
 #endif
c294fc
 
c294fc
+  /*
c294fc
+   * Since the EFI loader is not calling the LoadImage() and StartImage()
c294fc
+   * services for loading the kernel and booting respectively, it has to
c294fc
+   * set the Loaded Image base address.
c294fc
+   */
c294fc
+  loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle);
c294fc
+  if (loaded_image)
c294fc
+    loaded_image->image_base = kernel_addr;
c294fc
+  else
c294fc
+    grub_dprintf ("linux", "Loaded Image base address could not be set\n");
c294fc
+
c294fc
   grub_dprintf ("linux", "kernel_addr: %p handover_offset: %p params: %p\n",
c294fc
 		kernel_addr, (void *)(grub_efi_uintn_t)handover_offset, kernel_params);
c294fc
   hf = (handover_func)((char *)kernel_addr + handover_offset + offset);