* [PATCH 0/1] OvmfPkg/QemuFwCfgDxeLib: SEV: zero FW_CFG_DMA_ACCESS before decrypting it @ 2017-08-28 12:39 Laszlo Ersek 2017-08-28 12:39 ` [PATCH 1/1] " Laszlo Ersek 0 siblings, 1 reply; 5+ messages in thread From: Laszlo Ersek @ 2017-08-28 12:39 UTC (permalink / raw) To: edk2-devel-01; +Cc: Brijesh Singh, Jordan Justen, Tom Lendacky This crossed my mind previously in <http://mid.mail-archive.com/1d6bade7-578e-c0e7-5aa6-2ca6af1185e6@redhat.com>, point (4), and now I thought I should search for EdkiiIoMmuOperationBusMasterCommonBuffer too, not just VirtioOperationBusMasterCommonBuffer. Repo: https://github.com/lersek/edk2.git Branch: fwcfg_sev_commonbuffer Cc: Brijesh Singh <brijesh.singh@amd.com> Cc: Jordan Justen <jordan.l.justen@intel.com> Cc: Tom Lendacky <thomas.lendacky@amd.com> Thanks Laszlo Laszlo Ersek (1): OvmfPkg/QemuFwCfgDxeLib: SEV: zero FW_CFG_DMA_ACCESS before decrypting it OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c | 7 +++++++ 1 file changed, 7 insertions(+) -- 2.14.1.3.gb7cf6e02401b ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/1] OvmfPkg/QemuFwCfgDxeLib: SEV: zero FW_CFG_DMA_ACCESS before decrypting it 2017-08-28 12:39 [PATCH 0/1] OvmfPkg/QemuFwCfgDxeLib: SEV: zero FW_CFG_DMA_ACCESS before decrypting it Laszlo Ersek @ 2017-08-28 12:39 ` Laszlo Ersek 2017-08-29 5:11 ` Jordan Justen 2017-08-29 14:02 ` Brijesh Singh 0 siblings, 2 replies; 5+ messages in thread From: Laszlo Ersek @ 2017-08-28 12:39 UTC (permalink / raw) To: edk2-devel-01; +Cc: Brijesh Singh, Jordan Justen, Tom Lendacky 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 <brijesh.singh@amd.com> Cc: Jordan Justen <jordan.l.justen@intel.com> Cc: Tom Lendacky <thomas.lendacky@amd.com> Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Laszlo Ersek <lersek@redhat.com> --- 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 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 1/1] OvmfPkg/QemuFwCfgDxeLib: SEV: zero FW_CFG_DMA_ACCESS before decrypting it 2017-08-28 12:39 ` [PATCH 1/1] " Laszlo Ersek @ 2017-08-29 5:11 ` Jordan Justen 2017-08-29 14:02 ` Brijesh Singh 1 sibling, 0 replies; 5+ messages in thread From: Jordan Justen @ 2017-08-29 5:11 UTC (permalink / raw) To: Laszlo Ersek, edk2-devel-01; +Cc: Brijesh Singh, Tom Lendacky Reviewed-by: Jordan Justen <jordan.l.justen@intel.com> 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 <brijesh.singh@amd.com> > Cc: Jordan Justen <jordan.l.justen@intel.com> > Cc: Tom Lendacky <thomas.lendacky@amd.com> > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Laszlo Ersek <lersek@redhat.com> > --- > 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 > ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/1] OvmfPkg/QemuFwCfgDxeLib: SEV: zero FW_CFG_DMA_ACCESS before decrypting it 2017-08-28 12:39 ` [PATCH 1/1] " Laszlo Ersek 2017-08-29 5:11 ` Jordan Justen @ 2017-08-29 14:02 ` Brijesh Singh 2017-08-29 20:47 ` Laszlo Ersek 1 sibling, 1 reply; 5+ messages in thread From: Brijesh Singh @ 2017-08-29 14:02 UTC (permalink / raw) To: Laszlo Ersek, edk2-devel-01; +Cc: brijesh.singh, Jordan Justen, Tom Lendacky On 08/28/2017 07:39 AM, 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 <brijesh.singh@amd.com> > Cc: Jordan Justen <jordan.l.justen@intel.com> > Cc: Tom Lendacky <thomas.lendacky@amd.com> > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Brijesh Singh <brijesh.singh@amd.com> ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/1] OvmfPkg/QemuFwCfgDxeLib: SEV: zero FW_CFG_DMA_ACCESS before decrypting it 2017-08-29 14:02 ` Brijesh Singh @ 2017-08-29 20:47 ` Laszlo Ersek 0 siblings, 0 replies; 5+ messages in thread From: Laszlo Ersek @ 2017-08-29 20:47 UTC (permalink / raw) To: Brijesh Singh, edk2-devel-01; +Cc: Jordan Justen, Tom Lendacky On 08/29/17 16:02, Brijesh Singh wrote: > > > On 08/28/2017 07:39 AM, 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 <brijesh.singh@amd.com> >> Cc: Jordan Justen <jordan.l.justen@intel.com> >> Cc: Tom Lendacky <thomas.lendacky@amd.com> >> Contributed-under: TianoCore Contribution Agreement 1.1 >> Signed-off-by: Laszlo Ersek <lersek@redhat.com> > > > Reviewed-by: Brijesh Singh <brijesh.singh@amd.com> Thank you guys for the reviews, pushed as commit d431d8339e8b. Laszlo ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2017-08-29 20:44 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2017-08-28 12:39 [PATCH 0/1] OvmfPkg/QemuFwCfgDxeLib: SEV: zero FW_CFG_DMA_ACCESS before decrypting it Laszlo Ersek 2017-08-28 12:39 ` [PATCH 1/1] " Laszlo Ersek 2017-08-29 5:11 ` Jordan Justen 2017-08-29 14:02 ` Brijesh Singh 2017-08-29 20:47 ` Laszlo Ersek
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox