Reviewed-by: Jordan Justen <[email protected]>
On 2017-08-28 08:39:28, Laszlo Ersek wrote: > There's a small window between > > - AllocFwCfgDmaAccessBuffer() mapping the new FW_CFG_DMA_ACCESS object for > common buffer operation (i.e., decrypting it), and > > - InternalQemuFwCfgDmaBytes() setting the fields of the object. > > In this window, earlier garbage in the object is "leaked" to the > hypervisor. So zero the object before we decrypt it. > > (This commit message references AMD SEV directly, because QemuFwCfgDxeLib > is not *generally* enabled for IOMMU operation just yet, unlike our goal > for the virtio infrastructure. Instead, QemuFwCfgDxeLib uses > MemEncryptSevLib explicitly to detect SEV, and then relies on IOMMU > protocol behavior that is specific to SEV. At this point, this is by > design.) > > Cc: Brijesh Singh <[email protected]> > Cc: Jordan Justen <[email protected]> > Cc: Tom Lendacky <[email protected]> > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Laszlo Ersek <[email protected]> > --- > OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c | 7 +++++++ > 1 file changed, 7 insertions(+) > > diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c > b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c > index 8b98208591e6..22077851a40c 100644 > --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c > +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c > @@ -1,29 +1,30 @@ > /** @file > > Stateful and implicitly initialized fw_cfg library implementation. > > Copyright (C) 2013, Red Hat, Inc. > Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR> > Copyright (c) 2017, Advanced Micro Devices. All rights reserved.<BR> > > This program and the accompanying materials are licensed and made available > under the terms and conditions of the BSD License which accompanies this > distribution. The full text of the license may be found at > http://opensource.org/licenses/bsd-license.php > > THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > WITHOUT > WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. > **/ > > #include <Uefi.h> > > #include <Protocol/IoMmu.h> > > #include <Library/BaseLib.h> > +#include <Library/BaseMemoryLib.h> > #include <Library/IoLib.h> > #include <Library/DebugLib.h> > #include <Library/QemuFwCfgLib.h> > #include <Library/UefiBootServicesTableLib.h> > #include <Library/MemEncryptSevLib.h> > > #include "QemuFwCfgLibInternal.h" > @@ -155,75 +156,81 @@ VOID > AllocFwCfgDmaAccessBuffer ( > OUT VOID **Access, > OUT VOID **MapInfo > ) > { > UINTN Size; > UINTN NumPages; > EFI_STATUS Status; > VOID *HostAddress; > EFI_PHYSICAL_ADDRESS DmaAddress; > VOID *Mapping; > > Size = sizeof (FW_CFG_DMA_ACCESS); > NumPages = EFI_SIZE_TO_PAGES (Size); > > // > // As per UEFI spec, in order to map a host address with > // BusMasterCommomBuffer64, the buffer must be allocated using the IOMMU > // AllocateBuffer() > // > Status = mIoMmuProtocol->AllocateBuffer ( > mIoMmuProtocol, > AllocateAnyPages, > EfiBootServicesData, > NumPages, > &HostAddress, > EDKII_IOMMU_ATTRIBUTE_DUAL_ADDRESS_CYCLE > ); > if (EFI_ERROR (Status)) { > DEBUG ((DEBUG_ERROR, > "%a:%a failed to allocate FW_CFG_DMA_ACCESS\n", gEfiCallerBaseName, > __FUNCTION__)); > ASSERT (FALSE); > CpuDeadLoop (); > } > > + // > + // Avoid exposing stale data even temporarily: zero the area before mapping > + // it. > + // > + ZeroMem (HostAddress, Size); > + > // > // Map the host buffer with BusMasterCommonBuffer64 > // > Status = mIoMmuProtocol->Map ( > mIoMmuProtocol, > EdkiiIoMmuOperationBusMasterCommonBuffer64, > HostAddress, > &Size, > &DmaAddress, > &Mapping > ); > if (EFI_ERROR (Status)) { > mIoMmuProtocol->FreeBuffer (mIoMmuProtocol, NumPages, HostAddress); > DEBUG ((DEBUG_ERROR, > "%a:%a failed to Map() FW_CFG_DMA_ACCESS\n", gEfiCallerBaseName, > __FUNCTION__)); > ASSERT (FALSE); > CpuDeadLoop (); > } > > if (Size < sizeof (FW_CFG_DMA_ACCESS)) { > mIoMmuProtocol->Unmap (mIoMmuProtocol, Mapping); > mIoMmuProtocol->FreeBuffer (mIoMmuProtocol, NumPages, HostAddress); > DEBUG ((DEBUG_ERROR, > "%a:%a failed to Map() - requested 0x%Lx got 0x%Lx\n", > gEfiCallerBaseName, > __FUNCTION__, (UINT64)sizeof (FW_CFG_DMA_ACCESS), (UINT64)Size)); > ASSERT (FALSE); > CpuDeadLoop (); > } > > *Access = HostAddress; > *MapInfo = Mapping; > } > > /** > Function is to used for freeing the Access buffer allocated using > AllocFwCfgDmaAccessBuffer() > > **/ > -- > 2.14.1.3.gb7cf6e02401b > _______________________________________________ edk2-devel mailing list [email protected] https://lists.01.org/mailman/listinfo/edk2-devel

