]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
efi: Move the shim_lock verifier to the GRUB core
authorMarco A Benatto <mbenatto@redhat.com>
Wed, 23 Sep 2020 18:21:14 +0000 (14:21 -0400)
committerDaniel Kiper <daniel.kiper@oracle.com>
Tue, 2 Mar 2021 14:54:15 +0000 (15:54 +0100)
Move the shim_lock verifier from its own module into the core image. The
Secure Boot lockdown mechanism has the intent to prevent the load of any
unsigned code or binary when Secure Boot is enabled.

The reason is that GRUB must be able to prevent executing untrusted code
if UEFI Secure Boot is enabled, without depending on external modules.

Signed-off-by: Marco A Benatto <mbenatto@redhat.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
docs/grub.texi
grub-core/Makefile.core.def
grub-core/commands/efi/shim_lock.c [deleted file]
grub-core/kern/efi/init.c
grub-core/kern/efi/sb.c
include/grub/efi/sb.h

index eeac9b2ce0fc88c97885c38d315780b6172488d9..e3de2a4dc554b6a49bcfd52b12711c0499ca4b6c 100644 (file)
@@ -5910,15 +5910,16 @@ secure boot chain.
 @section UEFI secure boot and shim support
 
 The GRUB, except the @command{chainloader} command, works with the UEFI secure
-boot and the shim. This functionality is provided by the shim_lock module. It
-is recommend to build in this and other required modules into the @file{core.img}.
+boot and the shim. This functionality is provided by the shim_lock verifier. It
+is built into the @file{core.img} and is registered if the UEFI secure boot is
+enabled.
+
 All modules not stored in the @file{core.img} and the ACPI tables for the
 @command{acpi} command have to be signed, e.g. using PGP. Additionally, the
 @command{iorw}, the @command{memrw} and the @command{wrmsr} commands are
 prohibited if the UEFI secure boot is enabled. This is done due to
 security reasons. All above mentioned requirements are enforced by the
-shim_lock module. And itself it is a persistent module which means that
-it cannot be unloaded if it was loaded into the memory.
+shim_lock verifier logic.
 
 @node Measured Boot
 @section Measuring boot components
index 0cecc3875cef19ac035171867078a848840d6a55..2b98fe1fc411cb7d22bda0ee9489c5cbec29c0ca 100644 (file)
@@ -944,12 +944,6 @@ module = {
   cppflags = '-I$(srcdir)/lib/posix_wrap';
 };
 
-module = {
-  name = shim_lock;
-  common = commands/efi/shim_lock.c;
-  enable = efi;
-};
-
 module = {
   name = hdparm;
   common = commands/hdparm.c;
diff --git a/grub-core/commands/efi/shim_lock.c b/grub-core/commands/efi/shim_lock.c
deleted file mode 100644 (file)
index f7f3109..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2017  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- *
- *  EFI shim lock verifier.
- */
-
-#include <grub/dl.h>
-#include <grub/efi/efi.h>
-#include <grub/efi/sb.h>
-#include <grub/err.h>
-#include <grub/file.h>
-#include <grub/misc.h>
-#include <grub/verify.h>
-
-GRUB_MOD_LICENSE ("GPLv3+");
-
-static grub_efi_guid_t shim_lock_guid = GRUB_EFI_SHIM_LOCK_GUID;
-
-/* List of modules which cannot be loaded if UEFI secure boot mode is enabled. */
-static const char * const disabled_mods[] = {"iorw", "memrw", "wrmsr", NULL};
-
-static grub_err_t
-shim_lock_init (grub_file_t io, enum grub_file_type type,
-               void **context __attribute__ ((unused)),
-               enum grub_verify_flags *flags)
-{
-  const char *b, *e;
-  int i;
-
-  *flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION;
-
-  switch (type & GRUB_FILE_TYPE_MASK)
-    {
-    case GRUB_FILE_TYPE_GRUB_MODULE:
-      /* Establish GRUB module name. */
-      b = grub_strrchr (io->name, '/');
-      e = grub_strrchr (io->name, '.');
-
-      b = b ? (b + 1) : io->name;
-      e = e ? e : io->name + grub_strlen (io->name);
-      e = (e > b) ? e : io->name + grub_strlen (io->name);
-
-      for (i = 0; disabled_mods[i]; i++)
-       if (!grub_strncmp (b, disabled_mods[i], grub_strlen (b) - grub_strlen (e)))
-         {
-           grub_error (GRUB_ERR_ACCESS_DENIED,
-                       N_("module cannot be loaded in UEFI secure boot mode: %s"),
-                       io->name);
-           return GRUB_ERR_ACCESS_DENIED;
-         }
-
-      /* Fall through. */
-
-    case GRUB_FILE_TYPE_ACPI_TABLE:
-    case GRUB_FILE_TYPE_DEVICE_TREE_IMAGE:
-      *flags = GRUB_VERIFY_FLAGS_DEFER_AUTH;
-
-      return GRUB_ERR_NONE;
-
-    case GRUB_FILE_TYPE_LINUX_KERNEL:
-    case GRUB_FILE_TYPE_MULTIBOOT_KERNEL:
-    case GRUB_FILE_TYPE_BSD_KERNEL:
-    case GRUB_FILE_TYPE_XNU_KERNEL:
-    case GRUB_FILE_TYPE_PLAN9_KERNEL:
-      for (i = 0; disabled_mods[i]; i++)
-       if (grub_dl_get (disabled_mods[i]))
-         {
-           grub_error (GRUB_ERR_ACCESS_DENIED,
-                       N_("cannot boot due to dangerous module in memory: %s"),
-                       disabled_mods[i]);
-           return GRUB_ERR_ACCESS_DENIED;
-         }
-
-      *flags = GRUB_VERIFY_FLAGS_SINGLE_CHUNK;
-
-      /* Fall through. */
-
-    default:
-      return GRUB_ERR_NONE;
-    }
-}
-
-static grub_err_t
-shim_lock_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);
-
-  if (sl == NULL)
-    return grub_error (GRUB_ERR_ACCESS_DENIED, N_("shim_lock protocol not found"));
-
-  if (sl->verify (buf, size) != GRUB_EFI_SUCCESS)
-    return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad shim signature"));
-
-  return GRUB_ERR_NONE;
-}
-
-struct grub_file_verifier shim_lock =
-  {
-    .name = "shim_lock",
-    .init = shim_lock_init,
-    .write = shim_lock_write
-  };
-
-GRUB_MOD_INIT(shim_lock)
-{
-  grub_efi_shim_lock_protocol_t *sl = grub_efi_locate_protocol (&shim_lock_guid, 0);
-
-  if (sl == NULL || grub_efi_get_secureboot () != GRUB_EFI_SECUREBOOT_MODE_ENABLED)
-    return;
-
-  grub_verifier_register (&shim_lock);
-
-  grub_dl_set_persistent (mod);
-}
-
-GRUB_MOD_FINI(shim_lock)
-{
-  grub_verifier_unregister (&shim_lock);
-}
index 2c31847bf6db77fab377c90e7ed36897439d6027..b683bec5a18b5b8982cf4a20c9cde3a306c7726f 100644 (file)
@@ -20,6 +20,7 @@
 #include <grub/efi/efi.h>
 #include <grub/efi/console.h>
 #include <grub/efi/disk.h>
+#include <grub/efi/sb.h>
 #include <grub/term.h>
 #include <grub/misc.h>
 #include <grub/env.h>
@@ -39,6 +40,9 @@ grub_efi_init (void)
   /* Initialize the memory management system.  */
   grub_efi_mm_init ();
 
+  /* Register the shim_lock verifier if UEFI Secure Boot is enabled. */
+  grub_shim_lock_verifier_setup ();
+
   efi_call_4 (grub_efi_system_table->boot_services->set_watchdog_timer,
              0, 0, 0, NULL);
 
index 19658d9626dab1af3acdb3fe4d3943186f03bcf9..8bd5e936d156c42e97ea53630fc60348150a9b91 100644 (file)
 #include <grub/efi/pe32.h>
 #include <grub/efi/sb.h>
 #include <grub/err.h>
+#include <grub/file.h>
 #include <grub/i386/linux.h>
 #include <grub/mm.h>
 #include <grub/types.h>
+#include <grub/verify.h>
+
+static grub_efi_guid_t shim_lock_guid = GRUB_EFI_SHIM_LOCK_GUID;
+
+/* List of modules which cannot be loaded if UEFI secure boot mode is enabled. */
+static const char * const disabled_mods[] = {"iorw", "memrw", "wrmsr", NULL};
 
 /*
  * Determine whether we're in secure boot mode.
@@ -107,3 +114,101 @@ grub_efi_get_secureboot (void)
 
   return secureboot;
 }
+
+static grub_err_t
+shim_lock_verifier_init (grub_file_t io __attribute__ ((unused)),
+                        enum grub_file_type type,
+                        void **context __attribute__ ((unused)),
+                        enum grub_verify_flags *flags)
+{
+  const char *b, *e;
+  int i;
+
+  *flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION;
+
+  switch (type & GRUB_FILE_TYPE_MASK)
+    {
+    case GRUB_FILE_TYPE_GRUB_MODULE:
+      /* Establish GRUB module name. */
+      b = grub_strrchr (io->name, '/');
+      e = grub_strrchr (io->name, '.');
+
+      b = b ? (b + 1) : io->name;
+      e = e ? e : io->name + grub_strlen (io->name);
+      e = (e > b) ? e : io->name + grub_strlen (io->name);
+
+      for (i = 0; disabled_mods[i]; i++)
+       if (!grub_strncmp (b, disabled_mods[i], grub_strlen (b) - grub_strlen (e)))
+         {
+           grub_error (GRUB_ERR_ACCESS_DENIED,
+                       N_("module cannot be loaded in UEFI secure boot mode: %s"),
+                       io->name);
+           return GRUB_ERR_ACCESS_DENIED;
+         }
+
+      /* Fall through. */
+
+    case GRUB_FILE_TYPE_ACPI_TABLE:
+    case GRUB_FILE_TYPE_DEVICE_TREE_IMAGE:
+      *flags = GRUB_VERIFY_FLAGS_DEFER_AUTH;
+
+      return GRUB_ERR_NONE;
+
+    case GRUB_FILE_TYPE_LINUX_KERNEL:
+    case GRUB_FILE_TYPE_MULTIBOOT_KERNEL:
+    case GRUB_FILE_TYPE_BSD_KERNEL:
+    case GRUB_FILE_TYPE_XNU_KERNEL:
+    case GRUB_FILE_TYPE_PLAN9_KERNEL:
+      for (i = 0; disabled_mods[i]; i++)
+       if (grub_dl_get (disabled_mods[i]))
+         {
+           grub_error (GRUB_ERR_ACCESS_DENIED,
+                       N_("cannot boot due to dangerous module in memory: %s"),
+                       disabled_mods[i]);
+           return GRUB_ERR_ACCESS_DENIED;
+         }
+
+      *flags = GRUB_VERIFY_FLAGS_SINGLE_CHUNK;
+
+      /* Fall through. */
+
+    default:
+      return GRUB_ERR_NONE;
+    }
+}
+
+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);
+
+  if (!sl)
+    return grub_error (GRUB_ERR_ACCESS_DENIED, N_("shim_lock protocol not found"));
+
+  if (sl->verify (buf, size) != GRUB_EFI_SUCCESS)
+    return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad shim signature"));
+
+  return GRUB_ERR_NONE;
+}
+
+struct grub_file_verifier shim_lock_verifier =
+  {
+    .name = "shim_lock_verifier",
+    .init = shim_lock_verifier_init,
+    .write = shim_lock_verifier_write
+  };
+
+void
+grub_shim_lock_verifier_setup (void)
+{
+  grub_efi_shim_lock_protocol_t *sl =
+    grub_efi_locate_protocol (&shim_lock_guid, 0);
+
+  if (!sl)
+    return;
+
+  if (grub_efi_get_secureboot () != GRUB_EFI_SECUREBOOT_MODE_ENABLED)
+    return;
+
+  grub_verifier_register (&shim_lock_verifier);
+}
index a33d985e3c469278dcbd8402723527278779eab5..30c4335bb1238e79ca048eef7509781cf13564a1 100644 (file)
@@ -30,6 +30,9 @@
 #ifdef GRUB_MACHINE_EFI
 extern grub_uint8_t
 EXPORT_FUNC (grub_efi_get_secureboot) (void);
+
+extern void
+grub_shim_lock_verifier_setup (void);
 #else
 static inline grub_uint8_t
 grub_efi_get_secureboot (void)