SecurityPkg-Opal(2): Enhance AHCI Bar MMIO region check.
authorEric Dong <eric.dong@intel.com>
Fri, 22 Apr 2016 07:40:46 +0000 (15:40 +0800)
committerJiewen Yao <jiewen.yao@intel.com>
Fri, 29 Apr 2016 04:49:25 +0000 (12:49 +0800)
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>
SecurityPkg/Tcg/Opal/OpalPasswordSmm/OpalAhciMode.c
SecurityPkg/Tcg/Opal/OpalPasswordSmm/OpalPasswordSmm.c
SecurityPkg/Tcg/Opal/OpalPasswordSmm/OpalPasswordSmm.h
SecurityPkg/Tcg/Opal/OpalPasswordSmm/OpalPasswordSmm.inf

index 0dc3490a362d2135e17091031cec7a24bfe1abba..33f77bd8a248248baa75c61b45fca88a7fdc1f38 100644 (file)
@@ -1022,6 +1022,34 @@ GetAhciBarSize (
   return Size;\r
 }\r
 \r
+/**\r
+  This function check if the memory region is in GCD MMIO region.\r
+\r
+  @param Addr  The memory region start address to be checked.\r
+  @param Size  The memory region length to be checked.\r
+\r
+  @retval TRUE  This memory region is in GCD MMIO region.\r
+  @retval FALSE This memory region is not in GCD MMIO region.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+OpalIsValidMmioSpace (\r
+  IN  EFI_PHYSICAL_ADDRESS       Addr,\r
+  IN  UINTN                      Size\r
+  )\r
+{\r
+  UINTN                           Index;\r
+  EFI_GCD_MEMORY_SPACE_DESCRIPTOR *Desc;\r
+\r
+  for (Index = 0; Index < mNumberOfDescriptors; Index ++) {\r
+    Desc = &mGcdMemSpace[Index];\r
+    if ((Desc->GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) && (Addr >= Desc->BaseAddress) && ((Addr + Size) <= (Desc->BaseAddress + Desc->Length))) {\r
+      return TRUE;\r
+    }\r
+  }\r
+\r
+  return FALSE;\r
+}\r
 /**\r
   Get AHCI mode base address registers' Value.\r
 \r
@@ -1055,7 +1083,7 @@ GetAhciBaseAddress (
   //\r
   // Check if the AHCI Bar region is in SMRAM to avoid malicious attack by modifying MMIO Bar to point to SMRAM.\r
   //\r
-  if (!SmmIsBufferOutsideSmmValid ((EFI_PHYSICAL_ADDRESS)mAhciBar, Size)) {\r
+  if (!OpalIsValidMmioSpace ((EFI_PHYSICAL_ADDRESS)mAhciBar, Size)) {\r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
index 57d10a17b77a42d60c44be990371e58697ace3d7..b7e2d552d5c2f25dd0e3ccecdc450e2779925d5b 100644 (file)
@@ -61,6 +61,9 @@ VOID                 *mBuffer = NULL; // DMA can not read/write Data to smram, s
 // NVME\r
 NVME_CONTEXT         mNvmeContext;\r
 \r
+EFI_GCD_MEMORY_SPACE_DESCRIPTOR   *mGcdMemSpace        = NULL;\r
+UINTN                             mNumberOfDescriptors = 0;\r
+\r
 /**\r
   Add new bridge node or nvme device info to the device list.\r
 \r
@@ -592,6 +595,44 @@ S3SleepEntryCallBack (
   return Status;\r
 }\r
 \r
+/**\r
+  OpalPassword Notification for SMM EndOfDxe protocol.\r
+\r
+  @param[in] Protocol   Points to the protocol's unique identifier.\r
+  @param[in] Interface  Points to the interface instance.\r
+  @param[in] Handle     The handle on which the interface was installed.\r
+\r
+  @retval EFI_SUCCESS   Notification runs successfully.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+OpalPasswordEndOfDxeNotification (\r
+  IN CONST EFI_GUID  *Protocol,\r
+  IN VOID            *Interface,\r
+  IN EFI_HANDLE      Handle\r
+  )\r
+{\r
+  UINTN                            NumberOfDescriptors;\r
+  EFI_GCD_MEMORY_SPACE_DESCRIPTOR  *MemSpaceMap;\r
+  EFI_STATUS                       Status;\r
+\r
+  Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemSpaceMap);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  mGcdMemSpace = AllocateCopyPool (NumberOfDescriptors * sizeof (EFI_GCD_MEMORY_SPACE_DESCRIPTOR), MemSpaceMap);\r
+  if (EFI_ERROR (Status)) {\r
+    gBS->FreePool (MemSpaceMap);\r
+    return Status;\r
+  }\r
+\r
+  mNumberOfDescriptors = NumberOfDescriptors;\r
+  gBS->FreePool (MemSpaceMap);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
 /**\r
   Main entry for this driver.\r
 \r
@@ -618,6 +659,7 @@ OpalPasswordSmmInit (
   EFI_SMM_VARIABLE_PROTOCOL             *SmmVariable;\r
   OPAL_EXTRA_INFO_VAR                   OpalExtraInfo;\r
   UINTN                                 DataSize;\r
+  EFI_EVENT                             EndOfDxeEvent;\r
   EFI_PHYSICAL_ADDRESS                  Address;\r
 \r
   mBuffer            = NULL;\r
@@ -726,6 +768,15 @@ OpalPasswordSmmInit (
   //\r
   mSwSmiValue = (UINT8) Context.SwSmiInputValue;\r
 \r
+  //\r
+  // Create event to record GCD descriptors at end of dxe for judging AHCI/NVMe PCI Bar\r
+  // is in MMIO space to avoid attack.\r
+  //\r
+  Status = gSmst->SmmRegisterProtocolNotify (&gEfiSmmEndOfDxeProtocolGuid, OpalPasswordEndOfDxeNotification, &EndOfDxeEvent);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG((DEBUG_ERROR, "OpalPasswordSmm: Register SmmEndOfDxe fail, Status: %r\n", Status));\r
+    goto EXIT;\r
+  }\r
   Status = gSmst->SmmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID**)&SmmVariable);\r
   if (!EFI_ERROR (Status)) {\r
     DataSize = sizeof (OPAL_EXTRA_INFO_VAR);\r
index f365136918d979501851fd84cb74b1f7994d345b..ab31a6bfe7bc59b8b2dc0a34468047f8861961da 100644 (file)
@@ -25,6 +25,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Protocol/SmmReadyToLock.h>\r
 #include <Protocol/SmmVariable.h>\r
 #include <Protocol/VariableLock.h>\r
+#include <Protocol/SmmEndOfDxe.h>\r
 #include <Protocol/StorageSecurityCommand.h>\r
 \r
 #include <Library/OpalPasswordSupportLib.h>\r
@@ -43,8 +44,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Library/UefiLib.h>\r
 #include <Library/S3BootScriptLib.h>\r
 #include <Library/DevicePathLib.h>\r
-#include <Library/SmmMemLib.h>\r
-\r
 #include <Library/DxeServicesTableLib.h>\r
 \r
 #include <IndustryStandard/Pci22.h>\r
@@ -71,6 +70,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 extern VOID                              *mBuffer;\r
 \r
+extern EFI_GCD_MEMORY_SPACE_DESCRIPTOR   *mGcdMemSpace;\r
+extern UINTN                             mNumberOfDescriptors;\r
 #pragma pack(1)\r
 \r
 typedef struct {\r
index dae51ece029598d599def6dc08e3875d62ba1ff9..cab0fd5656d93c0d3523018d7e095be1eb3ccbcb 100644 (file)
@@ -58,7 +58,6 @@
   DxeServicesTableLib\r
   DevicePathLib\r
   OpalPasswordSupportLib\r
-  SmmMemLib\r
 \r
 [Guids]\r
   gOpalExtraInfoVariableGuid                    ## CONSUMES ## GUID\r
@@ -70,6 +69,7 @@
   gEfiSmmSxDispatch2ProtocolGuid                ## CONSUMES\r
   gEfiSmmVariableProtocolGuid                   ## CONSUMES\r
   gEfiStorageSecurityCommandProtocolGuid        ## CONSUMES\r
+  gEfiSmmEndOfDxeProtocolGuid                   ## CONSUMES\r
 \r
 [Depex]\r
   gEfiSmmSwDispatch2ProtocolGuid AND\r