zbyszek / rpms / grub2

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