From: Jiewen Yao Date: Thu, 2 Nov 2017 10:21:13 +0000 (+0800) Subject: MdePkg/SmmMemLib: Check for untested memory in GCD X-Git-Tag: edk2-stable201903~1347 X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=commitdiff_plain;h=233ffa90ccd852a8c6a478eb0426731d64598316 MdePkg/SmmMemLib: Check for untested memory in GCD It treats GCD untested memory as invalid SMM communication buffer. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Jiewen Yao Reviewed-by: Star Zeng --- diff --git a/MdePkg/Library/SmmMemLib/SmmMemLib.c b/MdePkg/Library/SmmMemLib/SmmMemLib.c index 8c78a0b426..3f79e46d46 100644 --- a/MdePkg/Library/SmmMemLib/SmmMemLib.c +++ b/MdePkg/Library/SmmMemLib/SmmMemLib.c @@ -25,12 +25,20 @@ #include #include #include +#include #include #include #include #include #include +// +// attributes for reserved memory before it is promoted to system memory +// +#define EFI_MEMORY_PRESENT 0x0100000000000000ULL +#define EFI_MEMORY_INITIALIZED 0x0200000000000000ULL +#define EFI_MEMORY_TESTED 0x0400000000000000ULL + #define NEXT_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \ ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) + (Size))) @@ -46,10 +54,13 @@ UINTN mMemoryMapEntryCount; EFI_MEMORY_DESCRIPTOR *mMemoryMap; UINTN mDescriptorSize; +EFI_GCD_MEMORY_SPACE_DESCRIPTOR *mSmmMemLibGcdMemSpace = NULL; +UINTN mSmmMemLibGcdMemNumberOfDesc = 0; + VOID *mRegistrationEndOfDxe; VOID *mRegistrationReadyToLock; -BOOLEAN mSmmReadyToLock = FALSE; +BOOLEAN mSmmMemLibSmmReadyToLock = FALSE; /** Calculate and save the maximum support address. @@ -154,7 +165,7 @@ SmmIsBufferOutsideSmmValid ( // // Check override for Valid Communication Region // - if (mSmmReadyToLock) { + if (mSmmMemLibSmmReadyToLock) { EFI_MEMORY_DESCRIPTOR *MemoryMap; BOOLEAN InValidCommunicationRegion; @@ -171,12 +182,28 @@ SmmIsBufferOutsideSmmValid ( if (!InValidCommunicationRegion) { DEBUG (( EFI_D_ERROR, - "SmmIsBufferOutsideSmmValid: Not in ValidCommunicationRegion: Buffer (0x%lx) - Length (0x%lx), ", + "SmmIsBufferOutsideSmmValid: Not in ValidCommunicationRegion: Buffer (0x%lx) - Length (0x%lx)\n", Buffer, Length )); return FALSE; } + + // + // Check untested memory as invalid communication buffer. + // + for (Index = 0; Index < mSmmMemLibGcdMemNumberOfDesc; Index++) { + if (((Buffer >= mSmmMemLibGcdMemSpace[Index].BaseAddress) && (Buffer < mSmmMemLibGcdMemSpace[Index].BaseAddress + mSmmMemLibGcdMemSpace[Index].Length)) || + ((mSmmMemLibGcdMemSpace[Index].BaseAddress >= Buffer) && (mSmmMemLibGcdMemSpace[Index].BaseAddress < Buffer + Length))) { + DEBUG (( + EFI_D_ERROR, + "SmmIsBufferOutsideSmmValid: In Untested Memory Region: Buffer (0x%lx) - Length (0x%lx)\n", + Buffer, + Length + )); + return FALSE; + } + } } return TRUE; } @@ -317,6 +344,61 @@ SmmSetMem ( return EFI_SUCCESS; } +/** + Get GCD memory map. + Only record untested memory as invalid communication buffer. +**/ +VOID +SmmMemLibInternalGetGcdMemoryMap ( + VOID + ) +{ + UINTN NumberOfDescriptors; + EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemSpaceMap; + EFI_STATUS Status; + UINTN Index; + + Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemSpaceMap); + if (EFI_ERROR (Status)) { + return ; + } + + mSmmMemLibGcdMemNumberOfDesc = 0; + for (Index = 0; Index < NumberOfDescriptors; Index++) { + if (MemSpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeReserved && + (MemSpaceMap[Index].Capabilities & (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED)) == + (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED) + ) { + mSmmMemLibGcdMemNumberOfDesc++; + } + } + + mSmmMemLibGcdMemSpace = AllocateZeroPool (mSmmMemLibGcdMemNumberOfDesc * sizeof (EFI_GCD_MEMORY_SPACE_DESCRIPTOR)); + ASSERT (mSmmMemLibGcdMemSpace != NULL); + if (mSmmMemLibGcdMemSpace == NULL) { + mSmmMemLibGcdMemNumberOfDesc = 0; + gBS->FreePool (MemSpaceMap); + return ; + } + + mSmmMemLibGcdMemNumberOfDesc = 0; + for (Index = 0; Index < NumberOfDescriptors; Index++) { + if (MemSpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeReserved && + (MemSpaceMap[Index].Capabilities & (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED)) == + (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED) + ) { + CopyMem ( + &mSmmMemLibGcdMemSpace[mSmmMemLibGcdMemNumberOfDesc], + &MemSpaceMap[Index], + sizeof(EFI_GCD_MEMORY_SPACE_DESCRIPTOR) + ); + mSmmMemLibGcdMemNumberOfDesc++; + } + } + + gBS->FreePool (MemSpaceMap); +} + /** Notification for SMM EndOfDxe protocol. @@ -415,10 +497,14 @@ SmmLibInternalEndOfDxeNotify ( gBS->FreePool (MemoryMap); + // + // Get additional information from GCD memory map. + // + SmmMemLibInternalGetGcdMemoryMap (); + return EFI_SUCCESS; } - /** Notification for SMM ReadyToLock protocol. @@ -436,7 +522,7 @@ SmmLibInternalReadyToLockNotify ( IN EFI_HANDLE Handle ) { - mSmmReadyToLock = TRUE; + mSmmMemLibSmmReadyToLock = TRUE; return EFI_SUCCESS; } /** diff --git a/MdePkg/Library/SmmMemLib/SmmMemLib.inf b/MdePkg/Library/SmmMemLib/SmmMemLib.inf index e4edad3af2..36576a4f2f 100644 --- a/MdePkg/Library/SmmMemLib/SmmMemLib.inf +++ b/MdePkg/Library/SmmMemLib/SmmMemLib.inf @@ -43,6 +43,7 @@ [LibraryClasses] SmmServicesTableLib UefiBootServicesTableLib + DxeServicesTableLib DebugLib BaseMemoryLib HobLib