summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Fan <Jeff.fan@intel.com>2014-12-09 02:20:16 +0000
committervanjeff <vanjeff@Edk2>2014-12-09 02:20:16 +0000
commit3720ee6d32219fd67d391f53f2cb812dc197a86b (patch)
treeb1fbd6326aa97be96886bed699df27cbf18ddf2d
parentbaaacdc82378d432f1c9c6ae0625869a26c174e0 (diff)
downloadedk2-platforms-3720ee6d32219fd67d391f53f2cb812dc197a86b.tar.xz
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
-rw-r--r--MdeModulePkg/Core/PiSmmCore/PiSmmCore.c119
-rw-r--r--MdeModulePkg/Core/PiSmmCore/PiSmmCore.h1
-rw-r--r--MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf1
3 files changed, 105 insertions, 16 deletions
diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c
index 3222a92a79..d8790241e3 100644
--- a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c
+++ b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c
@@ -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.
@@ -275,6 +280,76 @@ SmmEndOfDxeHandler (
}
/**
+ 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.
Note: This function is only used by SMRAM invocation. It is never used by DXE invocation.
@@ -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;
}
diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h
index d494519d2c..34bd6411d6 100644
--- a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h
+++ b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h
@@ -50,6 +50,7 @@
#include <Library/SmmCorePlatformHookLib.h>
#include <Library/PerformanceLib.h>
#include <Library/TimerLib.h>
+#include <Library/HobLib.h>
#include "PiSmmCorePrivateData.h"
diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf
index 0c8e690846..bf030d60e7 100644
--- a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf
+++ b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf
@@ -59,6 +59,7 @@
SmmCorePlatformHookLib
PerformanceLib
TimerLib
+ HobLib
[Protocols]
gEfiDxeSmmReadyToLockProtocolGuid ## UNDEFINED # SmiHandlerRegister