Checking if gSmmCorePrivate->CommunicationBuffer is in supported physical address scope.

If CommunicationBuffer is not in valid address scope, return EFI_INVALID_PARAMETER.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jeff Fan <Jeff.fan@intel.com>
Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>










git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16486 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Jeff Fan 2014-12-09 02:20:16 +00:00 committed by vanjeff
parent baaacdc823
commit 3720ee6d32
3 changed files with 105 additions and 16 deletions

View File

@ -85,6 +85,11 @@ SMM_CORE_SMI_HANDLERS mSmmCoreSmiHandlers[] = {
UINTN mFullSmramRangeCount;
EFI_SMRAM_DESCRIPTOR *mFullSmramRanges;
//
// Maximum support address used to check input CommunicationBuffer
//
UINTN mMaximumSupportAddress = 0;
/**
Place holder function until all the SMM System Table Service are available.
@ -274,6 +279,76 @@ SmmEndOfDxeHandler (
return Status;
}
/**
Caculate and save the maximum support address.
**/
VOID
CaculateMaximumSupportAddress (
VOID
)
{
VOID *Hob;
UINT32 RegEax;
UINT8 PhysicalAddressBits;
//
// Get physical address bits supported.
//
Hob = GetFirstHob (EFI_HOB_TYPE_CPU);
if (Hob != NULL) {
PhysicalAddressBits = ((EFI_HOB_CPU *) Hob)->SizeOfMemorySpace;
} else {
AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
if (RegEax >= 0x80000008) {
AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
PhysicalAddressBits = (UINT8) RegEax;
} else {
PhysicalAddressBits = 36;
}
}
//
// IA-32e paging translates 48-bit linear addresses to 52-bit physical addresses.
//
ASSERT (PhysicalAddressBits <= 52);
if (PhysicalAddressBits > 48) {
PhysicalAddressBits = 48;
}
//
// Save the maximum support address in one global variable
//
mMaximumSupportAddress = (UINTN) (LShiftU64 (1, PhysicalAddressBits) - 1);
DEBUG ((EFI_D_INFO, "mMaximumSupportAddress = 0x%lx\n", mMaximumSupportAddress));
}
/**
Check if input buffer is in valid address scope or not.
@param[in] Pointer Pointer to the input buffer.
@param[in] BufferSize Input buffer size in bytes.
@retval TRUE The input buffer is in valid address scope.
@retval FALSE The input buffer is not in valid address scope.
**/
BOOLEAN
IsValidPointer (
IN VOID *Pointer,
IN UINTN BufferSize
)
{
if ((UINTN) Pointer > mMaximumSupportAddress) {
return FALSE;
}
if (BufferSize > (mMaximumSupportAddress - (UINTN) Pointer)) {
return FALSE;
}
return TRUE;
}
/**
The main entry point to SMM Foundation.
@ -323,22 +398,29 @@ SmmEntryPoint (
//
// Synchronous SMI for SMM Core or request from Communicate protocol
//
CommunicateHeader = (EFI_SMM_COMMUNICATE_HEADER *)gSmmCorePrivate->CommunicationBuffer;
gSmmCorePrivate->BufferSize -= OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data);
Status = SmiManage (
&CommunicateHeader->HeaderGuid,
NULL,
CommunicateHeader->Data,
&gSmmCorePrivate->BufferSize
);
//
// Update CommunicationBuffer, BufferSize and ReturnStatus
// Communicate service finished, reset the pointer to CommBuffer to NULL
//
gSmmCorePrivate->BufferSize += OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data);
gSmmCorePrivate->CommunicationBuffer = NULL;
gSmmCorePrivate->ReturnStatus = (Status == EFI_SUCCESS) ? EFI_SUCCESS : EFI_NOT_FOUND;
if (!IsValidPointer (gSmmCorePrivate->CommunicationBuffer, gSmmCorePrivate->BufferSize)) {
//
// If CommunicationBuffer is not in valid address scope, return EFI_INVALID_PARAMETER
//
gSmmCorePrivate->CommunicationBuffer = NULL;
gSmmCorePrivate->ReturnStatus = EFI_INVALID_PARAMETER;
} else {
CommunicateHeader = (EFI_SMM_COMMUNICATE_HEADER *)gSmmCorePrivate->CommunicationBuffer;
gSmmCorePrivate->BufferSize -= OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data);
Status = SmiManage (
&CommunicateHeader->HeaderGuid,
NULL,
CommunicateHeader->Data,
&gSmmCorePrivate->BufferSize
);
//
// Update CommunicationBuffer, BufferSize and ReturnStatus
// Communicate service finished, reset the pointer to CommBuffer to NULL
//
gSmmCorePrivate->BufferSize += OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data);
gSmmCorePrivate->CommunicationBuffer = NULL;
gSmmCorePrivate->ReturnStatus = (Status == EFI_SUCCESS) ? EFI_SUCCESS : EFI_NOT_FOUND;
}
}
}
@ -430,5 +512,10 @@ SmmMain (
RegisterSmramProfileHandler ();
//
// Caculate and save maximum support address used in SmmEntryPoint().
//
CaculateMaximumSupportAddress ();
return EFI_SUCCESS;
}

View File

@ -50,6 +50,7 @@
#include <Library/SmmCorePlatformHookLib.h>
#include <Library/PerformanceLib.h>
#include <Library/TimerLib.h>
#include <Library/HobLib.h>
#include "PiSmmCorePrivateData.h"

View File

@ -59,6 +59,7 @@
SmmCorePlatformHookLib
PerformanceLib
TimerLib
HobLib
[Protocols]
gEfiDxeSmmReadyToLockProtocolGuid ## UNDEFINED # SmiHandlerRegister