REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3768
When processing DMAR structures of type
EFI_ACPI_DMAR_STRUCTURE_HEADER within the ACPI DMAR table, the code
determines the structure length by subtracting the DMAR structure
headers present from the overall DMAR ACPI table size.
The terminating condition is that the remaining total DMAR length
is greater than zero. However, the current DMAR structure length
is subtracted after the DMAR structure pointer has already been
assigned to the next structure.
This change subtracts the current DMAR structure length before
transitioning to the next structure.
The terminating condition is also updated to ensure the remaining
size is at least as large as the expected structure header size.
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Eric Dong <eric.dong@intel.com>
Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
Reviewed-by: Nate DeSimone <nathaniel.l.desimone@intel.com>
Speculative execution is used by processor to avoid having to wait for
data to arrive from memory, or for previous operations to finish, the
processor may speculate as to what will be executed.
If the speculation is incorrect, the speculatively executed instructions
might leave hints such as which memory locations have been brought into
cache. Malicious actors can use the bounds check bypass method (code
gadgets with controlled external inputs) to infer data values that have
been used in speculative operations to reveal secrets which should not
otherwise be accessed.
This commit will focus on the SMI handler(s) registered within
TestPointCheckLib & TestPointLib and insert AsmLfence API to mitigate the
bounds check bypass issue.
A. For SMI handler TestPointSmmHandler() within TestPointCheckLib:
Under "case TEST_POINT_SMM_COMMUNICATION_FUNC_ID_UEFI_GCD_MAP_INFO:",
'CommBuffer' (controlled external inputs) is passed into function
TestPointSmmReadyToBootSmmPageProtectionHandler().
Within function TestPointSmmReadyToBootSmmPageProtectionHandler(), the
contents in 'CommBuffer' will be copied into 'CommData'. But if the size
and sanity checks for the communication buffer is speculatively bypassed,
'(UINTN)CommData + CommData->UefiMemoryMapOffset)' can potentially point
to cross boundary area of 'CommData'. This pointer is then passed into
function TestPointCheckSmmCommunicationBuffer() as 'UefiMemoryMap'.
Within function TestPointCheckSmmCommunicationBuffer(),
'MemoryMap->PhysicalStart' can be a potential cross boundary access. And
its value can be inferred by function calls sequence:
TestPointCheckPageTable() via 'BaseAddress'
GetPageTableEntry() via 'BaseAddress'. Then one can observe which part of
the content within arrays 'L4PageTable', 'L3PageTable', 'L2PageTable' or
'L1PageTable', was brought into cache to possibly reveal the value.
B. For SMI handler SmmTestPointSmiHandler() within TestPointLib:
Under "case SMI_HANDLER_TEST_POINT_COMMAND_GET_DATA_BY_OFFSET:",
'CommBuffer' (controlled external inputs) is passed into function
SmmTestPointSmiHandlerGetDataByOffset().
Within function SmmTestPointSmiHandlerGetDataByOffset(), the contents in
'CommBuffer' will be copied into 'SmiHandlerTestPointGetDataByOffset'. But
if the size and sanity checks for the communication buffer is
speculatively bypassed, 'SmiHandlerTestPointGetDataByOffset.DataSize' can
be a potential cross boundary access.
Then in function SmiHandlerTestPointCopyData(), this value can be inferred
by code:
CopyMem(
DataBuffer,
(UINT8 *)InputData + *DataOffset,
(UINTN)*DataSize
);
One can observe which part of the content within 'DataBuffer' was brought
into cache to possibly reveal the cross boundary access value.
Hence, this commit adds AsmLfence() calls after the boundary/range checks
of the communication buffer to prevent the speculative execution.
A more detailed explanation of the purpose of commit is under the
'Bounds check bypass mitigation' section of the below link:
https://software.intel.com/security-software-guidance/insights/host-firmware-speculative-execution-side-channel-mitigation
And the document at:
https://software.intel.com/security-software-guidance/api-app/sites/default/files/337879-analyzing-potential-bounds-Check-bypass-vulnerabilities.pdf
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Hao Wu <hao.a.wu@intel.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
1) MinPlatform.dec
a) Add PcdFspWrapperBootMode to control different behavior in FSP wrapper mode and EDKII mode (by PlatformInitPei)
b) Add gPeiBaseMemoryTestPpiGuid and gPeiPlatformMemorySizePpiGuid – they are used for EDKII boot mode.
c) Rename MADT related PCD for server (PcdLocalApicAddress/PcdLocalApicMmioSize/PcdIoApicAddress/PcdIoApicMmioSize/PcdIoApicId)
d) Add MADT related PCD for multi IO APIC for server (PcdPcIoApicCount/PcdPcIoApicIdBase/PcdPcIoApicAddressBase/PcdPcIoApicInterruptBase)
e) Add HPET related PCD (PcdHpetTimerBlockId)
f) Add FADT related PCD (PcdFadtPreferredPmProfile/PcdFadtIaPcBootArch/PcdFadtFlags)
g) Add PCD for DXE Silicon module flash address (PcdFlashFvFspUBase/PcdFlashFvFspUSize/PcdFlashFvFspUOffset)
h) Make Flash Address PCD to be patchable, so that it can be updated in binary FV.
2) Include
a) DSC/FDF: Do not always include the module, which might be from silicon code, such as SEC/CpuDxe/SmmCpu/PciHostBridge.
b) DSC/FDF: UiApp.inf – fix a bug that UIAPP does not have boot manager.
c) DSC/FDF: DP.inf – sync to latest performance dump tool in ShellPkg.
3) Update AcpiPlatform for server platform
a) Construct MADT from scratch.
b) Construct MCFG from scratch.
4) CompressLib
a) Add CompressLib class and instance so that MRC data can be compressed.
5) PlatformInitPei
a) Produce BaseMemoryTestPpi and PlatformMemorySizePpi in EDKII boot mode.
b) Install FV in FSPM/FSPS/FSPU in EDKII boot mode.
c) Move SecurityFv/AdvancedFv installation from SEC to PlatformInitPei.
d) Remove BuildFvHob for flash region – it is a bug.
e) Mark above 4GiB MMIO to be uncatchable.
6) PciSegmentInfoLib
a) Handle the case that the lib is linked by a DXE module only.
7) PlatformSecLib
a) Move SecurityFv/AdvancedFv installation from SEC to PlatformInitPei.
8) SpiFvbService
a) Do not use fixed PCD, so that the address can be patchable.
9) TestPoint
a) Enhance the logic to check if a memory is in save state area or not. (Support PcdCpuHotPlugSupport)
10) Add python tool
a) AmlGenOffset.py – generate ACPI patch table.
b) ParseVar.py – parse the VarBin generated by FCE tool and output PCD value.
c) PatchFv/PatchBfv.py – patch the BFV address in ResetVector.bin
d) PatchFv/PatchBinFv.py – patch patchable PCD in a given FV according to build report.
e) PatchFv/RebaseBinFv.py – rebase a given FV to a new address.
f) PatchFv/SyncBinFvInf.py – generate INF for a binary FV.
Cc: Michael A Kubacki <michael.a.kubacki@intel.com>
Cc: Amy Chan <amy.chan@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
Cc: Isaac W Oram <isaac.w.oram@intel.com>
Cc: Brett Wang <brett.wang@intel.com>
Cc: Daocheng Bu <daocheng.bu@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>