diff options
author | Eric Dong <eric.dong@intel.com> | 2016-04-22 15:40:46 +0800 |
---|---|---|
committer | Jiewen Yao <jiewen.yao@intel.com> | 2016-04-29 12:49:25 +0800 |
commit | 009264f5cf0fa0009ff96f307eaac88860a998a8 (patch) | |
tree | a85ff49ddf66d7b6557bfba90fc868b11a825171 | |
parent | 83681c74f07978adbb621a467fe391ae901e2515 (diff) | |
download | edk2-009264f5cf0fa0009ff96f307eaac88860a998a8.tar.gz edk2-009264f5cf0fa0009ff96f307eaac88860a998a8.tar.bz2 edk2-009264f5cf0fa0009ff96f307eaac88860a998a8.zip |
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>
4 files changed, 84 insertions, 4 deletions
diff --git a/SecurityPkg/Tcg/Opal/OpalPasswordSmm/OpalAhciMode.c b/SecurityPkg/Tcg/Opal/OpalPasswordSmm/OpalAhciMode.c index 0dc3490a36..33f77bd8a2 100644 --- a/SecurityPkg/Tcg/Opal/OpalPasswordSmm/OpalAhciMode.c +++ b/SecurityPkg/Tcg/Opal/OpalPasswordSmm/OpalAhciMode.c @@ -1023,6 +1023,34 @@ GetAhciBarSize ( }
/**
+ 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.
@param[in] Bus The bus number of ata host controller.
@@ -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;
}
diff --git a/SecurityPkg/Tcg/Opal/OpalPasswordSmm/OpalPasswordSmm.c b/SecurityPkg/Tcg/Opal/OpalPasswordSmm/OpalPasswordSmm.c index 57d10a17b7..b7e2d552d5 100644 --- a/SecurityPkg/Tcg/Opal/OpalPasswordSmm/OpalPasswordSmm.c +++ b/SecurityPkg/Tcg/Opal/OpalPasswordSmm/OpalPasswordSmm.c @@ -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.
@@ -593,6 +596,44 @@ S3SleepEntryCallBack ( }
/**
+ 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.
@param ImageHandle Image handle 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);
diff --git a/SecurityPkg/Tcg/Opal/OpalPasswordSmm/OpalPasswordSmm.h b/SecurityPkg/Tcg/Opal/OpalPasswordSmm/OpalPasswordSmm.h index f365136918..ab31a6bfe7 100644 --- a/SecurityPkg/Tcg/Opal/OpalPasswordSmm/OpalPasswordSmm.h +++ b/SecurityPkg/Tcg/Opal/OpalPasswordSmm/OpalPasswordSmm.h @@ -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 {
diff --git a/SecurityPkg/Tcg/Opal/OpalPasswordSmm/OpalPasswordSmm.inf b/SecurityPkg/Tcg/Opal/OpalPasswordSmm/OpalPasswordSmm.inf index dae51ece02..cab0fd5656 100644 --- a/SecurityPkg/Tcg/Opal/OpalPasswordSmm/OpalPasswordSmm.inf +++ b/SecurityPkg/Tcg/Opal/OpalPasswordSmm/OpalPasswordSmm.inf @@ -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
|