OvmfPkg: improve SMM comms security with adaptive MemoryTypeInformation

* In the Intel whitepaper:

--v--
A Tour Beyond BIOS -- Secure SMM Communication

https://github.com/tianocore/tianocore.github.io/wiki/EDK-II-Security-White-Papers
https://github.com/tianocore-docs/Docs/raw/master/White_Papers/A_Tour_Beyond_BIOS_Secure_SMM_Communication.pdf
--^--

bullet#3 in section "Assumption and Recommendation", and bullet#4 in "Call
for action", recommend enabling the (adaptive) Memory Type Information
feature.

* In the Intel whitepaper:

--v--
A Tour Beyond BIOS -- Memory Map and Practices in UEFI BIOS

https://github.com/tianocore/tianocore.github.io/wiki/EDK-II-white-papers
https://github.com/tianocore-docs/Docs/raw/master/White_Papers/A_Tour_Beyond_BIOS_Memory_Map_And_Practices_in_UEFI_BIOS_V2.pdf
--^--

figure#6 describes the Memory Type Information feature in detail; namely
as a feedback loop between the Platform PEIM, the DXE IPL PEIM, the DXE
Core, and BDS.

Implement the missing PlatformPei functionality in OvmfPkg, for fulfilling
the Secure SMM Communication recommendation.

In the longer term, OVMF should install the WSMT ACPI table, and this
patch contributes to that.

Notes:

- the step in figure#6 where the UEFI variable is copied into the HOB is
  covered by the DXE IPL PEIM, in the DxeLoadCore() function,

- "PcdResetOnMemoryTypeInformationChange" must be reverted to the DEC
  default TRUE value, because both whitepapers indicate that BDS needs to
  reset the system if the Memory Type Information changes.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Philippe Mathieu-Daudé <philmd@redhat.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=386
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20200310222739.26717-6-lersek@redhat.com>
Acked-by: Leif Lindholm <leif@nuviainc.com>
This commit is contained in:
Laszlo Ersek 2020-03-10 23:27:39 +01:00 committed by mergify[bot]
parent 89465fe9e0
commit d42fdd6f83
7 changed files with 161 additions and 22 deletions

View File

@ -448,7 +448,9 @@
[PcdsFixedAtBuild]
gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeMemorySize|1
!if $(SMM_REQUIRE) == FALSE
gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
!endif
gEfiMdePkgTokenSpaceGuid.PcdMaximumGuidedExtractHandler|0x10
!if ($(FD_SIZE_IN_KB) == 1024) || ($(FD_SIZE_IN_KB) == 2048)
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000

View File

@ -452,7 +452,9 @@
[PcdsFixedAtBuild]
gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeMemorySize|1
!if $(SMM_REQUIRE) == FALSE
gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
!endif
gEfiMdePkgTokenSpaceGuid.PcdMaximumGuidedExtractHandler|0x10
!if ($(FD_SIZE_IN_KB) == 1024) || ($(FD_SIZE_IN_KB) == 2048)
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000

View File

@ -452,7 +452,9 @@
[PcdsFixedAtBuild]
gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeMemorySize|1
!if $(SMM_REQUIRE) == FALSE
gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
!endif
gEfiMdePkgTokenSpaceGuid.PcdMaximumGuidedExtractHandler|0x10
!if ($(FD_SIZE_IN_KB) == 1024) || ($(FD_SIZE_IN_KB) == 2048)
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000

View File

@ -0,0 +1,147 @@
/** @file
Produce a default memory type information HOB unless we can determine, from
the existence of the "MemoryTypeInformation" variable, that the DXE IPL PEIM
will produce the HOB.
Copyright (C) 2017-2020, Red Hat, Inc.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Guid/MemoryTypeInformation.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/HobLib.h>
#include <Library/PcdLib.h>
#include <Library/PeiServicesLib.h>
#include <Ppi/ReadOnlyVariable2.h>
#include <Uefi/UefiMultiPhase.h>
#include "Platform.h"
STATIC EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = {
{ EfiACPIMemoryNVS, 0x004 },
{ EfiACPIReclaimMemory, 0x008 },
{ EfiReservedMemoryType, 0x004 },
{ EfiRuntimeServicesData, 0x024 },
{ EfiRuntimeServicesCode, 0x030 },
{ EfiBootServicesCode, 0x180 },
{ EfiBootServicesData, 0xF00 },
{ EfiMaxMemoryType, 0x000 }
};
STATIC
VOID
BuildMemTypeInfoHob (
VOID
)
{
BuildGuidDataHob (
&gEfiMemoryTypeInformationGuid,
mDefaultMemoryTypeInformation,
sizeof mDefaultMemoryTypeInformation
);
DEBUG ((DEBUG_INFO, "%a: default memory type information HOB built\n",
__FUNCTION__));
}
/**
Notification function called when EFI_PEI_READ_ONLY_VARIABLE2_PPI becomes
available.
@param[in] PeiServices Indirect reference to the PEI Services Table.
@param[in] NotifyDescriptor Address of the notification descriptor data
structure.
@param[in] Ppi Address of the PPI that was installed.
@return Status of the notification. The status code returned from this
function is ignored.
**/
STATIC
EFI_STATUS
EFIAPI
OnReadOnlyVariable2Available (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
IN VOID *Ppi
)
{
EFI_PEI_READ_ONLY_VARIABLE2_PPI *ReadOnlyVariable2;
UINTN DataSize;
EFI_STATUS Status;
DEBUG ((DEBUG_VERBOSE, "%a\n", __FUNCTION__));
//
// Check if the "MemoryTypeInformation" variable exists, in the
// gEfiMemoryTypeInformationGuid namespace.
//
ReadOnlyVariable2 = Ppi;
DataSize = 0;
Status = ReadOnlyVariable2->GetVariable (
ReadOnlyVariable2,
EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,
&gEfiMemoryTypeInformationGuid,
NULL,
&DataSize,
NULL
);
switch (Status) {
case EFI_BUFFER_TOO_SMALL:
//
// The variable exists; the DXE IPL PEIM will build the HOB from it.
//
break;
case EFI_NOT_FOUND:
//
// The variable does not exist; install the default memory type information
// HOB.
//
BuildMemTypeInfoHob ();
break;
default:
DEBUG ((DEBUG_ERROR, "%a: unexpected: GetVariable(): %r\n", __FUNCTION__,
Status));
ASSERT (FALSE);
CpuDeadLoop ();
break;
}
return EFI_SUCCESS;
}
//
// Notification object for registering the callback, for when
// EFI_PEI_READ_ONLY_VARIABLE2_PPI becomes available.
//
STATIC CONST EFI_PEI_NOTIFY_DESCRIPTOR mReadOnlyVariable2Notify = {
(EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH |
EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), // Flags
&gEfiPeiReadOnlyVariable2PpiGuid, // Guid
OnReadOnlyVariable2Available // Notify
};
VOID
MemTypeInfoInitialization (
VOID
)
{
EFI_STATUS Status;
if (!FeaturePcdGet (PcdSmmSmramRequire)) {
//
// EFI_PEI_READ_ONLY_VARIABLE2_PPI will never be available; install
// the default memory type information HOB right away.
//
BuildMemTypeInfoHob ();
return;
}
Status = PeiServicesNotifyPpi (&mReadOnlyVariable2Notify);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a: failed to set up R/O Variable 2 callback: %r\n",
__FUNCTION__, Status));
ASSERT (FALSE);
CpuDeadLoop ();
}
}

View File

@ -28,7 +28,6 @@
#include <Library/QemuFwCfgLib.h>
#include <Library/QemuFwCfgS3Lib.h>
#include <Library/ResourcePublicationLib.h>
#include <Guid/MemoryTypeInformation.h>
#include <Ppi/MasterBootMode.h>
#include <IndustryStandard/I440FxPiix4.h>
#include <IndustryStandard/Pci22.h>
@ -39,18 +38,6 @@
#include "Platform.h"
#include "Cmos.h"
EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = {
{ EfiACPIMemoryNVS, 0x004 },
{ EfiACPIReclaimMemory, 0x008 },
{ EfiReservedMemoryType, 0x004 },
{ EfiRuntimeServicesData, 0x024 },
{ EfiRuntimeServicesCode, 0x030 },
{ EfiBootServicesCode, 0x180 },
{ EfiBootServicesData, 0xF00 },
{ EfiMaxMemoryType, 0x000 }
};
EFI_PEI_PPI_DESCRIPTOR mPpiBootMode[] = {
{
EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
@ -162,15 +149,6 @@ MemMapInitialization (
PciIoBase = 0xC000;
PciIoSize = 0x4000;
//
// Create Memory Type Information HOB
//
BuildGuidDataHob (
&gEfiMemoryTypeInformationGuid,
mDefaultMemoryTypeInformation,
sizeof(mDefaultMemoryTypeInformation)
);
//
// Video memory + Legacy BIOS region
//
@ -811,6 +789,7 @@ InitializePlatform (
ReserveEmuVariableNvStore ();
}
PeiFvInitialization ();
MemTypeInfoInitialization ();
MemMapInitialization ();
NoexecDxeInitialization ();
}

View File

@ -82,6 +82,11 @@ PeiFvInitialization (
VOID
);
VOID
MemTypeInfoInitialization (
VOID
);
VOID
InstallFeatureControlCallback (
VOID

View File

@ -30,6 +30,7 @@
FeatureControl.c
Fv.c
MemDetect.c
MemTypeInfo.c
Platform.c
Platform.h
Xen.c
@ -112,6 +113,7 @@
[Ppis]
gEfiPeiMasterBootModePpiGuid
gEfiPeiMpServicesPpiGuid
gEfiPeiReadOnlyVariable2PpiGuid
[Depex]
TRUE