aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArd Biesheuvel <ardb@kernel.org>2022-08-17 17:54:57 +0200
committerArd Biesheuvel <ardb@kernel.org>2022-09-05 18:15:39 +0200
commit00c11f81336fc66d58519ce9ff75aeecde8fdc6e (patch)
treedc9f2457213df2f5a0089d067650ad440cc2d561
parentc83511d70e6c37d4df6be70cd95760e0bcc001c1 (diff)
downloadgrub-00c11f81336fc66d58519ce9ff75aeecde8fdc6e.tar.gz
linux/arm: account for COFF headers appearing at unexpected offsets
The way we load the Linux and PE/COFF image headers depends on a fixed placement of the COFF header at offset 0x40 into the file. This is a reasonable default, given that this is where Linux emits it today. However, in order to comply with the PE/COFF spec, which allows this header to appear anywhere in the file, let's ensure that we read the header from where it actually appears in the file if it is not located at offset 0x40. Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
-rw-r--r--grub-core/loader/arm64/linux.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
index 7c0f17cf9..56ba8d0a6 100644
--- a/grub-core/loader/arm64/linux.c
+++ b/grub-core/loader/arm64/linux.c
@@ -63,6 +63,21 @@ grub_arch_efi_linux_load_image_header (grub_file_t file,
grub_dprintf ("linux", "UEFI stub kernel:\n");
grub_dprintf ("linux", "PE/COFF header @ %08x\n", lh->hdr_offset);
+ /*
+ * The PE/COFF spec permits the COFF header to appear anywhere in the file, so
+ * we need to double check whether it was where we expected it, and if not, we
+ * must load it from the correct offset into the coff_image_header field of
+ * struct linux_arch_kernel_header.
+ */
+ if ((grub_uint8_t *) lh + lh->hdr_offset != (grub_uint8_t *) &lh->coff_image_header)
+ {
+ grub_file_seek (file, lh->hdr_offset);
+
+ if (grub_file_read (file, &lh->coff_image_header, sizeof(struct grub_coff_image_header))
+ != sizeof(struct grub_coff_image_header))
+ return grub_error(GRUB_ERR_FILE_READ_ERROR, "failed to read COFF image header");
+ }
+
return GRUB_ERR_NONE;
}