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