summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brown2023-11-27 13:08:19 +0100
committerMichael Brown2023-11-27 13:42:58 +0100
commita147245f1a2f92a85a75226ea921acb22322ab4d (patch)
tree60926cab917e2e6e46fb5c846d631f3e21bc6783
parent[efi] Fix dependency list construction in EDK2 header import script (diff)
downloadipxe-a147245f1a2f92a85a75226ea921acb22322ab4d.tar.gz
ipxe-a147245f1a2f92a85a75226ea921acb22322ab4d.tar.xz
ipxe-a147245f1a2f92a85a75226ea921acb22322ab4d.zip
[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 e9760139..a3aff8f1 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 ) {