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