From b7c51c9cf4864df6aabb99a1ae843becd577237c Mon Sep 17 00:00:00 2001 From: raywu Date: Fri, 15 Jun 2018 00:00:50 +0800 Subject: init. 1AQQW051 --- Library/SmmAmiBufferValidationLib.c | 239 ++++++++++++++++++++++++++++++++++++ 1 file changed, 239 insertions(+) create mode 100644 Library/SmmAmiBufferValidationLib.c (limited to 'Library/SmmAmiBufferValidationLib.c') diff --git a/Library/SmmAmiBufferValidationLib.c b/Library/SmmAmiBufferValidationLib.c new file mode 100644 index 0000000..acc9a3d --- /dev/null +++ b/Library/SmmAmiBufferValidationLib.c @@ -0,0 +1,239 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2014, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/AmiBufferValidationLib/SmmAmiBufferValidationLib.c 4 1/06/15 10:21a Aaronp $ +// +// $Revision: 4 $ +// +// $Date: 1/06/15 10:21a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/AmiBufferValidationLib/SmmAmiBufferValidationLib.c $ +// +// 4 1/06/15 10:21a Aaronp +// [TAG] EIP198890 +// [Category] Improvement +// [Description] Use of CORE_COMBINED_VERSION requires Token.h to be +// included. +// +// 3 12/30/14 4:08p Aaronp +// [TAG] EIP198005 +// [Category] Improvement +// [Description] Added support for pre PI 1.2 +// +// 2 11/26/14 10:33a Aaronp +// Updated function headers with additional information that was added to +// the AptioV component. +// +// 1 11/07/14 12:07p Aaronp +// Initial addition of AmiBufferValidationLib +// +//********************************************************************** + +//********************************************************************** +// +// +// Name: SmmAmiBufferValidationLib.c +// +// Description: Source file that defines the AmiBufferValidationLib functions +// used for validating that buffer addresses and MMIO addreses +// do not reside in SMM. The file also provides a function to +// validate that a buffer does reside in SMM. +// +// +//********************************************************************** +#include +#include +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A) +#include +#else +#include +#endif + +/// Internal list of SMRAM regions +EFI_SMRAM_DESCRIPTOR *SmmAmiBufferValidationLibSmramRanges = NULL; + +/// Number of SMRAM regions in the internal list +UINTN SmmAmiBufferValidationLibNumberOfSmramRange = 0; + +// +//---------------------------------------------------------------------------- +// Procedure: AmiValidateMemoryBuffer +// +// Description: Function verifies the buffer to make sure its address range is legal for a memory buffer. A legal memory +// buffer is one that lies entirely outside of SMRAM. SMI handlers that receive buffer address and/or size +// from outside of SMM at runtime must validate the buffer using this function prior to using it or passing +// to other SMM interfaces. +// +// Input: +// VOID *Buffer - Buffer address +// UINTN BufferSize - Size of the Buffer +// +// Output: +// EFI_SUCCESS - The buffer address range is valid and can be safely used. +// EFI_ACCESS_DENIED - The buffer can't be used because its address range overlaps with protected area such as SMRAM. +// EFI_INVALID_PARAMETER - The buffer can't be used because its address range is invalid. +// EFI_NOT_FOUND - The buffer can't be used because its validity cannot be verified. Normally due to the SMRAM ranges were not available. +//---------------------------------------------------------------------------- +// +EFI_STATUS AmiValidateMemoryBuffer(VOID* Buffer, UINTN BufferSize){ + UINTN i; + UINTN BufferAddress; + + if (SmmAmiBufferValidationLibNumberOfSmramRange==0) return EFI_NOT_FOUND; + + BufferAddress = (UINTN)Buffer; + if (BufferAddress + BufferSize < BufferAddress) return EFI_INVALID_PARAMETER; // overflow + for (i = 0; i < SmmAmiBufferValidationLibNumberOfSmramRange; i ++) { + if ( BufferAddress >= SmmAmiBufferValidationLibSmramRanges[i].CpuStart + && BufferAddress < SmmAmiBufferValidationLibSmramRanges[i].CpuStart + SmmAmiBufferValidationLibSmramRanges[i].PhysicalSize + ) return EFI_ACCESS_DENIED; // Buffer starts in SMRAM + if ( BufferAddress < SmmAmiBufferValidationLibSmramRanges[i].CpuStart + && BufferAddress+BufferSize > SmmAmiBufferValidationLibSmramRanges[i].CpuStart + ) return EFI_ACCESS_DENIED; // Buffer overlaps with SMRAM + } + + return EFI_SUCCESS; +} + +// +//---------------------------------------------------------------------------- +// Procedure: AmiValidateMmioBuffer +// +// Description: Function verifies the buffer to make sure its address range is legal for a MMIO buffer. A legal MMIO buffer is one that lies +// entirely outside of SMRAM. SMI handlers that receive a buffer address and/or size from outside of SMM at runtime must validate +// the buffer using this function prior to using the MMIO Buffer or passing to other SMM interfaces. +// +// Input: +// VOID *Buffer - Buffer address +// UINTN BufferSize - Size of the Buffer +// +// Output: +// EFI_SUCCESS - The buffer address range is valid and can be safely used. +// EFI_ACCESS_DENIED - The buffer can't be used because its address range overlaps with protected area such as SMRAM. +// EFI_INVALID_PARAMETER - The buffer can't be used because its address range is invalid. +// EFI_NOT_FOUND - The buffer can't be used because its validity cannot be verified. Normally due to the SMRAM ranges were not available. +//---------------------------------------------------------------------------- +// +EFI_STATUS AmiValidateMmioBuffer(VOID* Buffer, UINTN BufferSize){ + return AmiValidateMemoryBuffer(Buffer,BufferSize); +} + +// +//---------------------------------------------------------------------------- +// Procedure: AmiValidateSmramBuffer +// +// Description: Function verifies the buffer to make sure it wholly resides in the SMRAM. +// +// Input: +// IN VOID *Buffer - Buffer address +// IN UINTN BufferSize - Size of the Buffer +// +// Output: +// EFI_SUCCESS - The buffer resides in the SMRAM and can be safely used. +// EFI_ACCESS_DENIED - The buffer can't be used because at least one byte of the buffer is outside of SMRAM. +// EFI_INVALID_PARAMETER - The buffer can't be used because its address range is invalid. +// EFI_NOT_FOUND - The buffer can't be used because its validity cannot be verified. Normally due to the SMRAM ranges were not available. +//---------------------------------------------------------------------------- +// +EFI_STATUS AmiValidateSmramBuffer(VOID* Buffer, UINTN BufferSize){ + UINTN i; + UINTN BufferAddress; + + if (SmmAmiBufferValidationLibNumberOfSmramRange==0) return EFI_NOT_FOUND; + + BufferAddress = (UINTN)Buffer; + if (BufferAddress + BufferSize < BufferAddress) return EFI_INVALID_PARAMETER; // overflow + for (i = 0; i < SmmAmiBufferValidationLibNumberOfSmramRange; i ++) { + if ( BufferAddress >= SmmAmiBufferValidationLibSmramRanges[i].CpuStart + && BufferAddress+BufferSize <= SmmAmiBufferValidationLibSmramRanges[i].CpuStart + SmmAmiBufferValidationLibSmramRanges[i].PhysicalSize + ) return EFI_SUCCESS; // Entire Buffer is in SMRAM + } + + return EFI_ACCESS_DENIED; +} + +// +//---------------------------------------------------------------------------- +// Procedure: InitAmiBufferValidationLib +// +// Description: Performs the necessary initialization so that the buffer validation functions will operate +// correctly when they are called. +// +// Input: +// IN EFI_HANDLE ImageHandle - The handle of this image +// IN EFI_SYSTEM_TABLE *SystemTable - Pointer to the EFI_SYSTEM_TABLE +// +// Output: +// EFI_NOT_FOUND - The Smm Access protocol could not be found +// EFI_OUT_OF_RESOURCES - An allocation failed because it could not find any memory resources +// EFI_INVALID_PARAMETER - An invalid parameter was passed to one of the functions +// EFI_SUCCESS - The necessary functions were initialized +//---------------------------------------------------------------------------- +// +EFI_STATUS EFIAPI InitAmiBufferValidationLib(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable){ + EFI_STATUS Status; +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A) + EFI_SMM_ACCESS2_PROTOCOL *SmmAccess; +#else + EFI_SMM_ACCESS_PROTOCOL *SmmAccess; +#endif + UINTN Size; + +#if defined(CORE_COMBINED_VERSION)&&(CORE_COMBINED_VERSION>0x4028a) + InitAmiSmmLib(ImageHandle,SystemTable); +#endif + + // Get SMRAM information +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A) + Status = pBS->LocateProtocol (&gEfiSmmAccess2ProtocolGuid, NULL, (VOID **)&SmmAccess); +#else + Status = pBS->LocateProtocol (&gEfiSmmAccessProtocolGuid, NULL, (VOID **)&SmmAccess); +#endif + if (EFI_ERROR(Status)) return Status; + + Size = 0; + Status = SmmAccess->GetCapabilities (SmmAccess, &Size, NULL); + if (Status != EFI_BUFFER_TOO_SMALL) return Status; + Status = pSmst->SmmAllocatePool (EfiRuntimeServicesData, Size, (VOID **)&SmmAmiBufferValidationLibSmramRanges); + if (EFI_ERROR(Status)){ + SmmAmiBufferValidationLibSmramRanges = NULL; + return Status; + } + Status = SmmAccess->GetCapabilities (SmmAccess, &Size, SmmAmiBufferValidationLibSmramRanges); + if (EFI_ERROR(Status)){ + pSmst->SmmFreePool (SmmAmiBufferValidationLibSmramRanges); + SmmAmiBufferValidationLibSmramRanges = NULL; + return Status; + } + SmmAmiBufferValidationLibNumberOfSmramRange = Size / sizeof (EFI_SMRAM_DESCRIPTOR); + + return EFI_SUCCESS; +} + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2014, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** -- cgit v1.2.3