StandaloneMmPkg: StandaloneMmIplPei: Use SafeIntLib for safe arithmetics

This change adds the SafeIntLib to communication input routine to
validate the incoming MM communication buffer length before using.

Signed-off-by: Kun Qin <kun.qin@microsoft.com>
This commit is contained in:
Kun Qin 2026-07-10 16:04:53 -07:00
parent 9e43f2f6d4
commit 8ef258eff0
3 changed files with 40 additions and 8 deletions

View file

@ -61,6 +61,7 @@ Communicate (
EFI_HOB_GUID_TYPE *GuidHob;
MM_COMM_BUFFER *MmCommBuffer;
MM_COMM_BUFFER_STATUS *MmCommBufferStatus;
UINTN MaxBufferSize;
DEBUG ((DEBUG_INFO, "StandaloneMmIpl Communicate Enter\n"));
@ -92,8 +93,14 @@ Communicate (
}
}
if (TempCommSize > EFI_PAGES_TO_SIZE (MmCommBuffer->NumberOfPages)) {
DEBUG ((DEBUG_ERROR, "Communicate buffer size (%d) is over MAX (%d) size!", TempCommSize, EFI_PAGES_TO_SIZE (MmCommBuffer->NumberOfPages)));
Status = SafeUintnMult (MmCommBuffer->NumberOfPages, EFI_PAGE_SIZE, &MaxBufferSize);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Overflow occurred while calculating MaxBufferSize!\n"));
return EFI_INVALID_PARAMETER;
}
if (TempCommSize > MaxBufferSize) {
DEBUG ((DEBUG_ERROR, "Communicate buffer size (%d) is over MAX (%d) size!", TempCommSize, MaxBufferSize));
return EFI_INVALID_PARAMETER;
}
@ -119,7 +126,17 @@ Communicate (
//
// Return status from software SMI
//
*CommSize = (UINTN)MmCommBufferStatus->ReturnBufferSize;
Status = SafeUint64ToUintn (MmCommBufferStatus->ReturnBufferSize, CommSize);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Overflow occurred while converting ReturnBufferSize to CommSize!\n"));
return EFI_BAD_BUFFER_SIZE;
}
if (*CommSize > TempCommSize) {
DEBUG ((DEBUG_ERROR, "Returned buffer size is larger than the Communication Buffer, TempCommSize: 0x%llx, ReturnBufferSize: 0x%llx\n", TempCommSize, *CommSize));
ASSERT (*CommSize <= TempCommSize);
return EFI_BAD_BUFFER_SIZE;
}
//
// Copy the returned data to the non-mmram buffer (CommBuffer)
@ -157,12 +174,13 @@ Communicate3 (
EFI_STATUS Status;
EFI_PEI_MM_CONTROL_PPI *MmControl;
UINT8 SmiCommand;
UINTN Size;
UINTN TempCommSize;
UINT64 Size;
UINT64 TempCommSize;
EFI_HOB_GUID_TYPE *GuidHob;
MM_COMM_BUFFER *MmCommBuffer;
MM_COMM_BUFFER_STATUS *MmCommBufferStatus;
EFI_MM_COMMUNICATE_HEADER_V3 *CommunicateHeader;
UINT64 MaxBufferSize;
DEBUG ((DEBUG_INFO, "StandaloneMmIpl Communicate Enter\n"));
@ -204,8 +222,14 @@ Communicate3 (
}
}
if (TempCommSize > EFI_PAGES_TO_SIZE (MmCommBuffer->NumberOfPages)) {
DEBUG ((DEBUG_ERROR, "Communicate buffer size (%d) is over MAX (%d) size!", TempCommSize, EFI_PAGES_TO_SIZE (MmCommBuffer->NumberOfPages)));
Status = SafeUint64Mult (MmCommBuffer->NumberOfPages, EFI_PAGE_SIZE, &MaxBufferSize);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Overflow occurred while calculating MaxBufferSize!\n"));
return EFI_INVALID_PARAMETER;
}
if (TempCommSize > MaxBufferSize) {
DEBUG ((DEBUG_ERROR, "Communicate buffer size (%d) is over MAX (%d) size!", TempCommSize, MaxBufferSize));
return EFI_INVALID_PARAMETER;
}
@ -231,7 +255,13 @@ Communicate3 (
//
// Return status from software SMI
//
TempCommSize = (UINTN)MmCommBufferStatus->ReturnBufferSize;
if (MmCommBufferStatus->ReturnBufferSize > TempCommSize) {
DEBUG ((DEBUG_ERROR, "Returned buffer size is larger than the Communication Buffer, TempCommSize: 0x%llx, ReturnBufferSize: 0x%llx\n", TempCommSize, MmCommBufferStatus->ReturnBufferSize));
ASSERT (MmCommBufferStatus->ReturnBufferSize <= TempCommSize);
return EFI_BAD_BUFFER_SIZE;
}
TempCommSize = MmCommBufferStatus->ReturnBufferSize;
//
// Copy the returned data to the non-mmram buffer (CommBuffer)

View file

@ -27,6 +27,7 @@
#include <Ppi/MmCoreFvLocationPpi.h>
#include <Protocol/MmCommunication.h>
#include <Library/MmPlatformHobProducerLib.h>
#include <Library/SafeIntLib.h>
/**
Communicates with a registered handler.

View file

@ -44,6 +44,7 @@
PeCoffLib
CacheMaintenanceLib
MmPlatformHobProducerLib
SafeIntLib
[Guids]
gMmCommBufferHobGuid