SecurityPkg-Opal(2): Enhance AHCI Bar MMIO region check.

This patch enhance OPAL password SMM driver to check SMM bar is valid MMIO
besides outside of SMRAM.

This is designed to meet Microsoft WSMT table definition on FIXED_COMM_BUFFERS
requirement.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Feng Tian <feng.tian@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Feng Tian <feng.tian@intel.com>
This commit is contained in:
Eric Dong 2016-04-22 15:40:46 +08:00 committed by Jiewen Yao
parent 83681c74f0
commit 009264f5cf
4 changed files with 84 additions and 4 deletions

View File

@ -1022,6 +1022,34 @@ GetAhciBarSize (
return Size;
}
/**
This function check if the memory region is in GCD MMIO region.
@param Addr The memory region start address to be checked.
@param Size The memory region length to be checked.
@retval TRUE This memory region is in GCD MMIO region.
@retval FALSE This memory region is not in GCD MMIO region.
**/
BOOLEAN
EFIAPI
OpalIsValidMmioSpace (
IN EFI_PHYSICAL_ADDRESS Addr,
IN UINTN Size
)
{
UINTN Index;
EFI_GCD_MEMORY_SPACE_DESCRIPTOR *Desc;
for (Index = 0; Index < mNumberOfDescriptors; Index ++) {
Desc = &mGcdMemSpace[Index];
if ((Desc->GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) && (Addr >= Desc->BaseAddress) && ((Addr + Size) <= (Desc->BaseAddress + Desc->Length))) {
return TRUE;
}
}
return FALSE;
}
/**
Get AHCI mode base address registers' Value.
@ -1055,7 +1083,7 @@ GetAhciBaseAddress (
//
// Check if the AHCI Bar region is in SMRAM to avoid malicious attack by modifying MMIO Bar to point to SMRAM.
//
if (!SmmIsBufferOutsideSmmValid ((EFI_PHYSICAL_ADDRESS)mAhciBar, Size)) {
if (!OpalIsValidMmioSpace ((EFI_PHYSICAL_ADDRESS)mAhciBar, Size)) {
return EFI_UNSUPPORTED;
}

View File

@ -61,6 +61,9 @@ VOID *mBuffer = NULL; // DMA can not read/write Data to smram, s
// NVME
NVME_CONTEXT mNvmeContext;
EFI_GCD_MEMORY_SPACE_DESCRIPTOR *mGcdMemSpace = NULL;
UINTN mNumberOfDescriptors = 0;
/**
Add new bridge node or nvme device info to the device list.
@ -592,6 +595,44 @@ S3SleepEntryCallBack (
return Status;
}
/**
OpalPassword Notification for SMM EndOfDxe protocol.
@param[in] Protocol Points to the protocol's unique identifier.
@param[in] Interface Points to the interface instance.
@param[in] Handle The handle on which the interface was installed.
@retval EFI_SUCCESS Notification runs successfully.
**/
EFI_STATUS
EFIAPI
OpalPasswordEndOfDxeNotification (
IN CONST EFI_GUID *Protocol,
IN VOID *Interface,
IN EFI_HANDLE Handle
)
{
UINTN NumberOfDescriptors;
EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemSpaceMap;
EFI_STATUS Status;
Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemSpaceMap);
if (EFI_ERROR (Status)) {
return Status;
}
mGcdMemSpace = AllocateCopyPool (NumberOfDescriptors * sizeof (EFI_GCD_MEMORY_SPACE_DESCRIPTOR), MemSpaceMap);
if (EFI_ERROR (Status)) {
gBS->FreePool (MemSpaceMap);
return Status;
}
mNumberOfDescriptors = NumberOfDescriptors;
gBS->FreePool (MemSpaceMap);
return EFI_SUCCESS;
}
/**
Main entry for this driver.
@ -618,6 +659,7 @@ OpalPasswordSmmInit (
EFI_SMM_VARIABLE_PROTOCOL *SmmVariable;
OPAL_EXTRA_INFO_VAR OpalExtraInfo;
UINTN DataSize;
EFI_EVENT EndOfDxeEvent;
EFI_PHYSICAL_ADDRESS Address;
mBuffer = NULL;
@ -726,6 +768,15 @@ OpalPasswordSmmInit (
//
mSwSmiValue = (UINT8) Context.SwSmiInputValue;
//
// Create event to record GCD descriptors at end of dxe for judging AHCI/NVMe PCI Bar
// is in MMIO space to avoid attack.
//
Status = gSmst->SmmRegisterProtocolNotify (&gEfiSmmEndOfDxeProtocolGuid, OpalPasswordEndOfDxeNotification, &EndOfDxeEvent);
if (EFI_ERROR (Status)) {
DEBUG((DEBUG_ERROR, "OpalPasswordSmm: Register SmmEndOfDxe fail, Status: %r\n", Status));
goto EXIT;
}
Status = gSmst->SmmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID**)&SmmVariable);
if (!EFI_ERROR (Status)) {
DataSize = sizeof (OPAL_EXTRA_INFO_VAR);

View File

@ -25,6 +25,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Protocol/SmmReadyToLock.h>
#include <Protocol/SmmVariable.h>
#include <Protocol/VariableLock.h>
#include <Protocol/SmmEndOfDxe.h>
#include <Protocol/StorageSecurityCommand.h>
#include <Library/OpalPasswordSupportLib.h>
@ -43,8 +44,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Library/UefiLib.h>
#include <Library/S3BootScriptLib.h>
#include <Library/DevicePathLib.h>
#include <Library/SmmMemLib.h>
#include <Library/DxeServicesTableLib.h>
#include <IndustryStandard/Pci22.h>
@ -71,6 +70,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
extern VOID *mBuffer;
extern EFI_GCD_MEMORY_SPACE_DESCRIPTOR *mGcdMemSpace;
extern UINTN mNumberOfDescriptors;
#pragma pack(1)
typedef struct {

View File

@ -58,7 +58,6 @@
DxeServicesTableLib
DevicePathLib
OpalPasswordSupportLib
SmmMemLib
[Guids]
gOpalExtraInfoVariableGuid ## CONSUMES ## GUID
@ -70,6 +69,7 @@
gEfiSmmSxDispatch2ProtocolGuid ## CONSUMES
gEfiSmmVariableProtocolGuid ## CONSUMES
gEfiStorageSecurityCommandProtocolGuid ## CONSUMES
gEfiSmmEndOfDxeProtocolGuid ## CONSUMES
[Depex]
gEfiSmmSwDispatch2ProtocolGuid AND