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