diff options
author | Michael Brown <mcb30@ipxe.org> | 2023-11-27 12:08:19 +0000 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2023-11-27 12:42:58 +0000 |
commit | a147245f1a2f92a85a75226ea921acb22322ab4d (patch) | |
tree | 60926cab917e2e6e46fb5c846d631f3e21bc6783 | |
parent | c3dd3168c916f624af1b843515c1305387060611 (diff) | |
download | ipxe-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.c | 25 |
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 ) { |