From b01dc9aaedb5a5e91e2ca10748fce65406d657c0 Mon Sep 17 00:00:00 2001
From: Fedora Ninjas <grub2-owner@fedoraproject.org>
Date: Mon, 10 Aug 2020 14:54:34 +0800
Subject: [PATCH 7/7] linuxefi: fail kernel validation without shim protocol.

If certificates that signed grub are installed into db, grub can be
booted directly. It will then boot any kernel without signature
validation. The booted kernel will think it was booted in secureboot
mode and will implement lockdown, yet it could have been tampered.

This version of the patch skips calling verification, when booted
without secureboot. And is indented with gnu ident.

CVE-2020-15705

Reported-by: Mathieu Trudel-Lapierre <cyphermox@ubuntu.com>
Signed-off-by: Dimitri John Ledkov <xnox@ubuntu.com>
Signed-off-by: Baogen Shang <baogen.shang@windriver.com.cn>
---
 grub-core/loader/arm64/linux.c    | 12 ++++++++----
 grub-core/loader/efi/linux.c      |  1 +
 grub-core/loader/i386/efi/linux.c | 13 ++++++++-----
 3 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
index e111074..7a076c1 100644
--- a/grub-core/loader/arm64/linux.c
+++ b/grub-core/loader/arm64/linux.c
@@ -381,11 +381,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
 
   grub_dprintf ("linux", "kernel @ %p\n", kernel_addr);
 
-  rc = grub_linuxefi_secure_validate (kernel_addr, kernel_size);
-  if (rc < 0)
+  if (grub_efi_secure_boot ())
     {
-      grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), argv[0]);
-      goto fail;
+      rc = grub_linuxefi_secure_validate (kernel_addr, kernel_size);
+      if (rc <= 0)
+	{
+	  grub_error (GRUB_ERR_INVALID_COMMAND,
+		      N_("%s has invalid signature"), argv[0]);
+	  goto fail;
+	}
     }
 
   pe = (void *)((unsigned long)kernel_addr + lh.hdr_offset);
diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
index b56ea0b..5f326eb 100644
--- a/grub-core/loader/efi/linux.c
+++ b/grub-core/loader/efi/linux.c
@@ -33,6 +33,7 @@ struct grub_efi_shim_lock
 };
 typedef struct grub_efi_shim_lock grub_efi_shim_lock_t;
 
+// Returns 1 on success, -1 on error, 0 when not available
 int
 grub_linuxefi_secure_validate (void *data, grub_uint32_t size)
 {
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
index 851bce7..30182c0 100644
--- a/grub-core/loader/i386/efi/linux.c
+++ b/grub-core/loader/i386/efi/linux.c
@@ -204,12 +204,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
   grub_tpm_measure (kernel, filelen, GRUB_BINARY_PCR, "grub_linuxefi", "Kernel");
   grub_print_error();
 
-  rc = grub_linuxefi_secure_validate (kernel, filelen);
-  if (rc < 0)
+  if (grub_efi_secure_boot ())
     {
-      grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"),
-		  argv[0]);
-      goto fail;
+      rc = grub_linuxefi_secure_validate (kernel, filelen);
+      if (rc <= 0)
+	{
+	  grub_error (GRUB_ERR_INVALID_COMMAND,
+		      N_("%s has invalid signature"), argv[0]);
+	  goto fail;
+	}
     }
 
   params = grub_efi_allocate_pages_max (GRUB_EFI_MAX_ALLOCATION_ADDRESS,
-- 
2.23.0

