nalika / rpms / grub2

Forked from rpms/grub2 2 years ago
Clone

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

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