On Fri, 30 Oct 2026 at 08:13, Ana Bobillo <[email protected]> wrote: > > From: Ana Bobillo <[email protected]> > > efi_load_pe() computes the end of each section as the sum of its > VirtualAddress and its size, both u32, so the sum wraps around before it > is widened to unsigned long. A section near 4 GiB then yields a small > virt_size, and the memset() and memcpy() of the section write far past > the allocated image. > > Relative virtual addresses are 32 bit, so reject a section whose end > does not fit into 32 bits. barebox, whose EFI loader is based on this > file, fixed the same in b6598389d46d ("efi: loader: fix integer overflow > in PE virt_size calculation"). > > This runs before the image is rejected when Secure Boot fails to verify > it. > > Fixes: cb149c66342c ("efi_loader: Add PE image loader") > Signed-off-by: Ana Bobillo <[email protected]> > ---
Reviewed-by: Ilias Apalodimas <[email protected]> > lib/efi_loader/efi_image_loader.c | 15 +++++++++++++-- > 1 file changed, 13 insertions(+), 2 deletions(-) > > diff --git a/lib/efi_loader/efi_image_loader.c > b/lib/efi_loader/efi_image_loader.c > index 35cf3cd268f..b15a662e5d6 100644 > --- a/lib/efi_loader/efi_image_loader.c > +++ b/lib/efi_loader/efi_image_loader.c > @@ -1062,9 +1062,20 @@ efi_status_t efi_load_pe(struct efi_loaded_image_obj > *handle, > /* Calculate upper virtual address boundary */ > for (i = num_sections - 1; i >= 0; i--) { > IMAGE_SECTION_HEADER *sec = §ions[i]; > + u32 end; > > - virt_size = max_t(unsigned long, virt_size, > - sec->VirtualAddress + section_size(sec)); > + /* > + * Relative virtual addresses are 32 bit. A section whose end > + * wraps around would make virt_size too small for the > memset() > + * and memcpy() below. > + */ > + if (__builtin_add_overflow(sec->VirtualAddress, > + section_size(sec), &end)) { > + log_err("Section %d virtual address overflow\n", i); > + return EFI_LOAD_ERROR; > + } > + > + virt_size = max_t(unsigned long, virt_size, end); > } > > /* Read 32/64bit specific header bits */
