dcavalca / rpms / grub2

Forked from rpms/grub2 3 years ago
Clone

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

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