dcavalca / rpms / grub2

Forked from rpms/grub2 3 years ago
Clone

Blame SOURCES/0313-linuxefi-fail-kernel-validation-without-shim-protoco.patch

80913e
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
80913e
From: Dimitri John Ledkov <xnox@ubuntu.com>
80913e
Date: Wed, 22 Jul 2020 11:31:43 +0100
80913e
Subject: [PATCH] linuxefi: fail kernel validation without shim protocol.
80913e
80913e
If certificates that signed grub are installed into db, grub can be
80913e
booted directly. It will then boot any kernel without signature
80913e
validation. The booted kernel will think it was booted in secureboot
80913e
mode and will implement lockdown, yet it could have been tampered.
80913e
80913e
This version of the patch skips calling verification, when booted
80913e
without secureboot. And is indented with gnu ident.
80913e
80913e
CVE-2020-15705
80913e
80913e
Reported-by: Mathieu Trudel-Lapierre <cyphermox@ubuntu.com>
80913e
Signed-off-by: Dimitri John Ledkov <xnox@ubuntu.com>
80913e
---
80913e
 grub-core/loader/arm64/linux.c     | 12 ++++++++----
80913e
 grub-core/loader/efi/chainloader.c |  1 +
80913e
 grub-core/loader/efi/linux.c       |  1 +
80913e
 grub-core/loader/i386/efi/linux.c  | 13 ++++++++-----
80913e
 4 files changed, 18 insertions(+), 9 deletions(-)
80913e
80913e
diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
80913e
index e1110749eb9..7a076c13171 100644
80913e
--- a/grub-core/loader/arm64/linux.c
80913e
+++ b/grub-core/loader/arm64/linux.c
80913e
@@ -381,11 +381,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
80913e
 
80913e
   grub_dprintf ("linux", "kernel @ %p\n", kernel_addr);
80913e
 
80913e
-  rc = grub_linuxefi_secure_validate (kernel_addr, kernel_size);
80913e
-  if (rc < 0)
80913e
+  if (grub_efi_secure_boot ())
80913e
     {
80913e
-      grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), argv[0]);
80913e
-      goto fail;
80913e
+      rc = grub_linuxefi_secure_validate (kernel_addr, kernel_size);
80913e
+      if (rc <= 0)
80913e
+	{
80913e
+	  grub_error (GRUB_ERR_INVALID_COMMAND,
80913e
+		      N_("%s has invalid signature"), argv[0]);
80913e
+	  goto fail;
80913e
+	}
80913e
     }
80913e
 
80913e
   pe = (void *)((unsigned long)kernel_addr + lh.hdr_offset);
80913e
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
80913e
index 8b99cf23e9d..a93edc975cd 100644
80913e
--- a/grub-core/loader/efi/chainloader.c
80913e
+++ b/grub-core/loader/efi/chainloader.c
80913e
@@ -1079,6 +1079,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
80913e
 
80913e
       return 0;
80913e
     }
80913e
+  // -1 fall-through to fail
80913e
 
80913e
 fail:
80913e
   if (dev)
80913e
diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
80913e
index e09f824862b..927d89a90d7 100644
80913e
--- a/grub-core/loader/efi/linux.c
80913e
+++ b/grub-core/loader/efi/linux.c
80913e
@@ -33,6 +33,7 @@ struct grub_efi_shim_lock
80913e
 };
80913e
 typedef struct grub_efi_shim_lock grub_efi_shim_lock_t;
80913e
 
80913e
+// Returns 1 on success, -1 on error, 0 when not available
80913e
 int
80913e
 grub_linuxefi_secure_validate (void *data, grub_uint32_t size)
80913e
 {
80913e
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
80913e
index ade7ab8f573..361e503cb52 100644
80913e
--- a/grub-core/loader/i386/efi/linux.c
80913e
+++ b/grub-core/loader/i386/efi/linux.c
80913e
@@ -206,12 +206,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
80913e
   grub_tpm_measure (kernel, filelen, GRUB_BINARY_PCR, "grub_linuxefi", "Kernel");
80913e
   grub_print_error();
80913e
 
80913e
-  rc = grub_linuxefi_secure_validate (kernel, filelen);
80913e
-  if (rc < 0)
80913e
+  if (grub_efi_secure_boot ())
80913e
     {
80913e
-      grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"),
80913e
-		  argv[0]);
80913e
-      goto fail;
80913e
+      rc = grub_linuxefi_secure_validate (kernel, filelen);
80913e
+      if (rc <= 0)
80913e
+	{
80913e
+	  grub_error (GRUB_ERR_INVALID_COMMAND,
80913e
+		      N_("%s has invalid signature"), argv[0]);
80913e
+	  goto fail;
80913e
+	}
80913e
     }
80913e
 
80913e
   params = grub_efi_allocate_pages_max (0x3fffffff,