nalika / rpms / grub2

Forked from rpms/grub2 2 years ago
Clone

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

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