From eab2668a1a549e15f549511075fb0c6a9a4f6353 Mon Sep 17 00:00:00 2001 From: Duncan Laurie Date: Fri, 5 May 2017 15:50:45 -0700 Subject: futility: Verify linux kernel signature Verify the linux kernel signature on images before assuming they contain a linux kernel. This allows non-linux images on x86 to be left unmodified when signed. BUG=b:38040849 BRANCH=none TEST=sign a multiboot kernel image that remains unmodified, and ensure that x86 linux kernels are still updated properly and can still be booted. Change-Id: Ib7ba2d59ebe6413ab355aa7c0a9ee2e32c3ed98a Signed-off-by: Duncan Laurie Reviewed-on: https://chromium-review.googlesource.com/497932 Reviewed-by: Randall Spangler --- futility/kernel_blob.h | 3 +++ futility/vb1_helper.c | 14 +++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/futility/kernel_blob.h b/futility/kernel_blob.h index ab1c82fd..1ee4ea7b 100644 --- a/futility/kernel_blob.h +++ b/futility/kernel_blob.h @@ -7,6 +7,9 @@ #ifndef VBOOT_REFERENCE_KERNEL_BLOB_H_ #define VBOOT_REFERENCE_KERNEL_BLOB_H_ +/* Linux vmlinuz header signature */ +#define VMLINUZ_HEADER_SIG 0x53726448 + /* Maximum kernel command-line size */ #define CROS_CONFIG_SIZE 4096 diff --git a/futility/vb1_helper.c b/futility/vb1_helper.c index fb9022f0..18caf1f3 100644 --- a/futility/vb1_helper.c +++ b/futility/vb1_helper.c @@ -146,6 +146,10 @@ static int KernelSize(uint8_t *kernel_buf, /* The first part of the x86 vmlinuz is a header, followed by * a real-mode boot stub. We only want the 32-bit part. */ lh = (struct linux_kernel_params *)kernel_buf; + if (lh->header != VMLINUZ_HEADER_SIG) { + Debug("Not a linux kernel image\n"); + return kernel_size; + } kernel32_start = (lh->setup_sects + 1) << 9; if (kernel32_start >= kernel_size) { fprintf(stderr, "Malformed kernel\n"); @@ -166,10 +170,15 @@ static int PickApartVmlinuz(uint8_t *kernel_buf, struct linux_kernel_params *lh, *params; /* Except for x86, the kernel is the kernel. */ - if (arch == ARCH_X86) { + switch (arch) { + case ARCH_X86: /* The first part of the x86 vmlinuz is a header, followed by * a real-mode boot stub. We only want the 32-bit part. */ lh = (struct linux_kernel_params *)kernel_buf; + if (lh->header != VMLINUZ_HEADER_SIG) { + Debug("Not a linux kernel image\n"); + break; + } kernel32_start = (lh->setup_sects + 1) << 9; if (kernel32_start >= kernel_size) { fprintf(stderr, "Malformed kernel\n"); @@ -207,6 +216,9 @@ static int PickApartVmlinuz(uint8_t *kernel_buf, params->e820_entries[1].start_addr = 0xfffff000; params->e820_entries[1].segment_size = 0x00001000; params->e820_entries[1].segment_type = E820_TYPE_RESERVED; + break; + default: + break; } Debug(" kernel32_start=0x%" PRIx64 "\n", kernel32_start); -- cgit v1.2.1