From d5bcf13e1d7f9bad6b51c55da99958631207ab23 Mon Sep 17 00:00:00 2001 From: rsun3 Date: Tue, 26 Jun 2012 05:37:34 +0000 Subject: EdkCompatibilityPkg SmmBaseHelper: In SmmHandlerEntry(), add check to ensure CommBuff+CommBuffSize is outside of SMRAM. Signed-off by: Sun Rui Reviewed-by: Yao Jiewen git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13472 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Compatibility/SmmBaseHelper/SmmBaseHelper.c | 121 ++++++++++++++++----- .../Compatibility/SmmBaseHelper/SmmBaseHelper.inf | 5 +- 2 files changed, 97 insertions(+), 29 deletions(-) (limited to 'EdkCompatibilityPkg') 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.
+ 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.
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 #include #include +#include /// /// 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; /// @@ -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 // diff --git a/EdkCompatibilityPkg/Compatibility/SmmBaseHelper/SmmBaseHelper.inf b/EdkCompatibilityPkg/Compatibility/SmmBaseHelper/SmmBaseHelper.inf index 9a0a2d91c9..f988c138fe 100644 --- a/EdkCompatibilityPkg/Compatibility/SmmBaseHelper/SmmBaseHelper.inf +++ b/EdkCompatibilityPkg/Compatibility/SmmBaseHelper/SmmBaseHelper.inf @@ -1,7 +1,7 @@ ## @file # Component description file for SMM Base Helper SMM driver. # -# Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+# Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.
# # 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 \ No newline at end of file + gEfiLoadPeImageProtocolGuid -- cgit v1.2.3