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

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