grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GRUB PATCH RFC 12/22] i386/efi: Report UEFI Secure Boot status to the L


From: Krystian Hebel
Subject: [GRUB PATCH RFC 12/22] i386/efi: Report UEFI Secure Boot status to the Linux kernel
Date: Tue, 10 Nov 2020 15:44:50 +0100

From: Norbert Kaminski <norbert.kaminski@3mdeb.com>

Otherwise the kernel does not know its state and cannot enable various
security features depending on UEFI Secure Boot.

Signed-off-by: Ignat Korchagin <ignat@cloudflare.com>
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Signed-off-by: Norbert Kaminski <norbert.kaminski@3mdeb.com>
---
 grub-core/loader/i386/linux.c | 86 ++++++++++++++++++++++++++++++++++-
 include/grub/i386/linux.h     | 14 +++++-
 2 files changed, 97 insertions(+), 3 deletions(-)

diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
index 976af3fae873..940ce0f98bca 100644
--- a/grub-core/loader/i386/linux.c
+++ b/grub-core/loader/i386/linux.c
@@ -397,6 +397,87 @@ grub_linux_boot_mmap_fill (grub_uint64_t addr, 
grub_uint64_t size,
   return 0;
 }
 
+#ifdef GRUB_MACHINE_EFI
+/*
+ * Determine whether we're in secure boot mode.
+ *
+ * Please keep the logic in sync with the Linux kernel,
+ * drivers/firmware/efi/libstub/secureboot.c:efi_get_secureboot().
+ */
+static grub_uint8_t
+grub_efi_get_secureboot (void)
+{
+  grub_efi_guid_t efi_variable_guid = GRUB_EFI_GLOBAL_VARIABLE_GUID;
+  grub_efi_guid_t efi_shim_lock_guid = GRUB_EFI_SHIM_LOCK_GUID;
+  grub_efi_status_t status;
+  grub_efi_uint32_t attr = 0;
+  grub_size_t size = 0;
+  grub_uint8_t *secboot = NULL;
+  grub_uint8_t *setupmode = NULL;
+  grub_uint8_t *moksbstate = NULL;
+  grub_uint8_t secureboot = GRUB_LINUX_EFI_SECUREBOOT_MODE_UNKNOWN;
+  const char *secureboot_str = "UNKNOWN";
+
+  status = grub_efi_get_variable ("SecureBoot", &efi_variable_guid,
+                                 &size, (void **) &secboot);
+
+  if (status == GRUB_EFI_NOT_FOUND)
+    {
+      secureboot = GRUB_LINUX_EFI_SECUREBOOT_MODE_DISABLED;
+      goto out;
+    }
+
+  if (status != GRUB_EFI_SUCCESS)
+    goto out;
+
+  status = grub_efi_get_variable ("SetupMode", &efi_variable_guid,
+                                 &size, (void **) &setupmode);
+
+  if (status != GRUB_EFI_SUCCESS)
+    goto out;
+
+  if ((*secboot == 0) || (*setupmode == 1))
+    {
+      secureboot = GRUB_LINUX_EFI_SECUREBOOT_MODE_DISABLED;
+      goto out;
+    }
+
+  /*
+   * See if a user has put the shim into insecure mode. If so, and if the
+   * variable doesn't have the runtime attribute set, we might as well
+   * honor that.
+   */
+  status = grub_efi_get_variable_with_attributes ("MokSBState", 
&efi_shim_lock_guid,
+                                                 &size, (void **) &moksbstate, 
&attr);
+
+  /* If it fails, we don't care why. Default to secure. */
+  if (status != GRUB_EFI_SUCCESS)
+    {
+      secureboot = GRUB_LINUX_EFI_SECUREBOOT_MODE_ENABLED;
+      goto out;
+    }
+
+  if (!(attr & GRUB_EFI_VARIABLE_RUNTIME_ACCESS) && *moksbstate == 1)
+    secureboot = GRUB_LINUX_EFI_SECUREBOOT_MODE_DISABLED;
+
+  secureboot = GRUB_LINUX_EFI_SECUREBOOT_MODE_ENABLED;
+
+ out:
+  grub_free (moksbstate);
+  grub_free (setupmode);
+  grub_free (secboot);
+
+  if (secureboot == GRUB_LINUX_EFI_SECUREBOOT_MODE_DISABLED)
+    secureboot_str = "Disabled";
+  else if (secureboot == GRUB_LINUX_EFI_SECUREBOOT_MODE_ENABLED)
+    secureboot_str = "Enabled";
+
+  grub_dprintf ("linux", "UEFI Secure Boot state: %s\n", secureboot_str);
+
+  return secureboot;
+}
+#endif
+
 static grub_err_t
 grub_linux_boot (void)
 {
@@ -583,6 +664,9 @@ grub_linux_boot (void)
     grub_efi_uintn_t efi_desc_size;
     grub_size_t efi_mmap_target;
     grub_efi_uint32_t efi_desc_version;
+
+    ctx.params->secure_boot = grub_efi_get_secureboot ();
+
     err = grub_efi_finish_boot_services (&efi_mmap_size, efi_mmap_buf, NULL,
                                         &efi_desc_size, &efi_desc_version);
     if (err)
@@ -794,7 +878,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
 
   linux_params.code32_start = prot_mode_target + lh.code32_start - 
GRUB_LINUX_BZIMAGE_ADDR;
   linux_params.kernel_alignment = (1 << align);
-  linux_params.ps_mouse = linux_params.padding10 = 0;
+  linux_params.ps_mouse = linux_params.padding11 = 0;
   linux_params.type_of_loader = GRUB_LINUX_BOOT_LOADER_TYPE;
 
   /* These two are used (instead of cmd_line_ptr) by older versions of Linux,
diff --git a/include/grub/i386/linux.h b/include/grub/i386/linux.h
index ce30e7fb01b9..6aea73ddb145 100644
--- a/include/grub/i386/linux.h
+++ b/include/grub/i386/linux.h
@@ -49,6 +49,12 @@
 /* Maximum number of MBR signatures to store. */
 #define EDD_MBR_SIG_MAX                        16
 
+/* Possible values for Linux secure_boot kernel parameter. */
+#define GRUB_LINUX_EFI_SECUREBOOT_MODE_UNSET   0
+#define GRUB_LINUX_EFI_SECUREBOOT_MODE_UNKNOWN 1
+#define GRUB_LINUX_EFI_SECUREBOOT_MODE_DISABLED        2
+#define GRUB_LINUX_EFI_SECUREBOOT_MODE_ENABLED 3
+
 #ifdef __x86_64__
 
 #define GRUB_LINUX_EFI_SIGNATURE       \
@@ -275,7 +281,11 @@ struct linux_kernel_params
 
   grub_uint8_t mmap_size;              /* 1e8 */
 
-  grub_uint8_t padding9[0x1f1 - 0x1e9];
+  grub_uint8_t padding9[0x1ec - 0x1e9];
+
+  grub_uint8_t secure_boot;             /* 1ec */
+
+  grub_uint8_t padding10[0x1f1 - 0x1ed];
 
   /* Linux setup header copy - BEGIN. */
   grub_uint8_t setup_sects;            /* The size of the setup in sectors */
@@ -286,7 +296,7 @@ struct linux_kernel_params
   grub_uint16_t vid_mode;              /* Video mode control */
   grub_uint16_t root_dev;              /* Default root device number */
 
-  grub_uint8_t padding10;              /* 1fe */
+  grub_uint8_t padding11;              /* 1fe */
   grub_uint8_t ps_mouse;               /* 1ff */
 
   grub_uint16_t jump;                  /* Jump instruction */
-- 
2.17.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]