aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2023-11-27 12:08:19 +0000
committerMichael Brown <mcb30@ipxe.org>2023-11-27 12:42:58 +0000
commita147245f1a2f92a85a75226ea921acb22322ab4d (patch)
tree60926cab917e2e6e46fb5c846d631f3e21bc6783
parentc3dd3168c916f624af1b843515c1305387060611 (diff)
downloadipxe-a147245f1a2f92a85a75226ea921acb22322ab4d.zip
ipxe-a147245f1a2f92a85a75226ea921acb22322ab4d.tar.gz
ipxe-a147245f1a2f92a85a75226ea921acb22322ab4d.tar.bz2
[efi] Extend PE header size to cover space up to first section
Hybrid bzImage and UEFI binaries (such as wimboot) may place sections at explicit offsets within the PE file, as described in commit b30a098 ("[efi] Use load memory address as file offset for hybrid binaries"). This can leave a gap after the PE headers that is not covered by any section. It is not entirely clear whether or not such gaps are permitted in binaries submitted for Secure Boot signing. To minimise potential problems, extend the PE header size to cover any space before the first explicitly placed section. Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r--src/util/elf2efi.c25
1 files changed, 23 insertions, 2 deletions
diff --git a/src/util/elf2efi.c b/src/util/elf2efi.c
index e976013..a3aff8f 100644
--- a/src/util/elf2efi.c
+++ b/src/util/elf2efi.c
@@ -1020,13 +1020,34 @@ static void write_pe_file ( struct pe_header *pe_header,
struct pe_section *pe_sections,
FILE *pe ) {
struct pe_section *section;
- unsigned long fpos = 0;
- unsigned long fposmax = 0;
+ unsigned long hdrmax;
+ unsigned long fpos;
+ unsigned long fposmax;
unsigned int count = 0;
+ /* Extend header length to reach first explicitly placed section */
+ hdrmax = -1UL;
+ for ( section = pe_sections ; section ; section = section->next ) {
+ if ( ( section->hdr.PointerToRawData != PTRD_AUTO ) &&
+ ( section->hdr.SizeOfRawData > 0 ) &&
+ ( ! section->hidden ) &&
+ ( hdrmax > section->hdr.PointerToRawData ) ) {
+ hdrmax = section->hdr.PointerToRawData;
+ }
+ }
+ if ( ( hdrmax != -1UL ) &&
+ ( pe_header->nt.OptionalHeader.SizeOfHeaders < hdrmax ) ) {
+ pe_header->nt.OptionalHeader.SizeOfHeaders = hdrmax;
+ }
+
/* Align length of headers */
fpos = fposmax = pe_header->nt.OptionalHeader.SizeOfHeaders =
efi_file_align ( pe_header->nt.OptionalHeader.SizeOfHeaders );
+ if ( fpos > hdrmax ) {
+ eprintf ( "Cannot fit %lx bytes of headers before section at "
+ "file offset %lx\n", fpos, hdrmax );
+ exit ( 1 );
+ }
/* Assign raw data pointers */
for ( section = pe_sections ; section ; section = section->next ) {