bbc6a89
From e7f79b18704982a8e589433e49e9d5f0408adf66 Mon Sep 17 00:00:00 2001
f4c76c0
From: Colin Watson <cjwatson@ubuntu.com>
f4c76c0
Date: Tue, 23 Oct 2012 10:40:49 -0400
bbc6a89
Subject: [PATCH 085/192] 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
---
9d15b4d
 grub-core/kern/dl.c      | 22 ++++++++++++++++++++++
f4c76c0
 grub-core/kern/efi/efi.c | 28 ++++++++++++++++++++++++++++
f4c76c0
 include/grub/efi/efi.h   |  1 +
9d15b4d
 3 files changed, 51 insertions(+)
f4c76c0
f4c76c0
diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c
bc092b9
index e394cd96f..621070918 100644
f4c76c0
--- a/grub-core/kern/dl.c
f4c76c0
+++ b/grub-core/kern/dl.c
9d15b4d
@@ -32,12 +32,21 @@
9d15b4d
 #include <grub/env.h>
9d15b4d
 #include <grub/cache.h>
9d15b4d
 #include <grub/i18n.h>
9d15b4d
+#include <grub/efi/sb.h>
9d15b4d
 
9d15b4d
 /* Platforms where modules are in a readonly area of memory.  */
9d15b4d
 #if defined(GRUB_MACHINE_QEMU)
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"
9d15b4d
@@ -686,6 +695,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
bc092b9
index 684ca93f8..2588b481e 100644
f4c76c0
--- a/grub-core/kern/efi/efi.c
f4c76c0
+++ b/grub-core/kern/efi/efi.c
d9747d8
@@ -269,6 +269,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
bbc6a89
index 91e29ce66..bb3ab7dfd 100644
f4c76c0
--- a/include/grub/efi/efi.h
f4c76c0
+++ b/include/grub/efi/efi.h
bbc6a89
@@ -83,6 +83,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
-- 
bbc6a89
2.13.4
f4c76c0