* [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