grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SECURITY PATCH 006/117] efi: Use grub_is_lockdown() instead of hardcodi


From: Daniel Kiper
Subject: [SECURITY PATCH 006/117] efi: Use grub_is_lockdown() instead of hardcoding a disabled modules list
Date: Tue, 2 Mar 2021 19:00:13 +0100

From: Javier Martinez Canillas <javierm@redhat.com>

Now the GRUB can check if it has been locked down and this can be used to
prevent executing commands that can be utilized to circumvent the UEFI
Secure Boot mechanisms. So, instead of hardcoding a list of modules that
have to be disabled, prevent the usage of commands that can be dangerous.

This not only allows the commands to be disabled on other platforms, but
also properly separate the concerns. Since the shim_lock verifier logic
should be only about preventing to run untrusted binaries and not about
defining these kind of policies.

Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
 docs/grub.texi                  | 15 +++++++++------
 grub-core/commands/i386/wrmsr.c |  5 +++--
 grub-core/commands/iorw.c       | 19 ++++++++++---------
 grub-core/commands/memrw.c      | 19 ++++++++++---------
 grub-core/kern/efi/sb.c         | 41 -----------------------------------------
 5 files changed, 32 insertions(+), 67 deletions(-)

diff --git a/docs/grub.texi b/docs/grub.texi
index 4c980d356..c3e015d4f 100644
--- a/docs/grub.texi
+++ b/docs/grub.texi
@@ -5405,6 +5405,9 @@ only applies to the particular cpu/core/thread that runs 
the command.
 Also, if you specify a reserved or unimplemented MSR address, it will
 cause a general protection exception (which is not currently being handled)
 and the system will reboot.
+
+Note: The command is not allowed when lockdown is enforced (@pxref{Lockdown}).
+      This is done to prevent subverting various security mechanisms.
 @end deffn
 
 @node xen_hypervisor
@@ -5915,12 +5918,12 @@ 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 verifier logic.
+All GRUB modules not stored in the @file{core.img}, OS kernels, ACPI tables,
+Device Trees, etc. have to be signed, e.g, using PGP. Additionally, the 
commands
+that can be used to subvert the UEFI secure boot mechanism, such as 
@command{iorw}
+and @command{memrw} will not be available when the UEFI secure boot is enabled.
+This is done for security reasons and are enforced by the GRUB Lockdown 
mechanism
+(@pxref{Lockdown}).
 
 @node Measured Boot
 @section Measuring boot components
diff --git a/grub-core/commands/i386/wrmsr.c b/grub-core/commands/i386/wrmsr.c
index fa76f5aed..1b143b888 100644
--- a/grub-core/commands/i386/wrmsr.c
+++ b/grub-core/commands/i386/wrmsr.c
@@ -24,6 +24,7 @@
 #include <grub/env.h>
 #include <grub/command.h>
 #include <grub/extcmd.h>
+#include <grub/lockdown.h>
 #include <grub/i18n.h>
 #include <grub/i386/cpuid.h>
 #include <grub/i386/wrmsr.h>
@@ -83,8 +84,8 @@ grub_cmd_msr_write (grub_command_t cmd __attribute__ 
((unused)), int argc, char
 
 GRUB_MOD_INIT(wrmsr)
 {
-  cmd_write = grub_register_command ("wrmsr", grub_cmd_msr_write, N_("ADDR 
VALUE"),
-                                    N_("Write a value to a CPU model specific 
register."));
+  cmd_write = grub_register_command_lockdown ("wrmsr", grub_cmd_msr_write, 
N_("ADDR VALUE"),
+                                              N_("Write a value to a CPU model 
specific register."));
 }
 
 GRUB_MOD_FINI(wrmsr)
diff --git a/grub-core/commands/iorw.c b/grub-core/commands/iorw.c
index a0c164e54..584baec8f 100644
--- a/grub-core/commands/iorw.c
+++ b/grub-core/commands/iorw.c
@@ -23,6 +23,7 @@
 #include <grub/env.h>
 #include <grub/cpu/io.h>
 #include <grub/i18n.h>
+#include <grub/lockdown.h>
 
 GRUB_MOD_LICENSE ("GPLv3+");
 
@@ -131,17 +132,17 @@ GRUB_MOD_INIT(memrw)
                          N_("PORT"), N_("Read 32-bit value from PORT."),
                          options);
   cmd_write_byte =
-    grub_register_command ("outb", grub_cmd_write,
-                          N_("PORT VALUE [MASK]"),
-                          N_("Write 8-bit VALUE to PORT."));
+    grub_register_command_lockdown ("outb", grub_cmd_write,
+                                    N_("PORT VALUE [MASK]"),
+                                    N_("Write 8-bit VALUE to PORT."));
   cmd_write_word =
-    grub_register_command ("outw", grub_cmd_write,
-                          N_("PORT VALUE [MASK]"),
-                          N_("Write 16-bit VALUE to PORT."));
+    grub_register_command_lockdown ("outw", grub_cmd_write,
+                                    N_("PORT VALUE [MASK]"),
+                                    N_("Write 16-bit VALUE to PORT."));
   cmd_write_dword =
-    grub_register_command ("outl", grub_cmd_write,
-                          N_("ADDR VALUE [MASK]"),
-                          N_("Write 32-bit VALUE to PORT."));
+    grub_register_command_lockdown ("outl", grub_cmd_write,
+                                    N_("ADDR VALUE [MASK]"),
+                                    N_("Write 32-bit VALUE to PORT."));
 }
 
 GRUB_MOD_FINI(memrw)
diff --git a/grub-core/commands/memrw.c b/grub-core/commands/memrw.c
index 98769eadb..d401a6db0 100644
--- a/grub-core/commands/memrw.c
+++ b/grub-core/commands/memrw.c
@@ -22,6 +22,7 @@
 #include <grub/extcmd.h>
 #include <grub/env.h>
 #include <grub/i18n.h>
+#include <grub/lockdown.h>
 
 GRUB_MOD_LICENSE ("GPLv3+");
 
@@ -133,17 +134,17 @@ GRUB_MOD_INIT(memrw)
                          N_("ADDR"), N_("Read 32-bit value from ADDR."),
                          options);
   cmd_write_byte =
-    grub_register_command ("write_byte", grub_cmd_write,
-                          N_("ADDR VALUE [MASK]"),
-                          N_("Write 8-bit VALUE to ADDR."));
+    grub_register_command_lockdown ("write_byte", grub_cmd_write,
+                                    N_("ADDR VALUE [MASK]"),
+                                    N_("Write 8-bit VALUE to ADDR."));
   cmd_write_word =
-    grub_register_command ("write_word", grub_cmd_write,
-                          N_("ADDR VALUE [MASK]"),
-                          N_("Write 16-bit VALUE to ADDR."));
+    grub_register_command_lockdown ("write_word", grub_cmd_write,
+                                    N_("ADDR VALUE [MASK]"),
+                                    N_("Write 16-bit VALUE to ADDR."));
   cmd_write_dword =
-    grub_register_command ("write_dword", grub_cmd_write,
-                          N_("ADDR VALUE [MASK]"),
-                          N_("Write 32-bit VALUE to ADDR."));
+    grub_register_command_lockdown ("write_dword", grub_cmd_write,
+                                    N_("ADDR VALUE [MASK]"),
+                                    N_("Write 32-bit VALUE to ADDR."));
 }
 
 GRUB_MOD_FINI(memrw)
diff --git a/grub-core/kern/efi/sb.c b/grub-core/kern/efi/sb.c
index 8bd5e936d..5d7210a82 100644
--- a/grub-core/kern/efi/sb.c
+++ b/grub-core/kern/efi/sb.c
@@ -30,9 +30,6 @@
 
 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.
  *
@@ -121,53 +118,15 @@ shim_lock_verifier_init (grub_file_t io __attribute__ 
((unused)),
                         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. */
-- 
2.11.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]