MdeModulePkg: DxeCore: Check overflow before using resource hob memory top

Current GCD logic uses plain addition calulation when iterating through
the resource descriptor hobs. However, if the resource descriptor is
incorrectly prepared, this could cause incorrect memory initialization
and other failures down the boot process.

This change adds an overflow check before using the value.

Signed-off-by: Kun Qin <kun.qin@microsoft.com>
This commit is contained in:
Kun Qin 2025-10-30 11:30:23 -07:00 committed by mergify[bot]
parent e93ee87643
commit 5be1bccd9c

View file

@ -2274,6 +2274,7 @@ CoreInitializeMemoryServices (
EFI_HOB_GUID_TYPE *GuidHob;
UINT32 ReservedCodePageNumber;
UINT64 MinimalMemorySizeNeeded;
EFI_PHYSICAL_ADDRESS ResourceHobMemoryTop;
//
// Point at the first HOB. This must be the PHIT HOB.
@ -2395,7 +2396,17 @@ CoreInitializeMemoryServices (
continue;
}
if (PhitHob->EfiFreeMemoryTop > (ResourceHob->PhysicalStart + ResourceHob->ResourceLength)) {
//
// Check for potential overflow before addition
//
if (ResourceHob->PhysicalStart > MAX_UINT64 - ResourceHob->ResourceLength) {
ASSERT (FALSE);
ResourceHobMemoryTop = MAX_UINT64;
} else {
ResourceHobMemoryTop = ResourceHob->PhysicalStart + ResourceHob->ResourceLength;
}
if (PhitHob->EfiFreeMemoryTop > ResourceHobMemoryTop) {
continue;
}
@ -2419,7 +2430,7 @@ CoreInitializeMemoryServices (
//
Attributes = PhitResourceHob->ResourceAttribute;
BaseAddress = PageAlignAddress (PhitHob->EfiMemoryTop);
Length = PageAlignLength (ResourceHob->PhysicalStart + ResourceHob->ResourceLength - BaseAddress);
Length = PageAlignLength (ResourceHobMemoryTop - BaseAddress);
FindLargestFreeRegion (&BaseAddress, &Length, (EFI_HOB_MEMORY_ALLOCATION *)GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION));
if (Length < MinimalMemorySizeNeeded) {
//
@ -2496,7 +2507,17 @@ CoreInitializeMemoryServices (
continue;
}
if ((ResourceHob->PhysicalStart + ResourceHob->ResourceLength) > (EFI_PHYSICAL_ADDRESS)MAX_ALLOC_ADDRESS) {
//
// Check for potential overflow before addition
//
if (ResourceHob->PhysicalStart > MAX_UINT64 - ResourceHob->ResourceLength) {
ASSERT (FALSE);
ResourceHobMemoryTop = MAX_UINT64;
} else {
ResourceHobMemoryTop = ResourceHob->PhysicalStart + ResourceHob->ResourceLength;
}
if (ResourceHobMemoryTop > (EFI_PHYSICAL_ADDRESS)MAX_ALLOC_ADDRESS) {
continue;
}
@ -2511,7 +2532,7 @@ CoreInitializeMemoryServices (
// Skip Resource Descriptor HOBs that are not large enough to initilize the DXE Core
//
TestedMemoryBaseAddress = PageAlignAddress (ResourceHob->PhysicalStart);
TestedMemoryLength = PageAlignLength (ResourceHob->PhysicalStart + ResourceHob->ResourceLength - TestedMemoryBaseAddress);
TestedMemoryLength = PageAlignLength (ResourceHobMemoryTop - TestedMemoryBaseAddress);
FindLargestFreeRegion (&TestedMemoryBaseAddress, &TestedMemoryLength, (EFI_HOB_MEMORY_ALLOCATION *)GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION));
if (TestedMemoryLength < MinimalMemorySizeNeeded) {
continue;