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

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