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