From 02bdaed98f9a17a06f71ce7e21d9af2bd6547dfc Mon Sep 17 00:00:00 2001
From: Dimitri John Ledkov <xnox@ubuntu.com>
Date: Wed, 22 Jul 2020 11:31:43 +0100
Subject: [PATCH 333/336] 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>
---
grub-core/loader/arm64/linux.c | 12 ++++++++----
grub-core/loader/efi/chainloader.c | 4 +---
grub-core/loader/efi/linux.c | 1 +
grub-core/loader/i386/efi/linux.c | 13 ++++++++-----
4 files changed, 18 insertions(+), 12 deletions(-)
diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
index 1eb332a892c..d0a428d05fc 100644
--- a/grub-core/loader/arm64/linux.c
+++ b/grub-core/loader/arm64/linux.c
@@ -439,11 +439,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/chainloader.c b/grub-core/loader/efi/chainloader.c
index dbcdf333b62..001766bdf68 100644
--- a/grub-core/loader/efi/chainloader.c
+++ b/grub-core/loader/efi/chainloader.c
@@ -1082,9 +1082,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
return 0;
}
-
- grub_file_close (file);
- grub_device_close (dev);
+ // -1 fall-through to fail
fail:
if (dev)
diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
index 7fe7201a388..d9b5380cfd3 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 95dbb9e20af..c146bc58e3d 100644
--- a/grub-core/loader/i386/efi/linux.c
+++ b/grub-core/loader/i386/efi/linux.c
@@ -201,12 +201,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
goto fail;
}
- 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 (0x3fffffff,
--
2.26.2