@param[in] Size2 Size of Buff2\r
\r
@retval TRUE Buffers overlap in memory.\r
+ @retval TRUE Math error. Prevents potential math over and underflows.\r
@retval FALSE Buffer doesn't overlap.\r
\r
**/\r
IN UINTN Size2\r
)\r
{\r
+ UINTN End1;\r
+ UINTN End2;\r
+ BOOLEAN IsOverUnderflow1;\r
+ BOOLEAN IsOverUnderflow2;\r
+\r
+ // Check for over or underflow\r
+ IsOverUnderflow1 = EFI_ERROR (SafeUintnAdd ((UINTN)Buff1, Size1, &End1));\r
+ IsOverUnderflow2 = EFI_ERROR (SafeUintnAdd ((UINTN)Buff2, Size2, &End2));\r
+\r
+ if (IsOverUnderflow1 || IsOverUnderflow2) {\r
+ return TRUE;\r
+ }\r
+\r
//\r
// If buff1's end is less than the start of buff2, then it's ok.\r
// Also, if buff1's start is beyond buff2's end, then it's ok.\r
//\r
- if (((Buff1 + Size1) <= Buff2) || (Buff1 >= (Buff2 + Size2))) {\r
+ if ((End1 <= (UINTN)Buff2) || ((UINTN)Buff1 >= End2)) {\r
return FALSE;\r
}\r
\r
EFI_SMM_COMMUNICATE_HEADER *CommunicateHeader;\r
BOOLEAN InLegacyBoot;\r
BOOLEAN IsOverlapped;\r
+ BOOLEAN IsOverUnderflow;\r
VOID *CommunicationBuffer;\r
UINTN BufferSize;\r
\r
(UINT8 *)gSmmCorePrivate,\r
sizeof (*gSmmCorePrivate)\r
);\r
- if (!SmmIsBufferOutsideSmmValid ((UINTN)CommunicationBuffer, BufferSize) || IsOverlapped) {\r
+ //\r
+ // Check for over or underflows\r
+ //\r
+ IsOverUnderflow = EFI_ERROR (SafeUintnSub (BufferSize, OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data), &BufferSize));\r
+\r
+ if (!SmmIsBufferOutsideSmmValid ((UINTN)CommunicationBuffer, BufferSize) ||\r
+ IsOverlapped || IsOverUnderflow)\r
+ {\r
//\r
// If CommunicationBuffer is not in valid address scope,\r
// or there is overlap between gSmmCorePrivate and CommunicationBuffer,\r
+ // or there is over or underflow,\r
// return EFI_INVALID_PARAMETER\r
//\r
gSmmCorePrivate->CommunicationBuffer = NULL;\r
gSmmCorePrivate->ReturnStatus = EFI_ACCESS_DENIED;\r
} else {\r
CommunicateHeader = (EFI_SMM_COMMUNICATE_HEADER *)CommunicationBuffer;\r
- BufferSize -= OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data);\r
- Status = SmiManage (\r
- &CommunicateHeader->HeaderGuid,\r
- NULL,\r
- CommunicateHeader->Data,\r
- &BufferSize\r
- );\r
+ // BufferSize was updated by the SafeUintnSub() call above.\r
+ Status = SmiManage (\r
+ &CommunicateHeader->HeaderGuid,\r
+ NULL,\r
+ CommunicateHeader->Data,\r
+ &BufferSize\r
+ );\r
//\r
// Update CommunicationBuffer, BufferSize and ReturnStatus\r
// Communicate service finished, reset the pointer to CommBuffer to NULL\r
#include <Library/UefiRuntimeLib.h>\r
#include <Library/PcdLib.h>\r
#include <Library/ReportStatusCodeLib.h>\r
-\r
#include "PiSmmCorePrivateData.h"\r
+#include <Library/SafeIntLib.h>\r
\r
#define SMRAM_CAPABILITIES (EFI_MEMORY_WB | EFI_MEMORY_UC)\r
\r
@param[in] ReservedRangeToCompare Pointer to EFI_SMM_RESERVED_SMRAM_REGION to compare.\r
\r
@retval TRUE There is overlap.\r
+ @retval TRUE Math error.\r
@retval FALSE There is no overlap.\r
\r
**/\r
IN EFI_SMM_RESERVED_SMRAM_REGION *ReservedRangeToCompare\r
)\r
{\r
- UINT64 RangeToCompareEnd;\r
- UINT64 ReservedRangeToCompareEnd;\r
-\r
- RangeToCompareEnd = RangeToCompare->CpuStart + RangeToCompare->PhysicalSize;\r
- ReservedRangeToCompareEnd = ReservedRangeToCompare->SmramReservedStart + ReservedRangeToCompare->SmramReservedSize;\r
+ UINT64 RangeToCompareEnd;\r
+ UINT64 ReservedRangeToCompareEnd;\r
+ BOOLEAN IsOverUnderflow1;\r
+ BOOLEAN IsOverUnderflow2;\r
+\r
+ // Check for over or underflow.\r
+ IsOverUnderflow1 = EFI_ERROR (\r
+ SafeUint64Add (\r
+ (UINT64)RangeToCompare->CpuStart,\r
+ RangeToCompare->PhysicalSize,\r
+ &RangeToCompareEnd\r
+ )\r
+ );\r
+ IsOverUnderflow2 = EFI_ERROR (\r
+ SafeUint64Add (\r
+ (UINT64)ReservedRangeToCompare->SmramReservedStart,\r
+ ReservedRangeToCompare->SmramReservedSize,\r
+ &ReservedRangeToCompareEnd\r
+ )\r
+ );\r
+ if (IsOverUnderflow1 || IsOverUnderflow2) {\r
+ return TRUE;\r
+ }\r
\r
if ((RangeToCompare->CpuStart >= ReservedRangeToCompare->SmramReservedStart) &&\r
(RangeToCompare->CpuStart < ReservedRangeToCompareEnd))\r