summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Bishop <nicholasbishop@google.com>2022-09-15 19:26:01 -0400
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-09-20 13:39:05 +0000
commit956c2efb0af310a3089b362fdb5d5f70238758f2 (patch)
tree9456cb00ba939c9841b87d53237a335f2ba2194e
parent9f2e9804b492f8fccc060e013b12de9679cca246 (diff)
downloadvboot-956c2efb0af310a3089b362fdb5d5f70238758f2.tar.gz
futility: Skip picking apart an x86 kernel if has the EFI stub
Crdyboot uses the kernel's own EFI boot stub to actually launch the kernel, so the "pick apart" operations done by futility on x86 kernels aren't desired. Skip those operations if the kernel contains the builtin EFI stub. This will only affect the reven board, as only the reven kernel config has CONFIG_EFI_STUB enabled. To detect whether the kernel was built with the EFI stub, check the first two bytes of kernel data for the COFF header magic bytes "MZ". Tested by running `vbutil_kernel --pack` on two amd64 kernels, one with CONFIG_EFI_STUB enabled and one with it disabled. Full command: futility --debug vbutil_kernel --pack out.img --keyblock /usr/share/vboot/devkeys/recovery_kernel.keyblock --signprivate /usr/share/vboot/devkeys/recovery_kernel_data_key.vbprivk --version 1 --config config.txt --bootloader /lib64/bootstub/bootstub.efi --vmlinuz vmlinuz.bin --arch amd64 In the kernel with the EFI stub the debug output includes "EFI boot stub detected", the other one does not. BUG=b:238316304 TEST=Test two kernels as described above TEST=Test booting through crdyboot BRANCH=none Signed-off-by: Nicholas Bishop <nicholasbishop@google.com> Change-Id: I14640eadce2a1e41a262921cb6ab96962b6b3a22 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/3900403 Reviewed-by: Julius Werner <jwerner@chromium.org> Reviewed-by: Hung-Te Lin <hungte@chromium.org> Reviewed-by: Yu-Ping Wu <yupingso@chromium.org>
-rw-r--r--futility/vb1_helper.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/futility/vb1_helper.c b/futility/vb1_helper.c
index 2a0e87a2..5a8908e6 100644
--- a/futility/vb1_helper.c
+++ b/futility/vb1_helper.c
@@ -1,4 +1,4 @@
-/* Copyright 2014 The Chromium OS Authors. All rights reserved.
+/* Copyright 2014 The ChromiumOS Authors
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
@@ -129,6 +129,18 @@ uint64_t kernel_cmd_line_offset(const struct vb2_kernel_preamble *preamble)
CROS_CONFIG_SIZE - CROS_PARAMS_SIZE;
}
+/* Returns whether the kernel CONFIG_EFI_STUB enabled. */
+static int KernelHasEfiBootStub(const uint8_t *kernel_buf,
+ uint32_t kernel_size)
+{
+ if (kernel_size < 2)
+ return 0;
+
+ /* If the stub is enabled then the kernel data will start with
+ * the COFF header, which begins with the magic bytes "MZ". */
+ return kernel_buf[0] == 'M' && kernel_buf[1] == 'Z';
+}
+
/* Returns the size of the 32-bit kernel, or negative on error. */
static int KernelSize(uint8_t *kernel_buf,
uint32_t kernel_size,
@@ -138,7 +150,7 @@ static int KernelSize(uint8_t *kernel_buf,
struct linux_kernel_params *lh;
/* Except for x86, the kernel is the kernel. */
- if (arch != ARCH_X86)
+ if (arch != ARCH_X86 || KernelHasEfiBootStub(kernel_buf, kernel_size))
return kernel_size;
/* The first part of the x86 vmlinuz is a header, followed by
@@ -170,6 +182,13 @@ static int PickApartVmlinuz(uint8_t *kernel_buf,
/* Except for x86, the kernel is the kernel. */
switch (arch) {
case ARCH_X86:
+ /* If the kernel has the EFI boot stub enabled, don't
+ * modify the kernel buffer. */
+ if (KernelHasEfiBootStub(kernel_buf, kernel_size)) {
+ VB2_DEBUG("EFI boot stub detected\n");
+ break;
+ }
+
/* 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;