dcavalca / rpms / grub2

Forked from rpms/grub2 3 years ago
Clone

Blame SOURCES/0005-Don-t-allow-insmod-when-secure-boot-is-enabled.patch

606ea6
From 926684b8498a820b2e1446b697ab9c746f5302ba Mon Sep 17 00:00:00 2001
606ea6
From: Colin Watson <cjwatson@ubuntu.com>
606ea6
Date: Tue, 23 Oct 2012 10:40:49 -0400
606ea6
Subject: [PATCH 05/34] Don't allow insmod when secure boot is enabled.
606ea6
606ea6
Hi,
606ea6
606ea6
Fedora's patch to forbid insmod in UEFI Secure Boot environments is fine
606ea6
as far as it goes.  However, the insmod command is not the only way that
606ea6
modules can be loaded.  In particular, the 'normal' command, which
606ea6
implements the usual GRUB menu and the fully-featured command prompt,
606ea6
will implicitly load commands not currently loaded into memory.  This
606ea6
permits trivial Secure Boot violations by writing commands implementing
606ea6
whatever you want to do and pointing $prefix at the malicious code.
606ea6
606ea6
I'm currently test-building this patch (replacing your current
606ea6
grub-2.00-no-insmod-on-sb.patch), but this should be more correct.  It
606ea6
moves the check into grub_dl_load_file.
606ea6
---
606ea6
 grub-core/kern/dl.c      | 21 +++++++++++++++++++++
606ea6
 grub-core/kern/efi/efi.c | 28 ++++++++++++++++++++++++++++
606ea6
 include/grub/efi/efi.h   |  1 +
606ea6
 3 files changed, 50 insertions(+)
606ea6
606ea6
diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c
606ea6
index 6850e04..b0b0405 100644
606ea6
--- a/grub-core/kern/dl.c
606ea6
+++ b/grub-core/kern/dl.c
606ea6
@@ -38,6 +38,14 @@
606ea6
 #define GRUB_MODULES_MACHINE_READONLY
606ea6
 #endif
606ea6
 
606ea6
+#ifdef GRUB_MACHINE_EMU
606ea6
+#include <sys/mman.h>
606ea6
+#endif
606ea6
+
606ea6
+#ifdef GRUB_MACHINE_EFI
606ea6
+#include <grub/efi/efi.h>
606ea6
+#endif
606ea6
+
606ea6
 
606ea6
 
606ea6
 #pragma GCC diagnostic ignored "-Wcast-align"
606ea6
@@ -680,6 +688,19 @@ grub_dl_load_file (const char *filename)
606ea6
   void *core = 0;
606ea6
   grub_dl_t mod = 0;
606ea6
 
606ea6
+#ifdef GRUB_MACHINE_EFI
606ea6
+  if (grub_efi_secure_boot ())
606ea6
+    {
606ea6
+#if 0
606ea6
+      /* This is an error, but grub2-mkconfig still generates a pile of
606ea6
+       * insmod commands, so emitting it would be mostly just obnoxious. */
606ea6
+      grub_error (GRUB_ERR_ACCESS_DENIED,
606ea6
+		  "Secure Boot forbids loading module from %s", filename);
606ea6
+#endif
606ea6
+      return 0;
606ea6
+    }
606ea6
+#endif
606ea6
+
606ea6
   grub_boot_time ("Loading module %s", filename);
606ea6
 
606ea6
   file = grub_file_open (filename);
606ea6
diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
606ea6
index b253141..aa81322 100644
606ea6
--- a/grub-core/kern/efi/efi.c
606ea6
+++ b/grub-core/kern/efi/efi.c
606ea6
@@ -259,6 +259,34 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
606ea6
   return NULL;
606ea6
 }
606ea6
 
606ea6
+grub_efi_boolean_t
606ea6
+grub_efi_secure_boot (void)
606ea6
+{
606ea6
+  grub_efi_guid_t efi_var_guid = GRUB_EFI_GLOBAL_VARIABLE_GUID;
606ea6
+  grub_size_t datasize;
606ea6
+  char *secure_boot = NULL;
606ea6
+  char *setup_mode = NULL;
606ea6
+  grub_efi_boolean_t ret = 0;
606ea6
+
606ea6
+  secure_boot = grub_efi_get_variable("SecureBoot", &efi_var_guid, &datasize);
606ea6
+
606ea6
+  if (datasize != 1 || !secure_boot)
606ea6
+    goto out;
606ea6
+
606ea6
+  setup_mode = grub_efi_get_variable("SetupMode", &efi_var_guid, &datasize);
606ea6
+
606ea6
+  if (datasize != 1 || !setup_mode)
606ea6
+    goto out;
606ea6
+
606ea6
+  if (*secure_boot && !*setup_mode)
606ea6
+    ret = 1;
606ea6
+
606ea6
+ out:
606ea6
+  grub_free (secure_boot);
606ea6
+  grub_free (setup_mode);
606ea6
+  return ret;
606ea6
+}
606ea6
+
606ea6
 #pragma GCC diagnostic ignored "-Wcast-align"
606ea6
 
606ea6
 /* Search the mods section from the PE32/PE32+ image. This code uses
606ea6
diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h
606ea6
index 9370fd5..a000c38 100644
606ea6
--- a/include/grub/efi/efi.h
606ea6
+++ b/include/grub/efi/efi.h
606ea6
@@ -72,6 +72,7 @@ EXPORT_FUNC (grub_efi_set_variable) (const char *var,
606ea6
 				     const grub_efi_guid_t *guid,
606ea6
 				     void *data,
606ea6
 				     grub_size_t datasize);
606ea6
+grub_efi_boolean_t EXPORT_FUNC (grub_efi_secure_boot) (void);
606ea6
 int
606ea6
 EXPORT_FUNC (grub_efi_compare_device_paths) (const grub_efi_device_path_t *dp1,
606ea6
 					     const grub_efi_device_path_t *dp2);
606ea6
-- 
606ea6
1.8.4.2
606ea6