summaryrefslogtreecommitdiffstats
path: root/EdkCompatibilityPkg/Compatibility/SmmBaseHelper/SmmBaseHelper.c
diff options
context:
space:
mode:
Diffstat (limited to 'EdkCompatibilityPkg/Compatibility/SmmBaseHelper/SmmBaseHelper.c')
-rw-r--r--EdkCompatibilityPkg/Compatibility/SmmBaseHelper/SmmBaseHelper.c121
1 files changed, 94 insertions, 27 deletions
diff --git a/EdkCompatibilityPkg/Compatibility/SmmBaseHelper/SmmBaseHelper.c b/EdkCompatibilityPkg/Compatibility/SmmBaseHelper/SmmBaseHelper.c
index 99dccab8e9..193ab19756 100644
--- a/EdkCompatibilityPkg/Compatibility/SmmBaseHelper/SmmBaseHelper.c
+++ b/EdkCompatibilityPkg/Compatibility/SmmBaseHelper/SmmBaseHelper.c
@@ -4,7 +4,14 @@
This driver is the counterpart of the SMM Base On SMM Base2 Thunk driver. It
provides helping services in SMM to the SMM Base On SMM Base2 Thunk driver.
- Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+ Caution: This module requires additional review when modified.
+ This driver will have external input - communicate buffer in SMM mode.
+ This external input must be validated carefully to avoid security issue like
+ buffer overflow, integer overflow.
+
+ SmmHandlerEntry() will receive untrusted input and do validation.
+
+ Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -35,6 +42,7 @@
#include <Protocol/MpService.h>
#include <Protocol/LoadPe32Image.h>
#include <Protocol/SmmReadyToLock.h>
+#include <Protocol/SmmAccess2.h>
///
/// Structure for tracking paired information of registered Framework SMI handler
@@ -78,6 +86,8 @@ SPIN_LOCK mPFLock;
UINT64 mPhyMask;
VOID *mOriginalHandler;
EFI_SMM_CPU_SAVE_STATE *mShadowSaveState;
+EFI_SMRAM_DESCRIPTOR *mSmramRanges;
+UINTN mSmramRangeCount;
LIST_ENTRY mCallbackInfoListHead = INITIALIZE_LIST_HEAD_VARIABLE (mCallbackInfoListHead);
@@ -695,6 +705,32 @@ LoadImage (
return Status;
}
+/**
+ This function check if the address is in SMRAM.
+
+ @param Buffer the buffer address to be checked.
+ @param Length the buffer length to be checked.
+
+ @retval TRUE this address is in SMRAM.
+ @retval FALSE this address is NOT in SMRAM.
+**/
+BOOLEAN
+IsAddressInSmram (
+ IN EFI_PHYSICAL_ADDRESS Buffer,
+ IN UINT64 Length
+ )
+{
+ UINTN Index;
+
+ for (Index = 0; Index < mSmramRangeCount; Index ++) {
+ if (((Buffer >= mSmramRanges[Index].CpuStart) && (Buffer < mSmramRanges[Index].CpuStart + mSmramRanges[Index].PhysicalSize)) ||
+ ((mSmramRanges[Index].CpuStart >= Buffer) && (mSmramRanges[Index].CpuStart < Buffer + Length))) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
/**
Thunk service of EFI_SMM_BASE_PROTOCOL.Register().
@@ -998,6 +1034,10 @@ HelperCommunicate (
This SMI handler provides services for the SMM Base Thunk driver.
+ Caution: This function may receive untrusted input during runtime.
+ The communicate buffer is external input, so this function will do operations only if the communicate
+ buffer is outside of SMRAM so that returning the status code in the buffer won't overwrite anywhere in SMRAM.
+
@param[in] DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().
@param[in] RegisterContext Points to an optional handler context which was specified when the
handler was registered.
@@ -1025,32 +1065,35 @@ SmmHandlerEntry (
SMMBASE_FUNCTION_DATA *FunctionData;
ASSERT (CommBuffer != NULL);
- ASSERT (*CommBufferSize == sizeof (SMMBASE_FUNCTION_DATA));
-
- FunctionData = (SMMBASE_FUNCTION_DATA *)CommBuffer;
-
- switch (FunctionData->Function) {
- case SmmBaseFunctionRegister:
- Register (FunctionData);
- break;
- case SmmBaseFunctionUnregister:
- UnRegister (FunctionData);
- break;
- case SmmBaseFunctionRegisterCallback:
- RegisterCallback (FunctionData);
- break;
- case SmmBaseFunctionAllocatePool:
- HelperAllocatePool (FunctionData);
- break;
- case SmmBaseFunctionFreePool:
- HelperFreePool (FunctionData);
- break;
- case SmmBaseFunctionCommunicate:
- HelperCommunicate (FunctionData);
- break;
- default:
- ASSERT (FALSE);
- FunctionData->Status = EFI_UNSUPPORTED;
+ ASSERT (CommBufferSize != NULL);
+
+ if (*CommBufferSize == sizeof (SMMBASE_FUNCTION_DATA) &&
+ !IsAddressInSmram ((EFI_PHYSICAL_ADDRESS)(UINTN)CommBuffer, *CommBufferSize)) {
+ FunctionData = (SMMBASE_FUNCTION_DATA *)CommBuffer;
+
+ switch (FunctionData->Function) {
+ case SmmBaseFunctionRegister:
+ Register (FunctionData);
+ break;
+ case SmmBaseFunctionUnregister:
+ UnRegister (FunctionData);
+ break;
+ case SmmBaseFunctionRegisterCallback:
+ RegisterCallback (FunctionData);
+ break;
+ case SmmBaseFunctionAllocatePool:
+ HelperAllocatePool (FunctionData);
+ break;
+ case SmmBaseFunctionFreePool:
+ HelperFreePool (FunctionData);
+ break;
+ case SmmBaseFunctionCommunicate:
+ HelperCommunicate (FunctionData);
+ break;
+ default:
+ DEBUG ((EFI_D_WARN, "SmmBaseHelper: invalid SMM Base function.\n"));
+ FunctionData->Status = EFI_UNSUPPORTED;
+ }
}
return EFI_SUCCESS;
}
@@ -1099,6 +1142,8 @@ SmmBaseHelperMain (
EFI_HANDLE Handle;
UINTN NumberOfEnabledProcessors;
VOID *Registration;
+ EFI_SMM_ACCESS2_PROTOCOL *SmmAccess;
+ UINTN Size;
Handle = NULL;
///
@@ -1144,6 +1189,28 @@ SmmBaseHelperMain (
mSmmBaseHelperReady->ServiceEntry = SmmHandlerEntry;
//
+ // Get SMRAM information
+ //
+ Status = gBS->LocateProtocol (&gEfiSmmAccess2ProtocolGuid, NULL, (VOID **)&SmmAccess);
+ ASSERT_EFI_ERROR (Status);
+
+ Size = 0;
+ Status = SmmAccess->GetCapabilities (SmmAccess, &Size, NULL);
+ ASSERT (Status == EFI_BUFFER_TOO_SMALL);
+
+ Status = gSmst->SmmAllocatePool (
+ EfiRuntimeServicesData,
+ Size,
+ (VOID **)&mSmramRanges
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = SmmAccess->GetCapabilities (SmmAccess, &Size, mSmramRanges);
+ ASSERT_EFI_ERROR (Status);
+
+ mSmramRangeCount = Size / sizeof (EFI_SMRAM_DESCRIPTOR);
+
+ //
// Register SMM Ready To Lock Protocol notification
//
Status = gSmst->SmmRegisterProtocolNotify (