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