From a147245f1a2f92a85a75226ea921acb22322ab4d Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Mon, 27 Nov 2023 12:08:19 +0000 Subject: [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 --- src/util/elf2efi.c | 25 +++++++++++++++++++++++-- 1 file 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 ) { -- cgit v1.1