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

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