]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
efi/sb: Add API for retrieving shim loader image handles
authorMate Kukri <mate.kukri@canonical.com>
Tue, 8 Jul 2025 20:21:15 +0000 (21:21 +0100)
committerDaniel Kiper <daniel.kiper@oracle.com>
Fri, 11 Jul 2025 15:46:19 +0000 (17:46 +0200)
Not reusing these handles will result in image measurements showing up
twice in the event log.

Signed-off-by: Mate Kukri <mate.kukri@canonical.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
grub-core/kern/efi/sb.c
include/grub/efi/sb.h

index 48d1ea9683d81d3b40f4bbe8e12543d64541dc5f..4409e03c519446f01b1bd8dce7309ca775eb2892 100644 (file)
@@ -36,6 +36,8 @@ static grub_guid_t shim_loader_guid = GRUB_EFI_SHIM_IMAGE_LOADER_GUID;
 static grub_efi_loader_t *shim_loader = NULL;
 static grub_efi_shim_lock_protocol_t *shim_lock = NULL;
 
+static grub_efi_handle_t last_verified_image_handle = NULL;
+
 /*
  * Determine whether we're in secure boot mode.
  *
@@ -181,11 +183,25 @@ shim_lock_verifier_write (void *context __attribute__ ((unused)), void *buf, gru
 
   if (shim_loader != NULL)
     {
+      if (last_verified_image_handle != NULL)
+        {
+          /*
+          * Unload the previous image because ownership of the handle was
+          * not transfered to a loader, and a new image is being loaded.
+          */
+          shim_loader->unload_image (last_verified_image_handle);
+          last_verified_image_handle = NULL;
+        }
+
       if (shim_loader->load_image (false, grub_efi_image_handle, NULL, buf, size, &image_handle) != GRUB_EFI_SUCCESS)
-       /* If verification fails no handle is produced */
+       /* If verification fails no handle is produced. */
         return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad shim loader signature"));
 
-      shim_loader->unload_image (image_handle);
+      /*
+       * Not unloading the image here because chainloader and linux
+       * might use this handle to avoid double TPM measurements.
+       */
+      last_verified_image_handle = image_handle;
       return GRUB_ERR_NONE;
     }
   if (shim_lock != NULL)
@@ -243,3 +259,17 @@ grub_is_using_legacy_shim_lock_protocol (void)
 {
   return (shim_loader == NULL && shim_lock != NULL) ? true : false;
 }
+
+grub_efi_handle_t
+grub_efi_get_last_verified_image_handle (void)
+{
+  grub_efi_handle_t tmp = last_verified_image_handle;
+
+  /*
+   * This function is intended to act as a "transfer of ownership"
+   * of the handle. We set it to NULL so that it cannot be buggily
+   * retrieved more than once and reused for the wrong image.
+   */
+  last_verified_image_handle = NULL;
+  return tmp;
+}
index 4cae883769455c83db9ff61dc01921a472683b19..149005ced3f8762b7ba4c0fe44988cb9635dd48c 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <grub/types.h>
 #include <grub/dl.h>
+#include <grub/efi/api.h>
 
 #define GRUB_EFI_SECUREBOOT_MODE_UNSET         0
 #define GRUB_EFI_SECUREBOOT_MODE_UNKNOWN       1
@@ -34,6 +35,9 @@ EXPORT_FUNC (grub_efi_get_secureboot) (void);
 extern bool
 EXPORT_FUNC (grub_is_using_legacy_shim_lock_protocol) (void);
 
+extern grub_efi_handle_t
+EXPORT_FUNC (grub_efi_get_last_verified_image_handle) (void);
+
 extern void
 grub_shim_lock_verifier_setup (void);
 #else