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: "Dong, Eric" <eric.d...@intel.com>
Cc: "Tian, Feng" <feng.t...@intel.com>
Cc: "Laszlo Ersek" <ler...@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: "Dong, Eric" <eric.d...@intel.com>
Reviewed-by: "Tian, Feng" <feng.t...@intel.com>
---
 .../Tcg/Opal/OpalPasswordSmm/OpalAhciMode.c        | 30 ++++++++++++-
 .../Tcg/Opal/OpalPasswordSmm/OpalPasswordSmm.c     | 51 ++++++++++++++++++++++
 .../Tcg/Opal/OpalPasswordSmm/OpalPasswordSmm.h     |  5 ++-
 .../Tcg/Opal/OpalPasswordSmm/OpalPasswordSmm.inf   |  2 +-
 4 files changed, 84 insertions(+), 4 deletions(-)

diff --git a/SecurityPkg/Tcg/Opal/OpalPasswordSmm/OpalAhciMode.c 
b/SecurityPkg/Tcg/Opal/OpalPasswordSmm/OpalAhciMode.c
index 0dc3490..33f77bd 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 57d10a1..b7e2d55 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 f365136..ab31a6b 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 dae51ec..cab0fd5 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
-- 
2.7.4.windows.1

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to