nalika / rpms / grub2

Forked from rpms/grub2 2 years ago
Clone

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

8e15ce
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
8e15ce
From: Dimitri John Ledkov <xnox@ubuntu.com>
8e15ce
Date: Wed, 22 Jul 2020 11:31:43 +0100
8e15ce
Subject: [PATCH] linuxefi: fail kernel validation without shim protocol.
8e15ce
8e15ce
If certificates that signed grub are installed into db, grub can be
8e15ce
booted directly. It will then boot any kernel without signature
8e15ce
validation. The booted kernel will think it was booted in secureboot
8e15ce
mode and will implement lockdown, yet it could have been tampered.
8e15ce
8e15ce
This version of the patch skips calling verification, when booted
8e15ce
without secureboot. And is indented with gnu ident.
8e15ce
8e15ce
CVE-2020-15705
8e15ce
8e15ce
Reported-by: Mathieu Trudel-Lapierre <cyphermox@ubuntu.com>
8e15ce
Signed-off-by: Dimitri John Ledkov <xnox@ubuntu.com>
8e15ce
---
8e15ce
 grub-core/loader/arm64/linux.c     | 13 +++++++++----
8e15ce
 grub-core/loader/efi/chainloader.c |  1 +
8e15ce
 grub-core/loader/efi/linux.c       |  1 +
8e15ce
 grub-core/loader/i386/efi/linux.c  | 17 +++++++++++------
8e15ce
 4 files changed, 22 insertions(+), 10 deletions(-)
8e15ce
8e15ce
diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
8e15ce
index 70a0075ec5e..47f8cf0d84b 100644
8e15ce
--- a/grub-core/loader/arm64/linux.c
8e15ce
+++ b/grub-core/loader/arm64/linux.c
8e15ce
@@ -34,6 +34,7 @@
8e15ce
 #include <grub/i18n.h>
8e15ce
 #include <grub/lib/cmdline.h>
8e15ce
 #include <grub/verify.h>
8e15ce
+#include <grub/efi/sb.h>
8e15ce
 
8e15ce
 GRUB_MOD_LICENSE ("GPLv3+");
8e15ce
 
8e15ce
@@ -363,11 +364,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
8e15ce
 
8e15ce
   grub_dprintf ("linux", "kernel @ %p\n", kernel_addr);
8e15ce
 
8e15ce
-  rc = grub_linuxefi_secure_validate (kernel_addr, kernel_size);
8e15ce
-  if (rc < 0)
8e15ce
+  if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED)
8e15ce
     {
8e15ce
-      grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), argv[0]);
8e15ce
-      goto fail;
8e15ce
+      rc = grub_linuxefi_secure_validate (kernel_addr, kernel_size);
8e15ce
+      if (rc <= 0)
8e15ce
+	{
8e15ce
+	  grub_error (GRUB_ERR_INVALID_COMMAND,
8e15ce
+		      N_("%s has invalid signature"), argv[0]);
8e15ce
+	  goto fail;
8e15ce
+	}
8e15ce
     }
8e15ce
 
8e15ce
   pe = (void *)((unsigned long)kernel_addr + lh.hdr_offset);
8e15ce
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
8e15ce
index ac8dfd40c61..d41e8ea14a8 100644
8e15ce
--- a/grub-core/loader/efi/chainloader.c
8e15ce
+++ b/grub-core/loader/efi/chainloader.c
8e15ce
@@ -1084,6 +1084,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
8e15ce
 
8e15ce
       return 0;
8e15ce
     }
8e15ce
+  // -1 fall-through to fail
8e15ce
 
8e15ce
 fail:
8e15ce
   if (dev)
8e15ce
diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
8e15ce
index e8b9ecb17f6..9260731c107 100644
8e15ce
--- a/grub-core/loader/efi/linux.c
8e15ce
+++ b/grub-core/loader/efi/linux.c
8e15ce
@@ -33,6 +33,7 @@ struct grub_efi_shim_lock
8e15ce
 };
8e15ce
 typedef struct grub_efi_shim_lock grub_efi_shim_lock_t;
8e15ce
 
8e15ce
+// Returns 1 on success, -1 on error, 0 when not available
8e15ce
 int
8e15ce
 grub_linuxefi_secure_validate (void *data, grub_uint32_t size)
8e15ce
 {
8e15ce
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
8e15ce
index f992ceeef20..3cf0f9b330b 100644
8e15ce
--- a/grub-core/loader/i386/efi/linux.c
8e15ce
+++ b/grub-core/loader/i386/efi/linux.c
8e15ce
@@ -30,6 +30,7 @@
8e15ce
 #include <grub/cpu/efi/memory.h>
8e15ce
 #include <grub/tpm.h>
8e15ce
 #include <grub/safemath.h>
8e15ce
+#include <grub/efi/sb.h>
8e15ce
 
8e15ce
 GRUB_MOD_LICENSE ("GPLv3+");
8e15ce
 
8e15ce
@@ -101,7 +102,7 @@ kernel_alloc(grub_efi_uintn_t size, const char * const errmsg)
8e15ce
 
8e15ce
       pages = BYTES_TO_PAGES(size);
8e15ce
       grub_dprintf ("linux", "Trying to allocate %lu pages from %p\n",
8e15ce
-		    pages, (void *)max);
8e15ce
+		    (unsigned long)pages, (void *)(unsigned long)max);
8e15ce
 
8e15ce
       prev_max = max;
8e15ce
       addr = grub_efi_allocate_pages_real (max, pages,
8e15ce
@@ -307,12 +308,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
8e15ce
       goto fail;
8e15ce
     }
8e15ce
 
8e15ce
-  rc = grub_linuxefi_secure_validate (kernel, filelen);
8e15ce
-  if (rc < 0)
8e15ce
+  if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED)
8e15ce
     {
8e15ce
-      grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"),
8e15ce
-		  argv[0]);
8e15ce
-      goto fail;
8e15ce
+      rc = grub_linuxefi_secure_validate (kernel, filelen);
8e15ce
+      if (rc <= 0)
8e15ce
+	{
8e15ce
+	  grub_error (GRUB_ERR_INVALID_COMMAND,
8e15ce
+		      N_("%s has invalid signature"), argv[0]);
8e15ce
+	  goto fail;
8e15ce
+	}
8e15ce
     }
8e15ce
 
8e15ce
   lh = (struct linux_i386_kernel_header *)kernel;
8e15ce
@@ -386,6 +390,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
8e15ce
 
8e15ce
   setup_header_end_offset = *((grub_uint8_t *)kernel + 0x201);
8e15ce
   grub_dprintf ("linux", "copying %lu bytes from %p to %p\n",
8e15ce
+		(unsigned long)
8e15ce
 		MIN((grub_size_t)0x202+setup_header_end_offset,
8e15ce
 		    sizeof (*params)) - 0x1f1,
8e15ce
 		(grub_uint8_t *)kernel + 0x1f1,