MdePkg/SmmMemLib: Check EFI_MEMORY_RO in UEFI mem attrib table.

It treats the UEFI runtime page with EFI_MEMORY_RO attribute as
invalid SMM communication buffer.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Star Zeng <star.zeng@intel.com>
This commit is contained in:
Jiewen Yao 2017-11-22 23:11:22 +08:00
parent b2305dd277
commit 6809627276
2 changed files with 59 additions and 3 deletions

View File

@ -27,10 +27,12 @@
#include <Library/UefiBootServicesTableLib.h>
#include <Library/DxeServicesTableLib.h>
#include <Library/SmmServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Library/HobLib.h>
#include <Protocol/SmmAccess2.h>
#include <Protocol/SmmReadyToLock.h>
#include <Protocol/SmmEndOfDxe.h>
#include <Guid/MemoryAttributesTable.h>
//
// attributes for reserved memory before it is promoted to system memory
@ -39,9 +41,6 @@
#define EFI_MEMORY_INITIALIZED 0x0200000000000000ULL
#define EFI_MEMORY_TESTED 0x0400000000000000ULL
#define NEXT_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \
((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) + (Size)))
EFI_SMRAM_DESCRIPTOR *mSmmMemLibInternalSmramRanges;
UINTN mSmmMemLibInternalSmramCount;
@ -57,6 +56,8 @@ UINTN mDescriptorSize;
EFI_GCD_MEMORY_SPACE_DESCRIPTOR *mSmmMemLibGcdMemSpace = NULL;
UINTN mSmmMemLibGcdMemNumberOfDesc = 0;
EFI_MEMORY_ATTRIBUTES_TABLE *mSmmMemLibMemoryAttributesTable = NULL;
VOID *mRegistrationEndOfDxe;
VOID *mRegistrationReadyToLock;
@ -204,6 +205,32 @@ SmmIsBufferOutsideSmmValid (
return FALSE;
}
}
//
// Check UEFI runtime memory with EFI_MEMORY_RO as invalid communication buffer.
//
if (mSmmMemLibMemoryAttributesTable != NULL) {
EFI_MEMORY_DESCRIPTOR *Entry;
Entry = (EFI_MEMORY_DESCRIPTOR *)(mSmmMemLibMemoryAttributesTable + 1);
for (Index = 0; Index < mSmmMemLibMemoryAttributesTable->NumberOfEntries; Index++) {
if (Entry->Type == EfiRuntimeServicesCode || Entry->Type == EfiRuntimeServicesData) {
if ((Entry->Attribute & EFI_MEMORY_RO) != 0) {
if (((Buffer >= Entry->PhysicalStart) && (Buffer < Entry->PhysicalStart + LShiftU64 (Entry->NumberOfPages, EFI_PAGE_SHIFT))) ||
((Entry->PhysicalStart >= Buffer) && (Entry->PhysicalStart < Buffer + Length))) {
DEBUG ((
EFI_D_ERROR,
"SmmIsBufferOutsideSmmValid: In RuntimeCode Region: Buffer (0x%lx) - Length (0x%lx)\n",
Buffer,
Length
));
return FALSE;
}
}
}
Entry = NEXT_MEMORY_DESCRIPTOR (Entry, mSmmMemLibMemoryAttributesTable->DescriptorSize);
}
}
}
return TRUE;
}
@ -399,6 +426,26 @@ SmmMemLibInternalGetGcdMemoryMap (
gBS->FreePool (MemSpaceMap);
}
/**
Get UEFI MemoryAttributesTable.
**/
VOID
SmmMemLibInternalGetUefiMemoryAttributesTable (
VOID
)
{
EFI_STATUS Status;
EFI_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable;
UINTN MemoryAttributesTableSize;
Status = EfiGetSystemConfigurationTable (&gEfiMemoryAttributesTableGuid, (VOID **)&MemoryAttributesTable);
if (!EFI_ERROR (Status)) {
MemoryAttributesTableSize = sizeof(EFI_MEMORY_ATTRIBUTES_TABLE) + MemoryAttributesTable->DescriptorSize * MemoryAttributesTable->NumberOfEntries;
mSmmMemLibMemoryAttributesTable = AllocateCopyPool (MemoryAttributesTableSize, MemoryAttributesTable);
ASSERT (mSmmMemLibMemoryAttributesTable != NULL);
}
}
/**
Notification for SMM EndOfDxe protocol.
@ -502,6 +549,11 @@ SmmLibInternalEndOfDxeNotify (
//
SmmMemLibInternalGetGcdMemoryMap ();
//
// Get UEFI memory attributes table.
//
SmmMemLibInternalGetUefiMemoryAttributesTable ();
return EFI_SUCCESS;
}

View File

@ -48,11 +48,15 @@
BaseMemoryLib
HobLib
MemoryAllocationLib
UefiLib
[Protocols]
gEfiSmmAccess2ProtocolGuid ## CONSUMES
gEfiSmmReadyToLockProtocolGuid ## CONSUMES
gEfiSmmEndOfDxeProtocolGuid ## CONSUMES
[Guids]
gEfiMemoryAttributesTableGuid ## CONSUMES ## SystemTable
[Depex]
gEfiSmmAccess2ProtocolGuid