nalika / rpms / grub2

Forked from rpms/grub2 2 years ago
Clone

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

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