grub-devel
[Top][All Lists]
Advanced

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

[PATCH 04/18] verifiers: factor unsafe module handling out of shim_lock


From: Daniel Axtens
Subject: [PATCH 04/18] verifiers: factor unsafe module handling out of shim_lock
Date: Fri, 2 Oct 2020 15:13:07 +1000

Other verifiers that implement secure boot may want to be able to
reuse the same list and behaviour.

Signed-off-by: Daniel Axtens <dja@axtens.net>
---
 grub-core/commands/efi/shim_lock.c | 45 +++++++++++------------------
 grub-core/commands/verifiers.c     | 46 ++++++++++++++++++++++++++++++
 include/grub/verify.h              | 13 +++++++++
 3 files changed, 75 insertions(+), 29 deletions(-)

diff --git a/grub-core/commands/efi/shim_lock.c 
b/grub-core/commands/efi/shim_lock.c
index 764098cfc83e..bad594b4620d 100644
--- a/grub-core/commands/efi/shim_lock.c
+++ b/grub-core/commands/efi/shim_lock.c
@@ -42,16 +42,12 @@ typedef struct grub_efi_shim_lock_protocol 
grub_efi_shim_lock_protocol_t;
 static grub_efi_guid_t shim_lock_guid = GRUB_EFI_SHIM_LOCK_GUID;
 static grub_efi_shim_lock_protocol_t *sl;
 
-/* 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;
+  const char *dangerous_mod;
 
   *flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION;
 
@@ -61,22 +57,13 @@ shim_lock_init (grub_file_t io, enum grub_file_type type,
   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;
-         }
+      if (grub_is_dangerous_module (io))
+       {
+         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. */
 
@@ -91,14 +78,14 @@ shim_lock_init (grub_file_t io, enum grub_file_type type,
     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;
-         }
+      dangerous_mod = grub_dangerous_module_loaded ();
+      if (dangerous_mod)
+       {
+         grub_error (GRUB_ERR_ACCESS_DENIED,
+                     N_("cannot boot due to dangerous module in memory: %s"),
+                     dangerous_mod);
+         return GRUB_ERR_ACCESS_DENIED;
+       }
 
       *flags = GRUB_VERIFY_FLAGS_SINGLE_CHUNK;
 
diff --git a/grub-core/commands/verifiers.c b/grub-core/commands/verifiers.c
index aae4d84bb118..1d67a2541dae 100644
--- a/grub-core/commands/verifiers.c
+++ b/grub-core/commands/verifiers.c
@@ -221,6 +221,52 @@ grub_verify_string (char *str, enum 
grub_verify_string_type type)
   return GRUB_ERR_NONE;
 }
 
+/* List of modules which may allow for verifcation to be bypassed. */
+static const char *const disabled_mods[] = { "iorw", "memrw", "wrmsr", NULL };
+
+/*
+ * Does the module in file `io' allow for the a verifier to be bypassed?
+ *
+ * Returns 1 if so, otherwise 0.
+ */
+char
+grub_is_dangerous_module (grub_file_t io)
+{
+  char *b, *e;
+  int i;
+
+  /* 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)))
+      return 1;
+  return 0;
+}
+
+/*
+ * Is there already an unsafe module in memory?
+ * Returns the name if one is loaded, otherwise NULL.
+ */
+const char *
+grub_dangerous_module_loaded (void)
+{
+  int i;
+
+  for (i = 0; disabled_mods[i]; i++)
+    if (grub_dl_get (disabled_mods[i]))
+      {
+       return disabled_mods[i];
+      }
+  return NULL;
+}
+
 GRUB_MOD_INIT(verifiers)
 {
   grub_file_filter_register (GRUB_FILE_FILTER_VERIFY, grub_verifiers_open);
diff --git a/include/grub/verify.h b/include/grub/verify.h
index ea049143368e..8c2de132051d 100644
--- a/include/grub/verify.h
+++ b/include/grub/verify.h
@@ -81,4 +81,17 @@ grub_verifier_unregister (struct grub_file_verifier *ver)
 grub_err_t
 grub_verify_string (char *str, enum grub_verify_string_type type);
 
+/*
+ * Does the module in file `io' allow for the a verifier to be bypassed?
+ *
+ * Returns 1 if so, otherwise 0.
+ */
+char grub_is_dangerous_module (grub_file_t io);
+
+/*
+ * Is there already an unsafe module in memory?
+ * Returns the name if one is loaded, otherwise NULL.
+ */
+const char *grub_dangerous_module_loaded (void);
+
 #endif /* ! GRUB_VERIFY_HEADER */
-- 
2.25.1




reply via email to

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