EdkCompatibilityPkg SmmBaseHelper: In SmmHandlerEntry(), add check to ensure CommBuff+CommBuffSize is outside of SMRAM.

Signed-off by: Sun Rui <rui.sun@intel.com>
Reviewed-by: Yao Jiewen <jiewen.yao@intel.com>


git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13472 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
rsun3 2012-06-26 05:37:34 +00:00
parent b00ed21ac6
commit d5bcf13e1d
2 changed files with 95 additions and 27 deletions

View File

@ -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));
ASSERT (CommBufferSize != NULL);
FunctionData = (SMMBASE_FUNCTION_DATA *)CommBuffer;
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:
ASSERT (FALSE);
FunctionData->Status = EFI_UNSUPPORTED;
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;
///
@ -1143,6 +1188,28 @@ SmmBaseHelperMain (
mSmmBaseHelperReady->FrameworkSmst = mFrameworkSmst;
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
//

View File

@ -1,7 +1,7 @@
## @file
# Component description file for SMM Base Helper SMM driver.
#
# Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
# 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
@ -72,9 +72,10 @@
gEfiSmmCpuIo2ProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiLoadPeImageProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiSmmReadyToLockProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiSmmAccess2ProtocolGuid # PROTOCOL ALWAYS_CONSUMED
[Depex]
gEfiSmmCpuProtocolGuid AND
gEfiMpServiceProtocolGuid AND
gEfiSmmCpuIo2ProtocolGuid AND
gEfiLoadPeImageProtocolGuid
gEfiLoadPeImageProtocolGuid