63 lines
2.1 KiB
Diff
63 lines
2.1 KiB
Diff
From e99bdbb827a50cde019393d3ca1e89397db221a7 Mon Sep 17 00:00:00 2001
|
|
From: Chris Coulson <chris.coulson@canonical.com>
|
|
Date: Tue, 3 May 2022 15:41:00 +0200
|
|
Subject: [PATCH] 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>
|
|
---
|
|
pe.c | 15 +++++++++------
|
|
1 file changed, 9 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/pe.c b/pe.c
|
|
index 5d0c6b0..1eb3f59 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);
|
|
}
|
|
}
|
|
|
|
--
|
|
2.27.0
|
|
|