From: Michael Brown Date: Tue, 11 Jan 2022 15:27:14 +0000 (+0000) Subject: [efi] Do not align VirtualSize for .reloc and .debug sections X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=91c77e2592f5b0e1098d3f341827d7e6925e4a85;p=thirdparty%2Fipxe.git [efi] Do not align VirtualSize for .reloc and .debug sections As of commit f1e9e2b ("[efi] Align EFI image sections by page size"), the VirtualSize fields for the .reloc and .debug sections have been rounded up to the (4kB) image alignment. This breaks the PE relocation logic in the UEFI shim, which requires the VirtualSize field to exactly match the size as recorded in the data directory. Fix by setting the VirtualSize field to the unaligned size of the section, as is already done for normal PE sections (i.e. those other than .reloc and .debug). Signed-off-by: Michael Brown --- diff --git a/src/util/elf2efi.c b/src/util/elf2efi.c index 8af53aeb4..08d790f1e 100644 --- a/src/util/elf2efi.c +++ b/src/util/elf2efi.c @@ -753,15 +753,13 @@ static struct pe_section * create_reloc_section ( struct pe_header *pe_header, struct pe_relocs *pe_reltab ) { struct pe_section *reloc; - size_t section_rawsz; size_t section_memsz; size_t section_filesz; EFI_IMAGE_DATA_DIRECTORY *relocdir; /* Allocate PE section */ - section_rawsz = output_pe_reltab ( pe_reltab, NULL ); - section_filesz = efi_file_align ( section_rawsz ); - section_memsz = efi_image_align ( section_rawsz ); + section_memsz = output_pe_reltab ( pe_reltab, NULL ); + section_filesz = efi_file_align ( section_memsz ); reloc = xmalloc ( sizeof ( *reloc ) + section_filesz ); memset ( reloc, 0, sizeof ( *reloc ) + section_filesz ); @@ -782,11 +780,12 @@ create_reloc_section ( struct pe_header *pe_header, /* Update file header details */ pe_header->nt.FileHeader.NumberOfSections++; pe_header->nt.OptionalHeader.SizeOfHeaders += sizeof ( reloc->hdr ); - pe_header->nt.OptionalHeader.SizeOfImage += section_memsz; + pe_header->nt.OptionalHeader.SizeOfImage += + efi_image_align ( section_memsz ); relocdir = &(pe_header->nt.OptionalHeader.DataDirectory [EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC]); relocdir->VirtualAddress = reloc->hdr.VirtualAddress; - relocdir->Size = section_rawsz; + relocdir->Size = section_memsz; return reloc; } @@ -824,8 +823,8 @@ create_debug_section ( struct pe_header *pe_header, const char *filename ) { } *contents; /* Allocate PE section */ - section_memsz = efi_image_align ( sizeof ( *contents ) ); - section_filesz = efi_file_align ( sizeof ( *contents ) ); + section_memsz = sizeof ( *contents ); + section_filesz = efi_file_align ( section_memsz ); debug = xmalloc ( sizeof ( *debug ) + section_filesz ); memset ( debug, 0, sizeof ( *debug ) + section_filesz ); contents = ( void * ) debug->contents; @@ -857,7 +856,8 @@ create_debug_section ( struct pe_header *pe_header, const char *filename ) { /* Update file header details */ pe_header->nt.FileHeader.NumberOfSections++; pe_header->nt.OptionalHeader.SizeOfHeaders += sizeof ( debug->hdr ); - pe_header->nt.OptionalHeader.SizeOfImage += section_memsz; + pe_header->nt.OptionalHeader.SizeOfImage += + efi_image_align ( section_memsz ); debugdir = &(pe_header->nt.OptionalHeader.DataDirectory [EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]); debugdir->VirtualAddress = debug->hdr.VirtualAddress;