summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Coulson <chris.coulson@canonical.com>2022-05-03 15:41:00 +0200
committerPeter Jones <pjones@redhat.com>2022-05-24 16:28:35 -0400
commite99bdbb827a50cde019393d3ca1e89397db221a7 (patch)
tree2394f33a580cebc6f9e2093bb23fc46096b612f2
parent77144e5a404df89b45941bfc54fd2f59e0ee607b (diff)
downloadefi-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.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/pe.c b/pe.c
index 5d0c6b0b..1eb3f59a 100644
--- a/pe.c
+++ b/pe.c
@@ -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);
}
}