From bb240087ce9ef9a62936fd6c1241df65a1e42d01 Mon Sep 17 00:00:00 2001 From: Dimitri John Ledkov Date: Wed, 22 Jul 2020 11:31:43 +0100 Subject: [PATCH 236/237] 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 Signed-off-by: Dimitri John Ledkov --- grub-core/loader/arm64/linux.c | 12 ++++++++---- grub-core/loader/efi/chainloader.c | 1 + grub-core/loader/efi/linux.c | 1 + grub-core/loader/i386/efi/linux.c | 13 ++++++++----- 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c index 628b320618c..e8ce560a2d2 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/chainloader.c b/grub-core/loader/efi/chainloader.c index 8b99cf23e9d..a93edc975cd 100644 --- a/grub-core/loader/efi/chainloader.c +++ b/grub-core/loader/efi/chainloader.c @@ -1079,6 +1079,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), return 0; } + // -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 b56ea0bc041..5f326eb4f53 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 2bd6663625d..cc6a503adb1 100644 --- a/grub-core/loader/i386/efi/linux.c +++ b/grub-core/loader/i386/efi/linux.c @@ -313,12 +313,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; + } } lh = (struct linux_i386_kernel_header *)kernel; -- 2.26.2