diff options
| author | Chris Coulson <chris.coulson@canonical.com> | 2022-05-03 15:41:00 +0200 |
|---|---|---|
| committer | Peter Jones <pjones@redhat.com> | 2022-05-24 16:28:35 -0400 |
| commit | e99bdbb827a50cde019393d3ca1e89397db221a7 (patch) | |
| tree | 2394f33a580cebc6f9e2093bb23fc46096b612f2 | |
| parent | 77144e5a404df89b45941bfc54fd2f59e0ee607b (diff) | |
| download | efi-boot-shim-e99bdbb827a50cde019393d3ca1e89397db221a7.tar.gz efi-boot-shim-e99bdbb827a50cde019393d3ca1e89397db221a7.zip | |
pe: Fix a buffer overflow when SizeOfRawData > VirtualSize
During image loading, the size of the destination buffer for the image
is determined by the SizeOfImage field in the optional header. The start
and end virtual addresses of each section, as determined by each section's
VirtualAddress and VirtualSize fields, are bounds checked against the
allocated buffer. However, the amount of data copied to the destination
buffer is determined by the section's SizeOfRawData filed. If this is
larger than the VirtualSize, then the copy can overflow the destination
buffer.
Fix this by limiting the amount of data to copy to the section's
VirtualSize. In the case where a section has SizeOfRawData > VirtualSize,
the excess data is discarded.
This fixes CVE-2022-28737
Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
| -rw-r--r-- | pe.c | 15 |
1 files changed, 9 insertions, 6 deletions
@@ -1089,6 +1089,7 @@ handle_image (void *data, unsigned int datasize, int i; EFI_IMAGE_SECTION_HEADER *Section; char *base, *end; + UINT32 size; PE_COFF_LOADER_IMAGE_CONTEXT context; unsigned int alignment, alloc_size; int found_entry_point = 0; @@ -1274,13 +1275,15 @@ handle_image (void *data, unsigned int datasize, return EFI_UNSUPPORTED; } - if (Section->SizeOfRawData > 0) - CopyMem(base, data + Section->PointerToRawData, - Section->SizeOfRawData); + size = Section->Misc.VirtualSize; + if (size > Section->SizeOfRawData) + size = Section->SizeOfRawData; - if (Section->SizeOfRawData < Section->Misc.VirtualSize) - ZeroMem(base + Section->SizeOfRawData, - Section->Misc.VirtualSize - Section->SizeOfRawData); + if (size > 0) + CopyMem(base, data + Section->PointerToRawData, size); + + if (size < Section->Misc.VirtualSize) + ZeroMem(base + size, Section->Misc.VirtualSize - size); } } |
