File 0009-efi-sb-Add-support-for-the-shim-loader-protocol.patch of Package grub2
From e1793f4388decaf58dc95c78c4b16fb6529b4b79 Mon Sep 17 00:00:00 2001
From: Mate Kukri <mate.kukri@canonical.com>
Date: Tue, 1 Apr 2025 11:26:42 +0100
Subject: [PATCH 09/13] efi/sb: Add support for the shim loader protocol
Use loader protocol for image verification where available, otherwise
fall back to the old shim lock protocol.
Signed-off-by: Mate Kukri <mate.kukri@canonical.com>
Link: https://lore.kernel.org/r/20250401102645.126390-3-mate.kukri@canonical.com
---
grub-core/kern/efi/sb.c | 58 ++++++++++++++++++++----------------
grub-core/loader/efi/linux.c | 6 ++--
include/grub/efi/api.h | 5 ++++
include/grub/efi/sb.h | 2 +-
4 files changed, 41 insertions(+), 30 deletions(-)
diff --git a/grub-core/kern/efi/sb.c b/grub-core/kern/efi/sb.c
index 8d3e413608..9c8811c987 100644
--- a/grub-core/kern/efi/sb.c
+++ b/grub-core/kern/efi/sb.c
@@ -31,8 +31,10 @@
#include <grub/verify.h>
static grub_guid_t shim_lock_guid = GRUB_EFI_SHIM_LOCK_GUID;
+static grub_guid_t shim_loader_guid = GRUB_EFI_SHIM_IMAGE_LOADER_GUID;
-static bool shim_lock_enabled = false;
+static grub_efi_loader_t *shim_loader = NULL;
+static grub_efi_shim_lock_protocol_t *shim_lock = NULL;
/*
* Determine whether we're in secure boot mode.
@@ -95,14 +97,6 @@ grub_efi_get_secureboot (void)
if (!(attr & GRUB_EFI_VARIABLE_RUNTIME_ACCESS) && *moksbstate == 1)
{
secureboot = GRUB_EFI_SECUREBOOT_MODE_DISABLED;
- /*
- * TODO: Replace this all with shim's LoadImage protocol, delegating policy to it.
- *
- * We need to set shim_lock_enabled here because we disabled secure boot
- * validation *inside* shim but not in the firmware, so we set this variable
- * here to trigger that code path, whereas the actual verifier is not enabled.
- */
- shim_lock_enabled = true;
goto out;
}
@@ -183,15 +177,24 @@ shim_lock_verifier_init (grub_file_t io __attribute__ ((unused)),
static grub_err_t
shim_lock_verifier_write (void *context __attribute__ ((unused)), void *buf, grub_size_t size)
{
- grub_efi_shim_lock_protocol_t *sl = grub_efi_locate_protocol (&shim_lock_guid, 0);
+ grub_efi_handle_t image_handle;
- if (!sl)
- return grub_error (GRUB_ERR_ACCESS_DENIED, N_("shim_lock protocol not found"));
+ if (shim_loader)
+ {
+
+ if (shim_loader->load_image (false, grub_efi_image_handle, NULL, buf, size, &image_handle) != GRUB_EFI_SUCCESS)
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad shim signature"));
- if (sl->verify (buf, size) != GRUB_EFI_SUCCESS)
- return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad shim signature"));
+ return GRUB_ERR_NONE;
+ }
+ if (shim_lock)
+ {
+ if (shim_lock->verify (buf, size) != GRUB_EFI_SUCCESS)
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad shim signature"));
+ return GRUB_ERR_NONE;
+ }
- return GRUB_ERR_NONE;
+ return grub_error (GRUB_ERR_ACCESS_DENIED, N_("shim protocols not found"));
}
struct grub_file_verifier shim_lock_verifier =
@@ -205,11 +208,17 @@ void
grub_shim_lock_verifier_setup (void)
{
struct grub_module_header *header;
- grub_efi_shim_lock_protocol_t *sl =
- grub_efi_locate_protocol (&shim_lock_guid, 0);
- /* shim_lock is missing, check if GRUB image is built with --disable-shim-lock. */
- if (!sl)
+ /* Secure Boot is off. Ignore shim. */
+ if (grub_efi_get_secureboot () != GRUB_EFI_SECUREBOOT_MODE_ENABLED)
+ return;
+
+ /* Find both shim protocols */
+ shim_loader = grub_efi_locate_protocol (&shim_loader_guid, 0);
+ shim_lock = grub_efi_locate_protocol (&shim_lock_guid, 0);
+
+ /* shim is missing, check if GRUB image is built with --disable-shim-lock. */
+ if (!shim_loader && !shim_lock)
{
FOR_MODULES (header)
{
@@ -218,21 +227,18 @@ grub_shim_lock_verifier_setup (void)
}
}
- /* Secure Boot is off. Do not load shim_lock. */
- if (grub_efi_get_secureboot () != GRUB_EFI_SECUREBOOT_MODE_ENABLED)
- return;
-
/* Enforce shim_lock_verifier. */
grub_verifier_register (&shim_lock_verifier);
- shim_lock_enabled = true;
+ /* Register shim loader if supported. */
+ grub_efi_register_loader (shim_loader);
grub_env_set ("shim_lock", "y");
grub_env_export ("shim_lock");
}
bool
-grub_is_shim_lock_enabled (void)
+grub_is_using_legacy_shim_lock_protocol (void)
{
- return shim_lock_enabled;
+ return !shim_loader && shim_lock;
}
diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
index 58be3c9f8b..993d18546d 100644
--- a/grub-core/loader/efi/linux.c
+++ b/grub-core/loader/efi/linux.c
@@ -460,10 +460,10 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
grub_dl_ref (my_mod);
- if (grub_is_shim_lock_enabled () == true)
+ if (grub_is_using_legacy_shim_lock_protocol () == true)
{
#if defined(__i386__) || defined(__x86_64__)
- grub_dprintf ("linux", "shim_lock enabled, falling back to legacy Linux kernel loader\n");
+ grub_dprintf ("linux", "using legacy shim_lock protocol, falling back to legacy Linux kernel loader\n");
err = grub_cmd_linux_x86_legacy (cmd, argc, argv);
@@ -472,7 +472,7 @@ 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", "using legacy shim_lock protocol on non-x86, only db verifiable kernels will work\n");
#endif
}
diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
index 5d1aada34a..72017eaa72 100644
--- a/include/grub/efi/api.h
+++ b/include/grub/efi/api.h
@@ -364,6 +364,11 @@
{ 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 } \
}
+#define GRUB_EFI_SHIM_IMAGE_LOADER_GUID \
+ { 0x1f492041, 0xfadb, 0x4e59, \
+ {0x9e, 0x57, 0x7c, 0xaf, 0xe7, 0x3a, 0x55, 0xab } \
+ }
+
#define GRUB_EFI_RNG_PROTOCOL_GUID \
{ 0x3152bca5, 0xeade, 0x433d, \
{ 0x86, 0x2e, 0xc0, 0x1c, 0xdc, 0x29, 0x1f, 0x44 } \
diff --git a/include/grub/efi/sb.h b/include/grub/efi/sb.h
index 49a9ad01cc..4cae883769 100644
--- a/include/grub/efi/sb.h
+++ b/include/grub/efi/sb.h
@@ -32,7 +32,7 @@ extern grub_uint8_t
EXPORT_FUNC (grub_efi_get_secureboot) (void);
extern bool
-EXPORT_FUNC (grub_is_shim_lock_enabled) (void);
+EXPORT_FUNC (grub_is_using_legacy_shim_lock_protocol) (void);
extern void
grub_shim_lock_verifier_setup (void);
--
2.49.0