* [PATCH v5 1/9] MdeModulePkg: Add new PCD to control the evacuate temporary memory feature (CVE-2019-11098)
2020-07-09 1:56 [PATCH v5 0/9] Add new feature that evacuate temporary to permanent memory (CVE-2019-11098) Guomin Jiang
@ 2020-07-09 1:56 ` Guomin Jiang
2020-07-13 2:54 ` Wang, Jian J
2020-07-09 1:56 ` [PATCH v5 2/9] MdeModulePkg/PeiCore: Enable T-RAM evacuation in PeiCore (CVE-2019-11098) Guomin Jiang
` (8 subsequent siblings)
9 siblings, 1 reply; 24+ messages in thread
From: Guomin Jiang @ 2020-07-09 1:56 UTC (permalink / raw)
To: devel; +Cc: Jian J Wang, Hao A Wu, Laszlo Ersek
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=1614
The security researcher found that we can get control after NEM disable.
The reason is that the flash content reside in NEM at startup and the
code will get the content from flash directly after disable NEM.
To avoid this vulnerability, the feature will copy the PEIMs from
temporary memory to permanent memory and only execute the code in
permanent memory.
The vulnerability is exist in physical platform and haven't report in
virtual platform, so the virtual can disable the feature currently.
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Hao A Wu <hao.a.wu@intel.com>
Signed-off-by: Guomin Jiang <guomin.jiang@intel.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
---
MdeModulePkg/MdeModulePkg.dec | 7 +++++++
MdeModulePkg/MdeModulePkg.uni | 6 ++++++
2 files changed, 13 insertions(+)
diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
index 843e963ad34b..16db17d0a873 100644
--- a/MdeModulePkg/MdeModulePkg.dec
+++ b/MdeModulePkg/MdeModulePkg.dec
@@ -1220,6 +1220,13 @@ [PcdsFixedAtBuild, PcdsPatchableInModule]
# @Prompt Shadow Peim and PeiCore on boot
gEfiMdeModulePkgTokenSpaceGuid.PcdShadowPeimOnBoot|TRUE|BOOLEAN|0x30001029
+ ## Enable the feature that evacuate temporary memory to permanent memory or not
+ # Set FALSE as default, if the developer need this feature to avoid this vulnerability, please
+ # enable it in dsc file.
+ # TRUE - Evacuate temporary memory, the actions include copy memory, convert PPI pointers and so on.
+ # FALSE - Do nothing, for example, no copy memory, no convert PPI pointers and so on.
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMigrateTemporaryRamFirmwareVolumes|FALSE|BOOLEAN|0x3000102A
+
## The mask is used to control memory profile behavior.<BR><BR>
# BIT0 - Enable UEFI memory profile.<BR>
# BIT1 - Enable SMRAM profile.<BR>
diff --git a/MdeModulePkg/MdeModulePkg.uni b/MdeModulePkg/MdeModulePkg.uni
index 2007e0596c4f..5235dee561ad 100644
--- a/MdeModulePkg/MdeModulePkg.uni
+++ b/MdeModulePkg/MdeModulePkg.uni
@@ -214,6 +214,12 @@
"TRUE - Shadow PEIM on S3 boot path after memory is ready.<BR>\n"
"FALSE - Not shadow PEIM on S3 boot path after memory is ready.<BR>"
+#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdMigrateTemporaryRamFirmwareVolumes_HELP #language en-US "Enable the feature that evacuate temporary memory to permanent memory or not.<BR><BR>\n"
+ "It will allocate page to save the temporary PEIMs resided in NEM(or CAR) to the permanent memory and change all pointers pointed to the NEM(or CAR) to permanent memory.<BR><BR>\n"
+ "After then, there are no pointer pointed to NEM(or CAR) and TOCTOU volnerability can be avoid.<BR><BR>\n"
+
+#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdMigrateTemporaryRamFirmwareVolumes_PROMPT #language en-US "Enable the feature that evacuate temporary memory to permanent memory or not"
+
#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdAcpiDefaultOemId_PROMPT #language en-US "Default OEM ID for ACPI table creation"
#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdAcpiDefaultOemId_HELP #language en-US "Default OEM ID for ACPI table creation, its length must be 0x6 bytes to follow ACPI specification."
--
2.25.1.windows.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH v5 1/9] MdeModulePkg: Add new PCD to control the evacuate temporary memory feature (CVE-2019-11098)
2020-07-09 1:56 ` [PATCH v5 1/9] MdeModulePkg: Add new PCD to control the evacuate temporary memory feature (CVE-2019-11098) Guomin Jiang
@ 2020-07-13 2:54 ` Wang, Jian J
0 siblings, 0 replies; 24+ messages in thread
From: Wang, Jian J @ 2020-07-13 2:54 UTC (permalink / raw)
To: Jiang, Guomin, devel@edk2.groups.io; +Cc: Wu, Hao A, Laszlo Ersek
Guomin,
> -----Original Message-----
> From: Jiang, Guomin <guomin.jiang@intel.com>
> Sent: Thursday, July 09, 2020 9:57 AM
> To: devel@edk2.groups.io
> Cc: Wang, Jian J <jian.j.wang@intel.com>; Wu, Hao A <hao.a.wu@intel.com>;
> Laszlo Ersek <lersek@redhat.com>
> Subject: [PATCH v5 1/9] MdeModulePkg: Add new PCD to control the evacuate
> temporary memory feature (CVE-2019-11098)
>
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=1614
>
> The security researcher found that we can get control after NEM disable.
>
> The reason is that the flash content reside in NEM at startup and the
> code will get the content from flash directly after disable NEM.
>
> To avoid this vulnerability, the feature will copy the PEIMs from
> temporary memory to permanent memory and only execute the code in
> permanent memory.
>
> The vulnerability is exist in physical platform and haven't report in
> virtual platform, so the virtual can disable the feature currently.
>
> Cc: Jian J Wang <jian.j.wang@intel.com>
> Cc: Hao A Wu <hao.a.wu@intel.com>
> Signed-off-by: Guomin Jiang <guomin.jiang@intel.com>
> Acked-by: Laszlo Ersek <lersek@redhat.com>
> ---
> MdeModulePkg/MdeModulePkg.dec | 7 +++++++
> MdeModulePkg/MdeModulePkg.uni | 6 ++++++
> 2 files changed, 13 insertions(+)
>
> diff --git a/MdeModulePkg/MdeModulePkg.dec
> b/MdeModulePkg/MdeModulePkg.dec
> index 843e963ad34b..16db17d0a873 100644
> --- a/MdeModulePkg/MdeModulePkg.dec
> +++ b/MdeModulePkg/MdeModulePkg.dec
> @@ -1220,6 +1220,13 @@ [PcdsFixedAtBuild, PcdsPatchableInModule]
> # @Prompt Shadow Peim and PeiCore on boot
>
> gEfiMdeModulePkgTokenSpaceGuid.PcdShadowPeimOnBoot|TRUE|BOOLEAN|
> 0x30001029
>
> + ## Enable the feature that evacuate temporary memory to permanent
> memory or not
> + # Set FALSE as default, if the developer need this feature to avoid this
> vulnerability, please
> + # enable it in dsc file.
> + # TRUE - Evacuate temporary memory, the actions include copy memory,
> convert PPI pointers and so on.
> + # FALSE - Do nothing, for example, no copy memory, no convert PPI pointers
> and so on.
Missing @Prompt tag here. With it addressed,
Reviewed-by: Jian J Wang <jian.j.wang@intel.com>
Regards,
Jian
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdMigrateTemporaryRamFirmwareVolum
> es|FALSE|BOOLEAN|0x3000102A
> +
> ## The mask is used to control memory profile behavior.<BR><BR>
> # BIT0 - Enable UEFI memory profile.<BR>
> # BIT1 - Enable SMRAM profile.<BR>
> diff --git a/MdeModulePkg/MdeModulePkg.uni
> b/MdeModulePkg/MdeModulePkg.uni
> index 2007e0596c4f..5235dee561ad 100644
> --- a/MdeModulePkg/MdeModulePkg.uni
> +++ b/MdeModulePkg/MdeModulePkg.uni
> @@ -214,6 +214,12 @@
> "TRUE - Shadow PEIM on S3
> boot path after memory is ready.<BR>\n"
> "FALSE - Not shadow PEIM on
> S3 boot path after memory is ready.<BR>"
>
> +#string
> STR_gEfiMdeModulePkgTokenSpaceGuid_PcdMigrateTemporaryRamFirmwareV
> olumes_HELP #language en-US "Enable the feature that evacuate temporary
> memory to permanent memory or not.<BR><BR>\n"
> + "It will allocate page to
> save the temporary PEIMs resided in NEM(or CAR) to the permanent memory
> and change all pointers pointed to the NEM(or CAR) to permanent
> memory.<BR><BR>\n"
> + "After then, there are
> no pointer pointed to NEM(or CAR) and TOCTOU volnerability can be
> avoid.<BR><BR>\n"
> +
> +#string
> STR_gEfiMdeModulePkgTokenSpaceGuid_PcdMigrateTemporaryRamFirmwareV
> olumes_PROMPT #language en-US "Enable the feature that evacuate temporary
> memory to permanent memory or not"
> +
> #string
> STR_gEfiMdeModulePkgTokenSpaceGuid_PcdAcpiDefaultOemId_PROMPT
> #language en-US "Default OEM ID for ACPI table creation"
>
> #string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdAcpiDefaultOemId_HELP
> #language en-US "Default OEM ID for ACPI table creation, its length must be 0x6
> bytes to follow ACPI specification."
> --
> 2.25.1.windows.1
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v5 2/9] MdeModulePkg/PeiCore: Enable T-RAM evacuation in PeiCore (CVE-2019-11098)
2020-07-09 1:56 [PATCH v5 0/9] Add new feature that evacuate temporary to permanent memory (CVE-2019-11098) Guomin Jiang
2020-07-09 1:56 ` [PATCH v5 1/9] MdeModulePkg: Add new PCD to control the evacuate temporary memory feature (CVE-2019-11098) Guomin Jiang
@ 2020-07-09 1:56 ` Guomin Jiang
2020-07-09 10:50 ` [edk2-devel] " Laszlo Ersek
2020-07-13 6:38 ` Wang, Jian J
2020-07-09 1:56 ` [PATCH v5 3/9] UefiCpuPkg/CpuMpPei: Add GDT and IDT migration support (CVE-2019-11098) Guomin Jiang
` (7 subsequent siblings)
9 siblings, 2 replies; 24+ messages in thread
From: Guomin Jiang @ 2020-07-09 1:56 UTC (permalink / raw)
To: devel
Cc: Michael Kubacki, Jian J Wang, Hao A Wu, Dandan Bi, Liming Gao,
Debkumar De, Harry Han, Catharine West
From: Michael Kubacki <michael.a.kubacki@intel.com>
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=1614
Introduces new changes to PeiCore to move the contents of temporary
RAM visible to the PeiCore to permanent memory. This expands on
pre-existing shadowing support in the PeiCore to perform the following
additional actions:
1. Migrate pointers in PPIs installed in PeiCore to the permanent
memory copy of PeiCore.
2. Copy all installed firmware volumes to permanent memory.
3. Relocate and fix up the PEIMs within the firmware volumes.
4. Convert all PPIs into the migrated firmware volume to the corresponding
PPI address in the permanent memory location.
This applies to PPIs and PEI notifications.
5. Convert all status code callbacks in the migrated firmware volume to
the corresponding address in the permanent memory location.
6. Update the FV HOB to the corresponding firmware volume in permanent
memory.
7. Add PcdMigrateTemporaryRamFirmwareVolumes to control if enable the
feature or not. when the PCD disable, the EvacuateTempRam() will
never be called.
The function control flow as below:
PeiCore()
DumpPpiList()
EvacuateTempRam()
ConvertPeiCorePpiPointers()
ConvertPpiPointersFv()
MigratePeimsInFv()
MigratePeim()
PeiGetPe32Data()
LoadAndRelocatePeCoffImageInPlace()
MigrateSecModulesInFv()
ConvertPpiPointersFv()
ConvertStatusCodeCallbacks()
ConvertFvHob()
RemoveFvHobsInTemporaryMemory()
DumpPpiList()
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Hao A Wu <hao.a.wu@intel.com>
Cc: Dandan Bi <dandan.bi@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Debkumar De <debkumar.de@intel.com>
Cc: Harry Han <harry.han@intel.com>
Cc: Catharine West <catharine.west@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
MdeModulePkg/Core/Pei/PeiMain.inf | 2 +
MdeModulePkg/Core/Pei/PeiMain.h | 168 ++++++++
MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c | 402 ++++++++++++++++++
MdeModulePkg/Core/Pei/Image/Image.c | 115 +++++
MdeModulePkg/Core/Pei/Memory/MemoryServices.c | 82 ++++
MdeModulePkg/Core/Pei/PeiMain/PeiMain.c | 24 ++
MdeModulePkg/Core/Pei/Ppi/Ppi.c | 287 +++++++++++++
7 files changed, 1080 insertions(+)
diff --git a/MdeModulePkg/Core/Pei/PeiMain.inf b/MdeModulePkg/Core/Pei/PeiMain.inf
index 6e25cc40232a..5b36d516b3fa 100644
--- a/MdeModulePkg/Core/Pei/PeiMain.inf
+++ b/MdeModulePkg/Core/Pei/PeiMain.inf
@@ -76,6 +76,7 @@ [Guids]
## CONSUMES ## UNDEFINED # Locate PPI
## CONSUMES ## GUID # Used to compare with FV's file system GUID and get the FV's file system format
gEfiFirmwareFileSystem3Guid
+ gStatusCodeCallbackGuid
[Ppis]
gEfiPeiStatusCodePpiGuid ## SOMETIMES_CONSUMES # PeiReportStatusService is not ready if this PPI doesn't exist
@@ -109,6 +110,7 @@ [Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdShadowPeimOnS3Boot ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdShadowPeimOnBoot ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdInitValueInTempStack ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMigrateTemporaryRamFirmwareVolumes ## CONSUMES
# [BootMode]
# S3_RESUME ## SOMETIMES_CONSUMES
diff --git a/MdeModulePkg/Core/Pei/PeiMain.h b/MdeModulePkg/Core/Pei/PeiMain.h
index 56b3bd85793d..b0101dba5e30 100644
--- a/MdeModulePkg/Core/Pei/PeiMain.h
+++ b/MdeModulePkg/Core/Pei/PeiMain.h
@@ -394,6 +394,41 @@ PeimDispatchReadiness (
IN VOID *DependencyExpression
);
+/**
+ Migrate a PEIM from Temporary RAM to permanent memory.
+
+ @param PeimFileHandle Pointer to the FFS file header of the image.
+ @param MigratedFileHandle Pointer to the FFS file header of the migrated image.
+
+ @retval EFI_SUCCESS Sucessfully migrated the PEIM to permanent memory.
+
+**/
+EFI_STATUS
+EFIAPI
+MigratePeim (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN EFI_PEI_FILE_HANDLE MigratedFileHandle
+ );
+
+/**
+ Migrate FVs out of Temporary RAM before the cache is flushed.
+
+ @param Private PeiCore's private data structure
+ @param SecCoreData Points to a data structure containing information about the PEI core's operating
+ environment, such as the size and location of temporary RAM, the stack location and
+ the BFV location.
+
+ @retval EFI_SUCCESS Succesfully migrated installed FVs from Temporary RAM to permanent memory.
+ @retval EFI_OUT_OF_RESOURCES Insufficient memory exists to allocate needed pages.
+
+**/
+EFI_STATUS
+EFIAPI
+EvacuateTempRam (
+ IN PEI_CORE_INSTANCE *Private,
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData
+ );
+
/**
Conduct PEIM dispatch.
@@ -477,6 +512,50 @@ ConvertPpiPointers (
IN PEI_CORE_INSTANCE *PrivateData
);
+/**
+
+ Migrate Notify Pointers inside an FV from temporary memory to permanent memory.
+
+ @param PrivateData Pointer to PeiCore's private data structure.
+ @param OrgFvHandle Address of FV Handle in temporary memory.
+ @param FvHandle Address of FV Handle in permanent memory.
+ @param FvSize Size of the FV.
+
+**/
+VOID
+ConvertPpiPointersFv (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ IN UINTN OrgFvHandle,
+ IN UINTN FvHandle,
+ IN UINTN FvSize
+ );
+
+/**
+
+ Migrate PPI Pointers of PEI_CORE from temporary memory to permanent memory.
+
+ @param PrivateData Pointer to PeiCore's private data structure.
+ @param CoreFvHandle Address of PEI_CORE FV Handle in temporary memory.
+
+**/
+VOID
+ConvertPeiCorePpiPointers (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ PEI_CORE_FV_HANDLE CoreFvHandle
+ );
+
+/**
+
+ Dumps the PPI lists to debug output.
+
+ @param PrivateData Points to PeiCore's private instance data.
+
+**/
+VOID
+DumpPpiList (
+ IN PEI_CORE_INSTANCE *PrivateData
+ );
+
/**
Install PPI services. It is implementation of EFI_PEI_SERVICE.InstallPpi.
@@ -808,6 +887,37 @@ PeiFfsFindNextFile (
IN OUT EFI_PEI_FILE_HANDLE *FileHandle
);
+/**
+ Go through the file to search SectionType section.
+ Search within encapsulation sections (compression and GUIDed) recursively,
+ until the match section is found.
+
+ @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
+ @param SectionType Filter to find only section of this type.
+ @param SectionInstance Pointer to the filter to find the specific instance of section.
+ @param Section From where to search.
+ @param SectionSize The file size to search.
+ @param OutputBuffer A pointer to the discovered section, if successful.
+ NULL if section not found
+ @param AuthenticationStatus Updated upon return to point to the authentication status for this section.
+ @param IsFfs3Fv Indicates the FV format.
+
+ @return EFI_NOT_FOUND The match section is not found.
+ @return EFI_SUCCESS The match section is found.
+
+**/
+EFI_STATUS
+ProcessSection (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_SECTION_TYPE SectionType,
+ IN OUT UINTN *SectionInstance,
+ IN EFI_COMMON_SECTION_HEADER *Section,
+ IN UINTN SectionSize,
+ OUT VOID **OutputBuffer,
+ OUT UINT32 *AuthenticationStatus,
+ IN BOOLEAN IsFfs3Fv
+ );
+
/**
Searches for the next matching section within the specified file.
@@ -931,6 +1041,33 @@ MigrateMemoryPages (
IN BOOLEAN TemporaryRamMigrated
);
+/**
+ Removes any FV HOBs whose base address is not in PEI installed memory.
+
+ @param[in] Private Pointer to PeiCore's private data structure.
+
+**/
+VOID
+RemoveFvHobsInTemporaryMemory (
+ IN PEI_CORE_INSTANCE *Private
+ );
+
+/**
+ Migrate the base address in firmware volume allocation HOBs
+ from temporary memory to PEI installed memory.
+
+ @param[in] PrivateData Pointer to PeiCore's private data structure.
+ @param[in] OrgFvHandle Address of FV Handle in temporary memory.
+ @param[in] FvHandle Address of FV Handle in permanent memory.
+
+**/
+VOID
+ConvertFvHob (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ IN UINTN OrgFvHandle,
+ IN UINTN FvHandle
+ );
+
/**
Migrate MemoryBaseAddress in memory allocation HOBs
from the temporary memory to PEI installed memory.
@@ -1249,6 +1386,37 @@ InitializeImageServices (
IN PEI_CORE_INSTANCE *OldCoreData
);
+/**
+ Loads and relocates a PE/COFF image in place.
+
+ @param Pe32Data The base address of the PE/COFF file that is to be loaded and relocated
+ @param ImageAddress The base address of the relocated PE/COFF image
+
+ @retval EFI_SUCCESS The file was loaded and relocated
+
+**/
+EFI_STATUS
+LoadAndRelocatePeCoffImageInPlace (
+ IN VOID *Pe32Data,
+ IN VOID *ImageAddress
+ );
+
+/**
+ Find the PE32 Data for an FFS file.
+
+ @param FileHandle Pointer to the FFS file header of the image.
+ @param Pe32Data Pointer to a (VOID *) PE32 Data pointer.
+
+ @retval EFI_SUCCESS Image is successfully loaded.
+ @retval EFI_NOT_FOUND Fail to locate PE32 Data.
+
+**/
+EFI_STATUS
+PeiGetPe32Data (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ OUT VOID **Pe32Data
+ );
+
/**
The wrapper function of PeiLoadImageLoadImage().
diff --git a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
index 4c2eac1384e8..ef88b3423376 100644
--- a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
+++ b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
@@ -952,6 +952,408 @@ PeiCheckAndSwitchStack (
}
}
+/**
+ Migrate a PEIM from Temporary RAM to permanent memory.
+
+ @param PeimFileHandle Pointer to the FFS file header of the image.
+ @param MigratedFileHandle Pointer to the FFS file header of the migrated image.
+
+ @retval EFI_SUCCESS Sucessfully migrated the PEIM to permanent memory.
+
+**/
+EFI_STATUS
+EFIAPI
+MigratePeim (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN EFI_PEI_FILE_HANDLE MigratedFileHandle
+ )
+{
+ EFI_STATUS Status;
+ EFI_FFS_FILE_HEADER *FileHeader;
+ VOID *Pe32Data;
+ VOID *ImageAddress;
+ CHAR8 *AsciiString;
+ UINTN Index;
+
+ Status = EFI_SUCCESS;
+
+ FileHeader = (EFI_FFS_FILE_HEADER *) FileHandle;
+ ASSERT (!IS_FFS_FILE2 (FileHeader));
+
+ ImageAddress = NULL;
+ PeiGetPe32Data (MigratedFileHandle, &ImageAddress);
+ if (ImageAddress != NULL) {
+ AsciiString = PeCoffLoaderGetPdbPointer (ImageAddress);
+ for (Index = 0; AsciiString[Index] != 0; Index++) {
+ if (AsciiString[Index] == '\\' || AsciiString[Index] == '/') {
+ AsciiString = AsciiString + Index + 1;
+ Index = 0;
+ } else if (AsciiString[Index] == '.') {
+ AsciiString[Index] = 0;
+ }
+ }
+ DEBUG ((DEBUG_INFO, "%a", AsciiString));
+
+ Pe32Data = (VOID *) ((UINTN) ImageAddress - (UINTN) MigratedFileHandle + (UINTN) FileHandle);
+ Status = LoadAndRelocatePeCoffImageInPlace (Pe32Data, ImageAddress);
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ return Status;
+}
+
+/**
+ Migrate Status Code Callback function pointers inside an FV from temporary memory to permanent memory.
+
+ @param OrgFvHandle Address of FV Handle in temporary memory.
+ @param FvHandle Address of FV Handle in permanent memory.
+ @param FvSize Size of the FV.
+
+**/
+VOID
+ConvertStatusCodeCallbacks (
+ IN UINTN OrgFvHandle,
+ IN UINTN FvHandle,
+ IN UINTN FvSize
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+ UINTN *NumberOfEntries;
+ UINTN *CallbackEntry;
+ UINTN Index;
+
+ Hob.Raw = GetFirstGuidHob (&gStatusCodeCallbackGuid);
+ while (Hob.Raw != NULL) {
+ NumberOfEntries = GET_GUID_HOB_DATA (Hob);
+ CallbackEntry = NumberOfEntries + 1;
+ for (Index = 0; Index < *NumberOfEntries; Index++) {
+ if (((VOID *) CallbackEntry[Index]) != NULL) {
+ if ((CallbackEntry[Index] >= OrgFvHandle) && (CallbackEntry[Index] < (OrgFvHandle + FvSize))) {
+ DEBUG ((DEBUG_INFO, "Migrating CallbackEntry[%d] from 0x%08X to ", Index, CallbackEntry[Index]));
+ if (OrgFvHandle > FvHandle) {
+ CallbackEntry[Index] = CallbackEntry[Index] - (OrgFvHandle - FvHandle);
+ } else {
+ CallbackEntry[Index] = CallbackEntry[Index] + (FvHandle - OrgFvHandle);
+ }
+ DEBUG ((DEBUG_INFO, "0x%08X\n", CallbackEntry[Index]));
+ }
+ }
+ }
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ Hob.Raw = GetNextGuidHob (&gStatusCodeCallbackGuid, Hob.Raw);
+ }
+}
+
+/**
+ Migrates SEC modules in the given firmware volume.
+
+ Migrating SECURITY_CORE files requires special treatment since they are not tracked for PEI dispatch.
+
+ This functioun should be called after the FV has been copied to its post-memory location and the PEI Core FV list has
+ been updated.
+
+ @param Private Pointer to the PeiCore's private data structure.
+ @param FvIndex The firmware volume index to migrate.
+ @param OrgFvHandle The handle to the firmware volume in temporary memory.
+
+ @retval EFI_SUCCESS SEC modules were migrated successfully
+ @retval EFI_INVALID_PARAMETER The Private pointer is NULL or FvCount is invalid.
+
+**/
+EFI_STATUS
+EFIAPI
+MigrateSecModulesInFv (
+ IN PEI_CORE_INSTANCE *Private,
+ IN UINTN FvIndex,
+ IN UINTN OrgFvHandle
+ )
+{
+ EFI_STATUS Status;
+ EFI_STATUS FindFileStatus;
+ EFI_PEI_FILE_HANDLE MigratedFileHandle;
+ EFI_PEI_FILE_HANDLE FileHandle;
+ UINT32 SectionAuthenticationStatus;
+ UINT32 FileSize;
+ VOID *OrgPe32SectionData;
+ VOID *Pe32SectionData;
+ EFI_FFS_FILE_HEADER *FfsFileHeader;
+ EFI_COMMON_SECTION_HEADER *Section;
+ BOOLEAN IsFfs3Fv;
+ UINTN SectionInstance;
+
+ if (Private == NULL || FvIndex >= Private->FvCount) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ do {
+ FindFileStatus = PeiFfsFindNextFile (
+ GetPeiServicesTablePointer (),
+ EFI_FV_FILETYPE_SECURITY_CORE,
+ Private->Fv[FvIndex].FvHandle,
+ &MigratedFileHandle
+ );
+ if (!EFI_ERROR (FindFileStatus ) && MigratedFileHandle != NULL) {
+ FileHandle = (EFI_PEI_FILE_HANDLE) ((UINTN) MigratedFileHandle - (UINTN) Private->Fv[FvIndex].FvHandle + OrgFvHandle);
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *) MigratedFileHandle;
+
+ DEBUG ((DEBUG_VERBOSE, " Migrating SEC_CORE MigratedFileHandle at 0x%x.\n", (UINTN) MigratedFileHandle));
+ DEBUG ((DEBUG_VERBOSE, " FileHandle at 0x%x.\n", (UINTN) FileHandle));
+
+ IsFfs3Fv = CompareGuid (&Private->Fv[FvIndex].FvHeader->FileSystemGuid, &gEfiFirmwareFileSystem3Guid);
+ if (IS_FFS_FILE2 (FfsFileHeader)) {
+ ASSERT (FFS_FILE2_SIZE (FfsFileHeader) > 0x00FFFFFF);
+ if (!IsFfs3Fv) {
+ DEBUG ((DEBUG_ERROR, "It is a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader->Name));
+ return EFI_NOT_FOUND;
+ }
+ Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER2));
+ FileSize = FFS_FILE2_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FILE_HEADER2);
+ } else {
+ Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER));
+ FileSize = FFS_FILE_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FILE_HEADER);
+ }
+
+ SectionInstance = 1;
+ SectionAuthenticationStatus = 0;
+ Status = ProcessSection (
+ GetPeiServicesTablePointer (),
+ EFI_SECTION_PE32,
+ &SectionInstance,
+ Section,
+ FileSize,
+ &Pe32SectionData,
+ &SectionAuthenticationStatus,
+ IsFfs3Fv
+ );
+
+ if (!EFI_ERROR (Status)) {
+ OrgPe32SectionData = (VOID *) ((UINTN) Pe32SectionData - (UINTN) MigratedFileHandle + (UINTN) FileHandle);
+ DEBUG ((DEBUG_VERBOSE, " PE32 section in migrated file at 0x%x.\n", (UINTN) Pe32SectionData));
+ DEBUG ((DEBUG_VERBOSE, " PE32 section in original file at 0x%x.\n", (UINTN) OrgPe32SectionData));
+ Status = LoadAndRelocatePeCoffImageInPlace (OrgPe32SectionData, Pe32SectionData);
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+ } while (!EFI_ERROR (FindFileStatus));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Migrates PEIMs in the given firmware volume.
+
+ @param Private Pointer to the PeiCore's private data structure.
+ @param FvIndex The firmware volume index to migrate.
+ @param OrgFvHandle The handle to the firmware volume in temporary memory.
+ @param FvHandle The handle to the firmware volume in permanent memory.
+
+ @retval EFI_SUCCESS The PEIMs in the FV were migrated successfully
+ @retval EFI_INVALID_PARAMETER The Private pointer is NULL or FvCount is invalid.
+
+**/
+EFI_STATUS
+EFIAPI
+MigratePeimsInFv (
+ IN PEI_CORE_INSTANCE *Private,
+ IN UINTN FvIndex,
+ IN UINTN OrgFvHandle,
+ IN UINTN FvHandle
+ )
+{
+ EFI_STATUS Status;
+ volatile UINTN FileIndex;
+ EFI_PEI_FILE_HANDLE MigratedFileHandle;
+ EFI_PEI_FILE_HANDLE FileHandle;
+
+ if (Private == NULL || FvIndex >= Private->FvCount) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Private->Fv[FvIndex].ScanFv) {
+ for (FileIndex = 0; FileIndex < Private->Fv[FvIndex].PeimCount; FileIndex++) {
+ if (Private->Fv[FvIndex].FvFileHandles[FileIndex] != NULL) {
+ FileHandle = Private->Fv[FvIndex].FvFileHandles[FileIndex];
+
+ MigratedFileHandle = (EFI_PEI_FILE_HANDLE) ((UINTN) FileHandle - OrgFvHandle + FvHandle);
+
+ DEBUG ((DEBUG_VERBOSE, " Migrating FileHandle %2d ", FileIndex));
+ Status = MigratePeim (FileHandle, MigratedFileHandle);
+ DEBUG ((DEBUG_INFO, "\n"));
+ ASSERT_EFI_ERROR (Status);
+
+ if (!EFI_ERROR (Status)) {
+ // if (Private->Fv[FvIndex].PeimState[FileIndex] == PEIM_STATE_REGISTER_FOR_SHADOW) {
+ // Private->Fv[FvIndex].PeimState[FileIndex]++;
+ // }
+ Private->Fv[FvIndex].FvFileHandles[FileIndex] = MigratedFileHandle;
+ if (FvIndex == Private->CurrentPeimFvCount) {
+ Private->CurrentFvFileHandles[FileIndex] = MigratedFileHandle;
+ }
+ }
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Migrate FVs out of temporary RAM before the cache is flushed.
+
+ @param Private PeiCore's private data structure
+ @param SecCoreData Points to a data structure containing information about the PEI core's operating
+ environment, such as the size and location of temporary RAM, the stack location and
+ the BFV location.
+
+ @retval EFI_SUCCESS Succesfully migrated installed FVs from temporary RAM to permanent memory.
+ @retval EFI_OUT_OF_RESOURCES Insufficient memory exists to allocate needed pages.
+
+**/
+EFI_STATUS
+EFIAPI
+EvacuateTempRam (
+ IN PEI_CORE_INSTANCE *Private,
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData
+ )
+{
+ EFI_STATUS Status;
+ volatile UINTN FvIndex;
+ volatile UINTN FvChildIndex;
+ UINTN ChildFvOffset;
+ EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
+ EFI_FIRMWARE_VOLUME_HEADER *ChildFvHeader;
+ EFI_FIRMWARE_VOLUME_HEADER *MigratedFvHeader;
+ EFI_FIRMWARE_VOLUME_HEADER *MigratedChildFvHeader;
+
+ PEI_CORE_FV_HANDLE PeiCoreFvHandle;
+ EFI_PEI_CORE_FV_LOCATION_PPI *PeiCoreFvLocationPpi;
+
+ ASSERT (Private->PeiMemoryInstalled);
+
+ DEBUG ((DEBUG_VERBOSE, "Beginning evacuation of content in temporary RAM.\n"));
+
+ //
+ // Migrate PPI Pointers of PEI_CORE from temporary memory to newly loaded PEI_CORE in permanent memory.
+ //
+ Status = PeiLocatePpi ((CONST EFI_PEI_SERVICES **) &Private->Ps, &gEfiPeiCoreFvLocationPpiGuid, 0, NULL, (VOID **) &PeiCoreFvLocationPpi);
+ if (!EFI_ERROR (Status) && (PeiCoreFvLocationPpi->PeiCoreFvLocation != NULL)) {
+ PeiCoreFvHandle.FvHandle = (EFI_PEI_FV_HANDLE) PeiCoreFvLocationPpi->PeiCoreFvLocation;
+ } else {
+ PeiCoreFvHandle.FvHandle = (EFI_PEI_FV_HANDLE) SecCoreData->BootFirmwareVolumeBase;
+ }
+ for (FvIndex = 0; FvIndex < Private->FvCount; FvIndex++) {
+ if (Private->Fv[FvIndex].FvHandle == PeiCoreFvHandle.FvHandle) {
+ PeiCoreFvHandle = Private->Fv[FvIndex];
+ break;
+ }
+ }
+ Status = EFI_SUCCESS;
+
+ ConvertPeiCorePpiPointers (Private, PeiCoreFvHandle);
+
+ for (FvIndex = 0; FvIndex < Private->FvCount; FvIndex++) {
+ FvHeader = Private->Fv[FvIndex].FvHeader;
+ ASSERT (FvHeader != NULL);
+ ASSERT (FvIndex < Private->FvCount);
+
+ DEBUG ((DEBUG_VERBOSE, "FV[%02d] at 0x%x.\n", FvIndex, (UINTN) FvHeader));
+ if (
+ !(
+ ((EFI_PHYSICAL_ADDRESS)(UINTN) FvHeader >= Private->PhysicalMemoryBegin) &&
+ (((EFI_PHYSICAL_ADDRESS)(UINTN) FvHeader + (FvHeader->FvLength - 1)) < Private->FreePhysicalMemoryTop)
+ )
+ ) {
+ Status = PeiServicesAllocatePages (
+ EfiBootServicesCode,
+ EFI_SIZE_TO_PAGES ((UINTN) FvHeader->FvLength),
+ (EFI_PHYSICAL_ADDRESS *) &MigratedFvHeader
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG ((
+ DEBUG_VERBOSE,
+ " Migrating FV[%d] from 0x%08X to 0x%08X\n",
+ FvIndex,
+ (UINTN) FvHeader,
+ (UINTN) MigratedFvHeader
+ ));
+
+ CopyMem (MigratedFvHeader, FvHeader, (UINTN) FvHeader->FvLength);
+
+ //
+ // Migrate any children for this FV now
+ //
+ for (FvChildIndex = FvIndex; FvChildIndex < Private->FvCount; FvChildIndex++) {
+ ChildFvHeader = Private->Fv[FvChildIndex].FvHeader;
+ if (
+ ((UINTN) ChildFvHeader > (UINTN) FvHeader) &&
+ (((UINTN) ChildFvHeader + ChildFvHeader->FvLength) < ((UINTN) FvHeader) + FvHeader->FvLength)
+ ) {
+ DEBUG ((DEBUG_VERBOSE, " Child FV[%02d] is being migrated.\n", FvChildIndex));
+ ChildFvOffset = (UINTN) ChildFvHeader - (UINTN) FvHeader;
+ DEBUG ((DEBUG_VERBOSE, " Child FV offset = 0x%x.\n", ChildFvOffset));
+ MigratedChildFvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) MigratedFvHeader + ChildFvOffset);
+ Private->Fv[FvChildIndex].FvHeader = MigratedChildFvHeader;
+ Private->Fv[FvChildIndex].FvHandle = (EFI_PEI_FV_HANDLE) MigratedChildFvHeader;
+ DEBUG ((DEBUG_VERBOSE, " Child migrated FV header at 0x%x.\n", (UINTN) MigratedChildFvHeader));
+
+ // @todo: find issue with file and section alignment in SEC PE32 images for migration
+ // (alignment in P32 is given as 32-bit when actual alignment is 16-bit)
+ // SEC PPIs are currently re-installed with a dedicated PEIM
+ // Status = MigrateSecModulesInFv (Private, FvChildIndex, (UINTN) ChildFvHeader);
+ // ASSERT_EFI_ERROR (Status);
+ Status = MigratePeimsInFv (Private, FvChildIndex, (UINTN) ChildFvHeader, (UINTN) MigratedChildFvHeader);
+ ASSERT_EFI_ERROR (Status);
+
+ ConvertPpiPointersFv (
+ Private,
+ (UINTN) ChildFvHeader,
+ (UINTN) MigratedChildFvHeader,
+ (UINTN) ChildFvHeader->FvLength - 1
+ );
+
+ ConvertStatusCodeCallbacks (
+ (UINTN) ChildFvHeader,
+ (UINTN) MigratedChildFvHeader,
+ (UINTN) ChildFvHeader->FvLength - 1
+ );
+
+ ConvertFvHob (Private, (UINTN) ChildFvHeader, (UINTN) MigratedChildFvHeader);
+ }
+ }
+ Private->Fv[FvIndex].FvHeader = MigratedFvHeader;
+ Private->Fv[FvIndex].FvHandle = (EFI_PEI_FV_HANDLE) MigratedFvHeader;
+
+ // @todo: find issue with file and section alignment in SEC PE32 images for migration
+ // (alignment in P32 is given as 32-bit when actual alignment is 16-bit)
+ // SEC PPIs are currently re-installed with a dedicated PEIM
+ // Status = MigrateSecModulesInFv (Private, FvIndex, (UINTN) FvHeader);
+ // ASSERT_EFI_ERROR (Status);
+ Status = MigratePeimsInFv (Private, FvIndex, (UINTN) FvHeader, (UINTN) MigratedFvHeader);
+ ASSERT_EFI_ERROR (Status);
+
+ ConvertPpiPointersFv (
+ Private,
+ (UINTN) FvHeader,
+ (UINTN) MigratedFvHeader,
+ (UINTN) FvHeader->FvLength - 1
+ );
+
+ ConvertStatusCodeCallbacks (
+ (UINTN) FvHeader,
+ (UINTN) MigratedFvHeader,
+ (UINTN) FvHeader->FvLength - 1
+ );
+
+ ConvertFvHob (Private, (UINTN) FvHeader, (UINTN) MigratedFvHeader);
+ }
+ }
+
+ RemoveFvHobsInTemporaryMemory (Private);
+
+ return Status;
+}
+
/**
Conduct PEIM dispatch.
diff --git a/MdeModulePkg/Core/Pei/Image/Image.c b/MdeModulePkg/Core/Pei/Image/Image.c
index e3ee3699337f..612797722a3e 100644
--- a/MdeModulePkg/Core/Pei/Image/Image.c
+++ b/MdeModulePkg/Core/Pei/Image/Image.c
@@ -444,6 +444,121 @@ LoadAndRelocatePeCoffImage (
return ReturnStatus;
}
+/**
+ Loads and relocates a PE/COFF image in place.
+
+ @param Pe32Data The base address of the PE/COFF file that is to be loaded and relocated
+ @param ImageAddress The base address of the relocated PE/COFF image
+
+ @retval EFI_SUCCESS The file was loaded and relocated
+
+**/
+EFI_STATUS
+LoadAndRelocatePeCoffImageInPlace (
+ IN VOID *Pe32Data,
+ IN VOID *ImageAddress
+ )
+{
+ EFI_STATUS Status;
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
+
+ ZeroMem (&ImageContext, sizeof (ImageContext));
+ ImageContext.Handle = Pe32Data;
+ ImageContext.ImageRead = PeiImageRead;
+
+ Status = PeCoffLoaderGetImageInfo (&ImageContext);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+
+ ImageContext.ImageAddress = (PHYSICAL_ADDRESS)(UINTN) ImageAddress;
+
+ //
+ // Load the image in place
+ //
+ Status = PeCoffLoaderLoadImage (&ImageContext);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+
+ //
+ // Relocate the image in place
+ //
+ Status = PeCoffLoaderRelocateImage (&ImageContext);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+
+ //
+ // Flush the instruction cache so the image data is written before we execute it
+ //
+ if (ImageContext.ImageAddress != (EFI_PHYSICAL_ADDRESS)(UINTN) Pe32Data) {
+ InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);
+ }
+
+ return Status;
+}
+
+/**
+ Find the PE32 Data for an FFS file.
+
+ @param FileHandle Pointer to the FFS file header of the image.
+ @param Pe32Data Pointer to a (VOID *) PE32 Data pointer.
+
+ @retval EFI_SUCCESS Image is successfully loaded.
+ @retval EFI_NOT_FOUND Fail to locate PE32 Data.
+
+**/
+EFI_STATUS
+PeiGetPe32Data (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ OUT VOID **Pe32Data
+ )
+{
+ EFI_STATUS Status;
+ EFI_SECTION_TYPE SearchType1;
+ EFI_SECTION_TYPE SearchType2;
+ UINT32 AuthenticationState;
+
+ *Pe32Data = NULL;
+
+ if (FeaturePcdGet (PcdPeiCoreImageLoaderSearchTeSectionFirst)) {
+ SearchType1 = EFI_SECTION_TE;
+ SearchType2 = EFI_SECTION_PE32;
+ } else {
+ SearchType1 = EFI_SECTION_PE32;
+ SearchType2 = EFI_SECTION_TE;
+ }
+
+ //
+ // Try to find a first exe section (if PcdPeiCoreImageLoaderSearchTeSectionFirst
+ // is true, TE will be searched first).
+ //
+ Status = PeiServicesFfsFindSectionData3 (
+ SearchType1,
+ 0,
+ FileHandle,
+ Pe32Data,
+ &AuthenticationState
+ );
+ //
+ // If we didn't find a first exe section, try to find the second exe section.
+ //
+ if (EFI_ERROR (Status)) {
+ Status = PeiServicesFfsFindSectionData3 (
+ SearchType2,
+ 0,
+ FileHandle,
+ Pe32Data,
+ &AuthenticationState
+ );
+ }
+ return Status;
+}
+
/**
Loads a PEIM into memory for subsequent execution. If there are compressed
images or images that need to be relocated into memory for performance reasons,
diff --git a/MdeModulePkg/Core/Pei/Memory/MemoryServices.c b/MdeModulePkg/Core/Pei/Memory/MemoryServices.c
index 6b3a64a811cd..9d933f0393a8 100644
--- a/MdeModulePkg/Core/Pei/Memory/MemoryServices.c
+++ b/MdeModulePkg/Core/Pei/Memory/MemoryServices.c
@@ -166,6 +166,88 @@ MigrateMemoryPages (
Private->FreePhysicalMemoryTop = NewMemPagesBase;
}
+/**
+ Removes any FV HOBs whose base address is not in PEI installed memory.
+
+ @param[in] Private Pointer to PeiCore's private data structure.
+
+**/
+VOID
+RemoveFvHobsInTemporaryMemory (
+ IN PEI_CORE_INSTANCE *Private
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+ EFI_HOB_FIRMWARE_VOLUME *FirmwareVolumeHob;
+
+ DEBUG ((DEBUG_INFO, "Removing FVs in FV HOB not already migrated to permanent memory.\n"));
+
+ for (Hob.Raw = GetHobList (); !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {
+ if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV || GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV2 || GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV3) {
+ FirmwareVolumeHob = Hob.FirmwareVolume;
+ DEBUG ((DEBUG_INFO, " Found FV HOB.\n"));
+ DEBUG ((
+ DEBUG_INFO,
+ " BA=%016lx L=%016lx\n",
+ FirmwareVolumeHob->BaseAddress,
+ FirmwareVolumeHob->Length
+ ));
+ if (
+ !(
+ ((EFI_PHYSICAL_ADDRESS) (UINTN) FirmwareVolumeHob->BaseAddress >= Private->PhysicalMemoryBegin) &&
+ (((EFI_PHYSICAL_ADDRESS) (UINTN) FirmwareVolumeHob->BaseAddress + (FirmwareVolumeHob->Length - 1)) < Private->FreePhysicalMemoryTop)
+ )
+ ) {
+ DEBUG ((DEBUG_INFO, " Removing FV HOB to an FV in T-RAM (was not migrated).\n"));
+ Hob.Header->HobType = EFI_HOB_TYPE_UNUSED;
+ }
+ }
+ }
+}
+
+/**
+ Migrate the base address in firmware volume allocation HOBs
+ from temporary memory to PEI installed memory.
+
+ @param[in] PrivateData Pointer to PeiCore's private data structure.
+ @param[in] OrgFvHandle Address of FV Handle in temporary memory.
+ @param[in] FvHandle Address of FV Handle in permanent memory.
+
+**/
+VOID
+ConvertFvHob (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ IN UINTN OrgFvHandle,
+ IN UINTN FvHandle
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+ EFI_HOB_FIRMWARE_VOLUME *FirmwareVolumeHob;
+ EFI_HOB_FIRMWARE_VOLUME2 *FirmwareVolume2Hob;
+ EFI_HOB_FIRMWARE_VOLUME3 *FirmwareVolume3Hob;
+
+ DEBUG ((DEBUG_INFO, "Converting FVs in FV HOB.\n"));
+
+ for (Hob.Raw = GetHobList (); !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {
+ if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV) {
+ FirmwareVolumeHob = Hob.FirmwareVolume;
+ if (FirmwareVolumeHob->BaseAddress == OrgFvHandle) {
+ FirmwareVolumeHob->BaseAddress = FvHandle;
+ }
+ } else if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV2) {
+ FirmwareVolume2Hob = Hob.FirmwareVolume2;
+ if (FirmwareVolume2Hob->BaseAddress == OrgFvHandle) {
+ FirmwareVolume2Hob->BaseAddress = FvHandle;
+ }
+ } else if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV3) {
+ FirmwareVolume3Hob = Hob.FirmwareVolume3;
+ if (FirmwareVolume3Hob->BaseAddress == OrgFvHandle) {
+ FirmwareVolume3Hob->BaseAddress = FvHandle;
+ }
+ }
+ }
+}
+
/**
Migrate MemoryBaseAddress in memory allocation HOBs
from the temporary memory to PEI installed memory.
diff --git a/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c b/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c
index cca57c4c0686..4a0671f87604 100644
--- a/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c
+++ b/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c
@@ -176,6 +176,9 @@ PeiCore (
EFI_HOB_HANDOFF_INFO_TABLE *HandoffInformationTable;
EFI_PEI_TEMPORARY_RAM_DONE_PPI *TemporaryRamDonePpi;
UINTN Index;
+ BOOLEAN Shadow;
+
+ Shadow = FALSE;
//
// Retrieve context passed into PEI Core
@@ -418,6 +421,27 @@ PeiCore (
ProcessPpiListFromSec ((CONST EFI_PEI_SERVICES **) &PrivateData.Ps, PpiList);
}
} else {
+ if (PcdGetBool (PcdMigrateTemporaryRamFirmwareVolumes)) {
+ if (PrivateData.HobList.HandoffInformationTable->BootMode == BOOT_ON_S3_RESUME) {
+ Shadow = PcdGetBool (PcdShadowPeimOnS3Boot);
+ } else {
+ Shadow = PcdGetBool (PcdShadowPeimOnBoot);
+ }
+ }
+
+ if (Shadow) {
+ DEBUG ((DEBUG_VERBOSE, "PPI lists before temporary RAM evacuation:\n"));
+ DumpPpiList (&PrivateData);
+
+ //
+ // Migrate installed content from Temporary RAM to Permanent RAM
+ //
+ EvacuateTempRam (&PrivateData, SecCoreData);
+
+ DEBUG ((DEBUG_VERBOSE, "PPI lists after temporary RAM evacuation:\n"));
+ DumpPpiList (&PrivateData);
+ }
+
//
// Try to locate Temporary RAM Done Ppi.
//
diff --git a/MdeModulePkg/Core/Pei/Ppi/Ppi.c b/MdeModulePkg/Core/Pei/Ppi/Ppi.c
index 1ffe718c4702..018b25f86470 100644
--- a/MdeModulePkg/Core/Pei/Ppi/Ppi.c
+++ b/MdeModulePkg/Core/Pei/Ppi/Ppi.c
@@ -198,6 +198,227 @@ ConvertPpiPointers (
}
}
+/**
+
+ Migrate Notify Pointers inside an FV from temporary memory to permanent memory.
+
+ @param PrivateData Pointer to PeiCore's private data structure.
+ @param OrgFvHandle Address of FV Handle in temporary memory.
+ @param FvHandle Address of FV Handle in permanent memory.
+ @param FvSize Size of the FV.
+
+**/
+VOID
+ConvertPpiPointersFv (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ IN UINTN OrgFvHandle,
+ IN UINTN FvHandle,
+ IN UINTN FvSize
+ )
+{
+ UINT8 Index;
+ UINTN Offset;
+ BOOLEAN OffsetPositive;
+ EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *FvInfoPpi;
+ UINT8 GuidIndex;
+ EFI_GUID *Guid;
+ EFI_GUID *GuidCheckList[2];
+
+ GuidCheckList[0] = &gEfiPeiFirmwareVolumeInfoPpiGuid;
+ GuidCheckList[1] = &gEfiPeiFirmwareVolumeInfo2PpiGuid;
+
+ if (FvHandle > OrgFvHandle) {
+ OffsetPositive = TRUE;
+ Offset = FvHandle - OrgFvHandle;
+ } else {
+ OffsetPositive = FALSE;
+ Offset = OrgFvHandle - FvHandle;
+ }
+
+ DEBUG ((DEBUG_VERBOSE, "Converting PPI pointers in FV.\n"));
+ DEBUG ((
+ DEBUG_VERBOSE,
+ " OrgFvHandle at 0x%08x. FvHandle at 0x%08x. FvSize = 0x%x\n",
+ (UINTN) OrgFvHandle,
+ (UINTN) FvHandle,
+ FvSize
+ ));
+ DEBUG ((
+ DEBUG_VERBOSE,
+ " OrgFvHandle range: 0x%08x - 0x%08x\n",
+ OrgFvHandle,
+ OrgFvHandle + FvSize
+ ));
+
+ for (Index = 0; Index < PrivateData->PpiData.CallbackNotifyList.CurrentCount; Index++) {
+ ConvertPointer (
+ (VOID **) &PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index].Raw,
+ OrgFvHandle,
+ OrgFvHandle + FvSize,
+ Offset,
+ OffsetPositive
+ );
+ ConvertPointer (
+ (VOID **) &PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index].Notify->Guid,
+ OrgFvHandle,
+ OrgFvHandle + FvSize,
+ Offset,
+ OffsetPositive
+ );
+ ConvertPointer (
+ (VOID **) &PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index].Notify->Notify,
+ OrgFvHandle,
+ OrgFvHandle + FvSize,
+ Offset,
+ OffsetPositive
+ );
+ }
+
+ for (Index = 0; Index < PrivateData->PpiData.DispatchNotifyList.CurrentCount; Index++) {
+ ConvertPointer (
+ (VOID **) &PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].Raw,
+ OrgFvHandle,
+ OrgFvHandle + FvSize,
+ Offset,
+ OffsetPositive
+ );
+ ConvertPointer (
+ (VOID **) &PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].Notify->Guid,
+ OrgFvHandle,
+ OrgFvHandle + FvSize,
+ Offset,
+ OffsetPositive
+ );
+ ConvertPointer (
+ (VOID **) &PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].Notify->Notify,
+ OrgFvHandle,
+ OrgFvHandle + FvSize,
+ Offset,
+ OffsetPositive
+ );
+ }
+
+ for (Index = 0; Index < PrivateData->PpiData.PpiList.CurrentCount; Index++) {
+ ConvertPointer (
+ (VOID **) &PrivateData->PpiData.PpiList.PpiPtrs[Index].Raw,
+ OrgFvHandle,
+ OrgFvHandle + FvSize,
+ Offset,
+ OffsetPositive
+ );
+ ConvertPointer (
+ (VOID **) &PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi->Guid,
+ OrgFvHandle,
+ OrgFvHandle + FvSize,
+ Offset,
+ OffsetPositive
+ );
+ ConvertPointer (
+ (VOID **) &PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi->Ppi,
+ OrgFvHandle,
+ OrgFvHandle + FvSize,
+ Offset,
+ OffsetPositive
+ );
+
+ Guid = PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi->Guid;
+ for (GuidIndex = 0; GuidIndex < ARRAY_SIZE (GuidCheckList); ++GuidIndex) {
+ //
+ // Don't use CompareGuid function here for performance reasons.
+ // Instead we compare the GUID as INT32 at a time and branch
+ // on the first failed comparison.
+ //
+ if ((((INT32 *)Guid)[0] == ((INT32 *)GuidCheckList[GuidIndex])[0]) &&
+ (((INT32 *)Guid)[1] == ((INT32 *)GuidCheckList[GuidIndex])[1]) &&
+ (((INT32 *)Guid)[2] == ((INT32 *)GuidCheckList[GuidIndex])[2]) &&
+ (((INT32 *)Guid)[3] == ((INT32 *)GuidCheckList[GuidIndex])[3])) {
+ FvInfoPpi = PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi->Ppi;
+ DEBUG ((DEBUG_VERBOSE, " FvInfo: %p -> ", FvInfoPpi->FvInfo));
+ if ((UINTN)FvInfoPpi->FvInfo == OrgFvHandle) {
+ ConvertPointer (
+ (VOID **)&FvInfoPpi->FvInfo,
+ OrgFvHandle,
+ OrgFvHandle + FvSize,
+ Offset,
+ OffsetPositive
+ );
+ DEBUG ((DEBUG_VERBOSE, "%p", FvInfoPpi->FvInfo));
+ }
+ DEBUG ((DEBUG_VERBOSE, "\n"));
+ break;
+ }
+ }
+ }
+}
+
+/**
+
+ Dumps the PPI lists to debug output.
+
+ @param PrivateData Points to PeiCore's private instance data.
+
+**/
+VOID
+DumpPpiList (
+ IN PEI_CORE_INSTANCE *PrivateData
+ )
+{
+ DEBUG_CODE_BEGIN ();
+ UINTN Index;
+
+ if (PrivateData == NULL) {
+ return;
+ }
+
+ for (Index = 0; Index < PrivateData->PpiData.CallbackNotifyList.CurrentCount; Index++) {
+ DEBUG ((
+ DEBUG_VERBOSE,
+ "CallbackNotify[%2d] {%g} at 0x%x (%a)\n",
+ Index,
+ PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index].Notify->Guid,
+ (UINTN) PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index].Raw,
+ (
+ !(
+ ((EFI_PHYSICAL_ADDRESS) (UINTN) PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index].Raw >= PrivateData->PhysicalMemoryBegin) &&
+ (((EFI_PHYSICAL_ADDRESS) ((UINTN) PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index].Raw) + sizeof (EFI_PEI_NOTIFY_DESCRIPTOR)) < PrivateData->FreePhysicalMemoryTop)
+ )
+ ? "CAR" : "Post-Memory"
+ )
+ ));
+ }
+ for (Index = 0; Index < PrivateData->PpiData.DispatchNotifyList.CurrentCount; Index++) {
+ DEBUG ((DEBUG_VERBOSE,
+ "DispatchNotify[%2d] {%g} at 0x%x (%a)\n",
+ Index,
+ PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].Notify->Guid,
+ (UINTN) PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].Raw,
+ (
+ !(
+ ((EFI_PHYSICAL_ADDRESS) (UINTN) PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].Raw >=PrivateData->PhysicalMemoryBegin) &&
+ (((EFI_PHYSICAL_ADDRESS) ((UINTN) PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].Raw) + sizeof (EFI_PEI_NOTIFY_DESCRIPTOR)) < PrivateData->FreePhysicalMemoryTop)
+ )
+ ? "CAR" : "Post-Memory"
+ )
+ ));
+ }
+ for (Index = 0; Index < PrivateData->PpiData.PpiList.CurrentCount; Index++) {
+ DEBUG ((DEBUG_VERBOSE,
+ "PPI[%2d] {%g} at 0x%x (%a)\n",
+ Index,
+ PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi->Guid,
+ (UINTN) PrivateData->PpiData.PpiList.PpiPtrs[Index].Raw,
+ (
+ !(
+ ((EFI_PHYSICAL_ADDRESS) (UINTN) PrivateData->PpiData.PpiList.PpiPtrs[Index].Raw >= PrivateData->PhysicalMemoryBegin) &&
+ (((EFI_PHYSICAL_ADDRESS) ((UINTN) PrivateData->PpiData.PpiList.PpiPtrs[Index].Raw) + sizeof (EFI_PEI_PPI_DESCRIPTOR)) < PrivateData->FreePhysicalMemoryTop)
+ )
+ ? "CAR" : "Post-Memory"
+ )
+ ));
+ }
+ DEBUG_CODE_END ();
+}
+
/**
This function installs an interface in the PEI PPI database by GUID.
@@ -830,3 +1051,69 @@ ProcessPpiListFromSec (
}
}
+/**
+
+ Migrate PPI Pointers of PEI_CORE from temporary memory to permanent memory.
+
+ @param PrivateData Pointer to PeiCore's private data structure.
+ @param CoreFvHandle Address of PEI_CORE FV Handle in temporary memory.
+
+**/
+
+VOID
+ConvertPeiCorePpiPointers (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ PEI_CORE_FV_HANDLE CoreFvHandle
+ )
+{
+ EFI_FV_FILE_INFO FileInfo;
+ EFI_PHYSICAL_ADDRESS OrgImageBase;
+ EFI_PHYSICAL_ADDRESS MigratedImageBase;
+ UINTN PeiCoreModuleSize;
+ EFI_PEI_FILE_HANDLE PeiCoreFileHandle;
+ VOID *PeiCoreImageBase;
+ VOID *PeiCoreEntryPoint;
+ EFI_STATUS Status;
+
+ PeiCoreFileHandle = NULL;
+
+ //
+ // Find the PEI Core in the BFV in temporary memory.
+ //
+ Status = CoreFvHandle.FvPpi->FindFileByType (
+ CoreFvHandle.FvPpi,
+ EFI_FV_FILETYPE_PEI_CORE,
+ CoreFvHandle.FvHandle,
+ &PeiCoreFileHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ if (!EFI_ERROR (Status)) {
+ Status = CoreFvHandle.FvPpi->GetFileInfo (CoreFvHandle.FvPpi, PeiCoreFileHandle, &FileInfo);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = PeiGetPe32Data (PeiCoreFileHandle, &PeiCoreImageBase);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Find PEI Core EntryPoint in the BFV in temporary memory.
+ //
+ Status = PeCoffLoaderGetEntryPoint ((VOID *) (UINTN) PeiCoreImageBase, &PeiCoreEntryPoint);
+ ASSERT_EFI_ERROR (Status);
+
+ OrgImageBase = (UINTN) PeiCoreImageBase;
+ MigratedImageBase = (UINTN) _ModuleEntryPoint - ((UINTN) PeiCoreEntryPoint - (UINTN) PeiCoreImageBase);
+
+ //
+ // Size of loaded PEI_CORE in permanent memory.
+ //
+ PeiCoreModuleSize = (UINTN)FileInfo.BufferSize - ((UINTN) OrgImageBase - (UINTN) FileInfo.Buffer);
+
+ //
+ // Migrate PEI_CORE PPI pointers from temporary memory to newly
+ // installed PEI_CORE in permanent memory.
+ //
+ ConvertPpiPointersFv (PrivateData, (UINTN) OrgImageBase, (UINTN) MigratedImageBase, PeiCoreModuleSize);
+ }
+}
+
--
2.25.1.windows.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [edk2-devel] [PATCH v5 2/9] MdeModulePkg/PeiCore: Enable T-RAM evacuation in PeiCore (CVE-2019-11098)
2020-07-09 1:56 ` [PATCH v5 2/9] MdeModulePkg/PeiCore: Enable T-RAM evacuation in PeiCore (CVE-2019-11098) Guomin Jiang
@ 2020-07-09 10:50 ` Laszlo Ersek
2020-07-13 6:38 ` Wang, Jian J
1 sibling, 0 replies; 24+ messages in thread
From: Laszlo Ersek @ 2020-07-09 10:50 UTC (permalink / raw)
To: devel, guomin.jiang
Cc: Michael Kubacki, Jian J Wang, Hao A Wu, Dandan Bi, Liming Gao,
Debkumar De, Harry Han, Catharine West
On 07/09/20 03:56, Guomin Jiang wrote:
> From: Michael Kubacki <michael.a.kubacki@intel.com>
>
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=1614
>
> Introduces new changes to PeiCore to move the contents of temporary
> RAM visible to the PeiCore to permanent memory. This expands on
> pre-existing shadowing support in the PeiCore to perform the following
> additional actions:
>
> 1. Migrate pointers in PPIs installed in PeiCore to the permanent
> memory copy of PeiCore.
>
> 2. Copy all installed firmware volumes to permanent memory.
>
> 3. Relocate and fix up the PEIMs within the firmware volumes.
>
> 4. Convert all PPIs into the migrated firmware volume to the corresponding
> PPI address in the permanent memory location.
>
> This applies to PPIs and PEI notifications.
>
> 5. Convert all status code callbacks in the migrated firmware volume to
> the corresponding address in the permanent memory location.
>
> 6. Update the FV HOB to the corresponding firmware volume in permanent
> memory.
>
> 7. Add PcdMigrateTemporaryRamFirmwareVolumes to control if enable the
> feature or not. when the PCD disable, the EvacuateTempRam() will
> never be called.
>
> The function control flow as below:
> PeiCore()
> DumpPpiList()
> EvacuateTempRam()
> ConvertPeiCorePpiPointers()
> ConvertPpiPointersFv()
> MigratePeimsInFv()
> MigratePeim()
> PeiGetPe32Data()
> LoadAndRelocatePeCoffImageInPlace()
> MigrateSecModulesInFv()
> ConvertPpiPointersFv()
> ConvertStatusCodeCallbacks()
> ConvertFvHob()
> RemoveFvHobsInTemporaryMemory()
> DumpPpiList()
>
> Cc: Jian J Wang <jian.j.wang@intel.com>
> Cc: Hao A Wu <hao.a.wu@intel.com>
> Cc: Dandan Bi <dandan.bi@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Debkumar De <debkumar.de@intel.com>
> Cc: Harry Han <harry.han@intel.com>
> Cc: Catharine West <catharine.west@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
> MdeModulePkg/Core/Pei/PeiMain.inf | 2 +
> MdeModulePkg/Core/Pei/PeiMain.h | 168 ++++++++
> MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c | 402 ++++++++++++++++++
> MdeModulePkg/Core/Pei/Image/Image.c | 115 +++++
> MdeModulePkg/Core/Pei/Memory/MemoryServices.c | 82 ++++
> MdeModulePkg/Core/Pei/PeiMain/PeiMain.c | 24 ++
> MdeModulePkg/Core/Pei/Ppi/Ppi.c | 287 +++++++++++++
> 7 files changed, 1080 insertions(+)
>
Acked-by: Laszlo Ersek <lersek@redhat.com>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [edk2-devel] [PATCH v5 2/9] MdeModulePkg/PeiCore: Enable T-RAM evacuation in PeiCore (CVE-2019-11098)
2020-07-09 1:56 ` [PATCH v5 2/9] MdeModulePkg/PeiCore: Enable T-RAM evacuation in PeiCore (CVE-2019-11098) Guomin Jiang
2020-07-09 10:50 ` [edk2-devel] " Laszlo Ersek
@ 2020-07-13 6:38 ` Wang, Jian J
2020-07-22 22:43 ` Laszlo Ersek
1 sibling, 1 reply; 24+ messages in thread
From: Wang, Jian J @ 2020-07-13 6:38 UTC (permalink / raw)
To: devel@edk2.groups.io, Jiang, Guomin
Cc: Michael Kubacki, Wu, Hao A, Bi, Dandan, Gao, Liming, De, Debkumar,
Han, Harry, West, Catharine
Guomin,
See my 16 comments embedded below.
About PcdMigrateTemporaryRamFirmwareVolumes, I think we need more
discussions on its use scenario along with PcdShadowPeimOnBoot and
PcdShadowPeimOnS3Boot. Currently it need all of them enabled to make
this solution work, which is a bit complex and confusion to me.
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Guomin
> Jiang
> Sent: Thursday, July 09, 2020 9:57 AM
> To: devel@edk2.groups.io
> Cc: Michael Kubacki <michael.a.kubacki@intel.com>; Wang, Jian J
> <jian.j.wang@intel.com>; Wu, Hao A <hao.a.wu@intel.com>; Bi, Dandan
> <dandan.bi@intel.com>; Gao, Liming <liming.gao@intel.com>; De, Debkumar
> <debkumar.de@intel.com>; Han, Harry <harry.han@intel.com>; West,
> Catharine <catharine.west@intel.com>
> Subject: [edk2-devel] [PATCH v5 2/9] MdeModulePkg/PeiCore: Enable T-RAM
> evacuation in PeiCore (CVE-2019-11098)
>
> From: Michael Kubacki <michael.a.kubacki@intel.com>
>
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=1614
>
> Introduces new changes to PeiCore to move the contents of temporary
> RAM visible to the PeiCore to permanent memory. This expands on
> pre-existing shadowing support in the PeiCore to perform the following
> additional actions:
>
> 1. Migrate pointers in PPIs installed in PeiCore to the permanent
> memory copy of PeiCore.
>
> 2. Copy all installed firmware volumes to permanent memory.
>
> 3. Relocate and fix up the PEIMs within the firmware volumes.
>
> 4. Convert all PPIs into the migrated firmware volume to the corresponding
> PPI address in the permanent memory location.
>
> This applies to PPIs and PEI notifications.
>
> 5. Convert all status code callbacks in the migrated firmware volume to
> the corresponding address in the permanent memory location.
>
> 6. Update the FV HOB to the corresponding firmware volume in permanent
> memory.
>
> 7. Add PcdMigrateTemporaryRamFirmwareVolumes to control if enable the
> feature or not. when the PCD disable, the EvacuateTempRam() will
> never be called.
>
> The function control flow as below:
> PeiCore()
> DumpPpiList()
> EvacuateTempRam()
> ConvertPeiCorePpiPointers()
> ConvertPpiPointersFv()
> MigratePeimsInFv()
> MigratePeim()
> PeiGetPe32Data()
> LoadAndRelocatePeCoffImageInPlace()
> MigrateSecModulesInFv()
> ConvertPpiPointersFv()
> ConvertStatusCodeCallbacks()
> ConvertFvHob()
> RemoveFvHobsInTemporaryMemory()
> DumpPpiList()
>
> Cc: Jian J Wang <jian.j.wang@intel.com>
> Cc: Hao A Wu <hao.a.wu@intel.com>
> Cc: Dandan Bi <dandan.bi@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Debkumar De <debkumar.de@intel.com>
> Cc: Harry Han <harry.han@intel.com>
> Cc: Catharine West <catharine.west@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
> MdeModulePkg/Core/Pei/PeiMain.inf | 2 +
> MdeModulePkg/Core/Pei/PeiMain.h | 168 ++++++++
> MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c | 402 ++++++++++++++++++
> MdeModulePkg/Core/Pei/Image/Image.c | 115 +++++
> MdeModulePkg/Core/Pei/Memory/MemoryServices.c | 82 ++++
> MdeModulePkg/Core/Pei/PeiMain/PeiMain.c | 24 ++
> MdeModulePkg/Core/Pei/Ppi/Ppi.c | 287 +++++++++++++
> 7 files changed, 1080 insertions(+)
>
> diff --git a/MdeModulePkg/Core/Pei/PeiMain.inf
> b/MdeModulePkg/Core/Pei/PeiMain.inf
> index 6e25cc40232a..5b36d516b3fa 100644
> --- a/MdeModulePkg/Core/Pei/PeiMain.inf
> +++ b/MdeModulePkg/Core/Pei/PeiMain.inf
> @@ -76,6 +76,7 @@ [Guids]
> ## CONSUMES ## UNDEFINED # Locate PPI
> ## CONSUMES ## GUID # Used to compare with FV's file system GUID and
> get the FV's file system format
> gEfiFirmwareFileSystem3Guid
> + gStatusCodeCallbackGuid
>
> [Ppis]
> gEfiPeiStatusCodePpiGuid ## SOMETIMES_CONSUMES #
> PeiReportStatusService is not ready if this PPI doesn't exist
> @@ -109,6 +110,7 @@ [Pcd]
> gEfiMdeModulePkgTokenSpaceGuid.PcdShadowPeimOnS3Boot ##
> CONSUMES
> gEfiMdeModulePkgTokenSpaceGuid.PcdShadowPeimOnBoot ##
> CONSUMES
> gEfiMdeModulePkgTokenSpaceGuid.PcdInitValueInTempStack ##
> CONSUMES
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdMigrateTemporaryRamFirmwareVolum
> es ## CONSUMES
>
> # [BootMode]
> # S3_RESUME ## SOMETIMES_CONSUMES
> diff --git a/MdeModulePkg/Core/Pei/PeiMain.h
> b/MdeModulePkg/Core/Pei/PeiMain.h
> index 56b3bd85793d..b0101dba5e30 100644
> --- a/MdeModulePkg/Core/Pei/PeiMain.h
> +++ b/MdeModulePkg/Core/Pei/PeiMain.h
> @@ -394,6 +394,41 @@ PeimDispatchReadiness (
> IN VOID *DependencyExpression
> );
>
> +/**
> + Migrate a PEIM from Temporary RAM to permanent memory.
1) 'Temporary' -> 'temporary'
> +
> + @param PeimFileHandle Pointer to the FFS file header of the image.
> + @param MigratedFileHandle Pointer to the FFS file header of the migrated
> image.
> +
> + @retval EFI_SUCCESS Sucessfully migrated the PEIM to permanent
> memory.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +MigratePeim (
> + IN EFI_PEI_FILE_HANDLE FileHandle,
> + IN EFI_PEI_FILE_HANDLE MigratedFileHandle
> + );
> +
> +/**
> + Migrate FVs out of Temporary RAM before the cache is flushed.
2) 'Temporary' -> 'temporary'
> +
> + @param Private PeiCore's private data structure
> + @param SecCoreData Points to a data structure containing information
> about the PEI core's operating
> + environment, such as the size and location of temporary RAM,
> the stack location and
> + the BFV location.
> +
> + @retval EFI_SUCCESS Succesfully migrated installed FVs from Temporary
> RAM to permanent memory.
3) 'Temporary' -> 'temporary'
> + @retval EFI_OUT_OF_RESOURCES Insufficient memory exists to allocate
> needed pages.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +EvacuateTempRam (
> + IN PEI_CORE_INSTANCE *Private,
> + IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData
> + );
> +
> /**
> Conduct PEIM dispatch.
>
> @@ -477,6 +512,50 @@ ConvertPpiPointers (
> IN PEI_CORE_INSTANCE *PrivateData
> );
>
> +/**
> +
> + Migrate Notify Pointers inside an FV from temporary memory to permanent
> memory.
> +
> + @param PrivateData Pointer to PeiCore's private data structure.
> + @param OrgFvHandle Address of FV Handle in temporary memory.
> + @param FvHandle Address of FV Handle in permanent memory.
> + @param FvSize Size of the FV.
> +
> +**/
> +VOID
> +ConvertPpiPointersFv (
> + IN PEI_CORE_INSTANCE *PrivateData,
> + IN UINTN OrgFvHandle,
> + IN UINTN FvHandle,
> + IN UINTN FvSize
> + );
> +
> +/**
> +
> + Migrate PPI Pointers of PEI_CORE from temporary memory to permanent
> memory.
> +
> + @param PrivateData Pointer to PeiCore's private data structure.
> + @param CoreFvHandle Address of PEI_CORE FV Handle in temporary
> memory.
> +
> +**/
> +VOID
> +ConvertPeiCorePpiPointers (
> + IN PEI_CORE_INSTANCE *PrivateData,
> + PEI_CORE_FV_HANDLE CoreFvHandle
> + );
> +
> +/**
> +
> + Dumps the PPI lists to debug output.
> +
> + @param PrivateData Points to PeiCore's private instance data.
> +
> +**/
> +VOID
> +DumpPpiList (
> + IN PEI_CORE_INSTANCE *PrivateData
> + );
> +
> /**
>
> Install PPI services. It is implementation of EFI_PEI_SERVICE.InstallPpi.
> @@ -808,6 +887,37 @@ PeiFfsFindNextFile (
> IN OUT EFI_PEI_FILE_HANDLE *FileHandle
> );
>
> +/**
> + Go through the file to search SectionType section.
> + Search within encapsulation sections (compression and GUIDed) recursively,
> + until the match section is found.
> +
> + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table
> published by the PEI Foundation.
> + @param SectionType Filter to find only section of this type.
> + @param SectionInstance Pointer to the filter to find the specific instance of
> section.
> + @param Section From where to search.
> + @param SectionSize The file size to search.
> + @param OutputBuffer A pointer to the discovered section, if successful.
> + NULL if section not found
4) Missing '.' at the end
> + @param AuthenticationStatus Updated upon return to point to the
> authentication status for this section.
5) Please align the start of parameter description
> + @param IsFfs3Fv Indicates the FV format.
> +
> + @return EFI_NOT_FOUND The match section is not found.
> + @return EFI_SUCCESS The match section is found.
> +
> +**/
> +EFI_STATUS
> +ProcessSection (
> + IN CONST EFI_PEI_SERVICES **PeiServices,
> + IN EFI_SECTION_TYPE SectionType,
> + IN OUT UINTN *SectionInstance,
> + IN EFI_COMMON_SECTION_HEADER *Section,
> + IN UINTN SectionSize,
> + OUT VOID **OutputBuffer,
> + OUT UINT32 *AuthenticationStatus,
> + IN BOOLEAN IsFfs3Fv
> + );
> +
> /**
> Searches for the next matching section within the specified file.
>
> @@ -931,6 +1041,33 @@ MigrateMemoryPages (
> IN BOOLEAN TemporaryRamMigrated
> );
>
> +/**
> + Removes any FV HOBs whose base address is not in PEI installed memory.
> +
> + @param[in] Private Pointer to PeiCore's private data structure.
> +
> +**/
> +VOID
> +RemoveFvHobsInTemporaryMemory (
> + IN PEI_CORE_INSTANCE *Private
> + );
> +
> +/**
> + Migrate the base address in firmware volume allocation HOBs
> + from temporary memory to PEI installed memory.
> +
> + @param[in] PrivateData Pointer to PeiCore's private data structure.
> + @param[in] OrgFvHandle Address of FV Handle in temporary memory.
> + @param[in] FvHandle Address of FV Handle in permanent memory.
> +
> +**/
> +VOID
> +ConvertFvHob (
> + IN PEI_CORE_INSTANCE *PrivateData,
> + IN UINTN OrgFvHandle,
> + IN UINTN FvHandle
> + );
> +
> /**
> Migrate MemoryBaseAddress in memory allocation HOBs
> from the temporary memory to PEI installed memory.
> @@ -1249,6 +1386,37 @@ InitializeImageServices (
> IN PEI_CORE_INSTANCE *OldCoreData
> );
>
> +/**
> + Loads and relocates a PE/COFF image in place.
> +
> + @param Pe32Data The base address of the PE/COFF file that is to be
> loaded and relocated
> + @param ImageAddress The base address of the relocated PE/COFF image
> +
> + @retval EFI_SUCCESS The file was loaded and relocated
> +
> +**/
> +EFI_STATUS
> +LoadAndRelocatePeCoffImageInPlace (
> + IN VOID *Pe32Data,
> + IN VOID *ImageAddress
> + );
> +
> +/**
> + Find the PE32 Data for an FFS file.
> +
> + @param FileHandle Pointer to the FFS file header of the image.
> + @param Pe32Data Pointer to a (VOID *) PE32 Data pointer.
> +
> + @retval EFI_SUCCESS Image is successfully loaded.
> + @retval EFI_NOT_FOUND Fail to locate PE32 Data.
> +
> +**/
> +EFI_STATUS
> +PeiGetPe32Data (
> + IN EFI_PEI_FILE_HANDLE FileHandle,
> + OUT VOID **Pe32Data
> + );
> +
> /**
> The wrapper function of PeiLoadImageLoadImage().
>
> diff --git a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
> b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
> index 4c2eac1384e8..ef88b3423376 100644
> --- a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
> +++ b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
> @@ -952,6 +952,408 @@ PeiCheckAndSwitchStack (
> }
> }
>
> +/**
> + Migrate a PEIM from Temporary RAM to permanent memory.
6) 'Temporary' -> 'temporary'
> +
> + @param PeimFileHandle Pointer to the FFS file header of the image.
> + @param MigratedFileHandle Pointer to the FFS file header of the migrated
> image.
> +
> + @retval EFI_SUCCESS Sucessfully migrated the PEIM to permanent
> memory.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +MigratePeim (
> + IN EFI_PEI_FILE_HANDLE FileHandle,
> + IN EFI_PEI_FILE_HANDLE MigratedFileHandle
> + )
> +{
> + EFI_STATUS Status;
> + EFI_FFS_FILE_HEADER *FileHeader;
> + VOID *Pe32Data;
> + VOID *ImageAddress;
> + CHAR8 *AsciiString;
> + UINTN Index;
> +
> + Status = EFI_SUCCESS;
> +
> + FileHeader = (EFI_FFS_FILE_HEADER *) FileHandle;
> + ASSERT (!IS_FFS_FILE2 (FileHeader));
> +
> + ImageAddress = NULL;
> + PeiGetPe32Data (MigratedFileHandle, &ImageAddress);
> + if (ImageAddress != NULL) {
> + AsciiString = PeCoffLoaderGetPdbPointer (ImageAddress);
> + for (Index = 0; AsciiString[Index] != 0; Index++) {
> + if (AsciiString[Index] == '\\' || AsciiString[Index] == '/') {
> + AsciiString = AsciiString + Index + 1;
> + Index = 0;
> + } else if (AsciiString[Index] == '.') {
> + AsciiString[Index] = 0;
> + }
> + }
> + DEBUG ((DEBUG_INFO, "%a", AsciiString));
7) Above code (from the line below 'if' to 'DEBUG') are used for
debug only. Suggest to put them into DEBUG_CODE();
> +
> + Pe32Data = (VOID *) ((UINTN) ImageAddress - (UINTN) MigratedFileHandle +
> (UINTN) FileHandle);
> + Status = LoadAndRelocatePeCoffImageInPlace (Pe32Data, ImageAddress);
> + ASSERT_EFI_ERROR (Status);
> + }
> +
> + return Status;
> +}
> +
> +/**
> + Migrate Status Code Callback function pointers inside an FV from temporary
> memory to permanent memory.
> +
> + @param OrgFvHandle Address of FV Handle in temporary memory.
8) 'Handle' -> 'handle'
> + @param FvHandle Address of FV Handle in permanent memory.
9) 'Handle' -> 'handle'
> + @param FvSize Size of the FV.
> +
> +**/
> +VOID
> +ConvertStatusCodeCallbacks (
> + IN UINTN OrgFvHandle,
> + IN UINTN FvHandle,
> + IN UINTN FvSize
> + )
> +{
> + EFI_PEI_HOB_POINTERS Hob;
> + UINTN *NumberOfEntries;
> + UINTN *CallbackEntry;
> + UINTN Index;
> +
> + Hob.Raw = GetFirstGuidHob (&gStatusCodeCallbackGuid);
> + while (Hob.Raw != NULL) {
> + NumberOfEntries = GET_GUID_HOB_DATA (Hob);
> + CallbackEntry = NumberOfEntries + 1;
> + for (Index = 0; Index < *NumberOfEntries; Index++) {
> + if (((VOID *) CallbackEntry[Index]) != NULL) {
> + if ((CallbackEntry[Index] >= OrgFvHandle) && (CallbackEntry[Index] <
> (OrgFvHandle + FvSize))) {
> + DEBUG ((DEBUG_INFO, "Migrating CallbackEntry[%d] from 0x%08X to ",
> Index, CallbackEntry[Index]));
CallbackEntry is defined as pointer to UINTN, which is 4-byte with 32-bit PEI.
Using %08X might be not a good idea. Suggest to use %p instead.
> + if (OrgFvHandle > FvHandle) {
> + CallbackEntry[Index] = CallbackEntry[Index] - (OrgFvHandle - FvHandle);
> + } else {
> + CallbackEntry[Index] = CallbackEntry[Index] + (FvHandle - OrgFvHandle);
> + }
> + DEBUG ((DEBUG_INFO, "0x%08X\n", CallbackEntry[Index]));
10) The same as above.
> + }
> + }
> + }
> + Hob.Raw = GET_NEXT_HOB (Hob);
> + Hob.Raw = GetNextGuidHob (&gStatusCodeCallbackGuid, Hob.Raw);
> + }
> +}
> +
> +/**
> + Migrates SEC modules in the given firmware volume.
> +
> + Migrating SECURITY_CORE files requires special treatment since they are not
> tracked for PEI dispatch.
> +
> + This functioun should be called after the FV has been copied to its post-
> memory location and the PEI Core FV list has
> + been updated.
> +
> + @param Private Pointer to the PeiCore's private data structure.
> + @param FvIndex The firmware volume index to migrate.
> + @param OrgFvHandle The handle to the firmware volume in temporary
> memory.
> +
> + @retval EFI_SUCCESS SEC modules were migrated successfully
> + @retval EFI_INVALID_PARAMETER The Private pointer is NULL or FvCount is
11) There's EFI_NOT_FOUND returned in the function body.
> invalid.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +MigrateSecModulesInFv (
> + IN PEI_CORE_INSTANCE *Private,
> + IN UINTN FvIndex,
> + IN UINTN OrgFvHandle
> + )
> +{
> + EFI_STATUS Status;
> + EFI_STATUS FindFileStatus;
> + EFI_PEI_FILE_HANDLE MigratedFileHandle;
> + EFI_PEI_FILE_HANDLE FileHandle;
> + UINT32 SectionAuthenticationStatus;
> + UINT32 FileSize;
> + VOID *OrgPe32SectionData;
> + VOID *Pe32SectionData;
> + EFI_FFS_FILE_HEADER *FfsFileHeader;
> + EFI_COMMON_SECTION_HEADER *Section;
> + BOOLEAN IsFfs3Fv;
> + UINTN SectionInstance;
> +
> + if (Private == NULL || FvIndex >= Private->FvCount) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + do {
> + FindFileStatus = PeiFfsFindNextFile (
> + GetPeiServicesTablePointer (),
> + EFI_FV_FILETYPE_SECURITY_CORE,
> + Private->Fv[FvIndex].FvHandle,
> + &MigratedFileHandle
> + );
> + if (!EFI_ERROR (FindFileStatus ) && MigratedFileHandle != NULL) {
> + FileHandle = (EFI_PEI_FILE_HANDLE) ((UINTN) MigratedFileHandle - (UINTN)
> Private->Fv[FvIndex].FvHandle + OrgFvHandle);
> + FfsFileHeader = (EFI_FFS_FILE_HEADER *) MigratedFileHandle;
> +
> + DEBUG ((DEBUG_VERBOSE, " Migrating SEC_CORE MigratedFileHandle at
> 0x%x.\n", (UINTN) MigratedFileHandle));
> + DEBUG ((DEBUG_VERBOSE, " FileHandle at 0x%x.\n", (UINTN)
> FileHandle));
> +
> + IsFfs3Fv = CompareGuid (&Private->Fv[FvIndex].FvHeader->FileSystemGuid,
> &gEfiFirmwareFileSystem3Guid);
> + if (IS_FFS_FILE2 (FfsFileHeader)) {
> + ASSERT (FFS_FILE2_SIZE (FfsFileHeader) > 0x00FFFFFF);
> + if (!IsFfs3Fv) {
> + DEBUG ((DEBUG_ERROR, "It is a FFS3 formatted file: %g in a non-FFS3
> formatted FV.\n", &FfsFileHeader->Name));
> + return EFI_NOT_FOUND;
> + }
> + Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) FfsFileHeader +
> sizeof (EFI_FFS_FILE_HEADER2));
> + FileSize = FFS_FILE2_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FILE_HEADER2);
> + } else {
> + Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) FfsFileHeader +
> sizeof (EFI_FFS_FILE_HEADER));
> + FileSize = FFS_FILE_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FILE_HEADER);
> + }
> +
> + SectionInstance = 1;
> + SectionAuthenticationStatus = 0;
> + Status = ProcessSection (
> + GetPeiServicesTablePointer (),
> + EFI_SECTION_PE32,
> + &SectionInstance,
> + Section,
> + FileSize,
> + &Pe32SectionData,
> + &SectionAuthenticationStatus,
> + IsFfs3Fv
> + );
> +
> + if (!EFI_ERROR (Status)) {
> + OrgPe32SectionData = (VOID *) ((UINTN) Pe32SectionData - (UINTN)
> MigratedFileHandle + (UINTN) FileHandle);
> + DEBUG ((DEBUG_VERBOSE, " PE32 section in migrated file at 0x%x.\n",
> (UINTN) Pe32SectionData));
> + DEBUG ((DEBUG_VERBOSE, " PE32 section in original file at 0x%x.\n",
> (UINTN) OrgPe32SectionData));
> + Status = LoadAndRelocatePeCoffImageInPlace (OrgPe32SectionData,
> Pe32SectionData);
> + ASSERT_EFI_ERROR (Status);
> + }
> + }
> + } while (!EFI_ERROR (FindFileStatus));
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Migrates PEIMs in the given firmware volume.
> +
> + @param Private Pointer to the PeiCore's private data structure.
> + @param FvIndex The firmware volume index to migrate.
> + @param OrgFvHandle The handle to the firmware volume in temporary
> memory.
> + @param FvHandle The handle to the firmware volume in permanent
> memory.
> +
> + @retval EFI_SUCCESS The PEIMs in the FV were migrated successfully
> + @retval EFI_INVALID_PARAMETER The Private pointer is NULL or FvCount is
> invalid.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +MigratePeimsInFv (
> + IN PEI_CORE_INSTANCE *Private,
> + IN UINTN FvIndex,
> + IN UINTN OrgFvHandle,
> + IN UINTN FvHandle
> + )
> +{
> + EFI_STATUS Status;
> + volatile UINTN FileIndex;
> + EFI_PEI_FILE_HANDLE MigratedFileHandle;
> + EFI_PEI_FILE_HANDLE FileHandle;
> +
> + if (Private == NULL || FvIndex >= Private->FvCount) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + if (Private->Fv[FvIndex].ScanFv) {
> + for (FileIndex = 0; FileIndex < Private->Fv[FvIndex].PeimCount; FileIndex++) {
> + if (Private->Fv[FvIndex].FvFileHandles[FileIndex] != NULL) {
> + FileHandle = Private->Fv[FvIndex].FvFileHandles[FileIndex];
> +
> + MigratedFileHandle = (EFI_PEI_FILE_HANDLE) ((UINTN) FileHandle -
> OrgFvHandle + FvHandle);
> +
> + DEBUG ((DEBUG_VERBOSE, " Migrating FileHandle %2d ", FileIndex));
> + Status = MigratePeim (FileHandle, MigratedFileHandle);
> + DEBUG ((DEBUG_INFO, "\n"));
DEBUG_VERBOSE is used line above but DEBUG_INFO here.
> + ASSERT_EFI_ERROR (Status);
> +
> + if (!EFI_ERROR (Status)) {
> + // if (Private->Fv[FvIndex].PeimState[FileIndex] ==
> PEIM_STATE_REGISTER_FOR_SHADOW) {
> + // Private->Fv[FvIndex].PeimState[FileIndex]++;
> + // }
12) Remove the code which have been commented out.
> + Private->Fv[FvIndex].FvFileHandles[FileIndex] = MigratedFileHandle;
> + if (FvIndex == Private->CurrentPeimFvCount) {
> + Private->CurrentFvFileHandles[FileIndex] = MigratedFileHandle;
> + }
> + }
> + }
> + }
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Migrate FVs out of temporary RAM before the cache is flushed.
> +
> + @param Private PeiCore's private data structure
> + @param SecCoreData Points to a data structure containing information
> about the PEI core's operating
> + environment, such as the size and location of temporary RAM,
> the stack location and
> + the BFV location.
> +
> + @retval EFI_SUCCESS Succesfully migrated installed FVs from temporary
> RAM to permanent memory.
> + @retval EFI_OUT_OF_RESOURCES Insufficient memory exists to allocate
> needed pages.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +EvacuateTempRam (
> + IN PEI_CORE_INSTANCE *Private,
> + IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData
> + )
> +{
> + EFI_STATUS Status;
> + volatile UINTN FvIndex;
> + volatile UINTN FvChildIndex;
> + UINTN ChildFvOffset;
> + EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
> + EFI_FIRMWARE_VOLUME_HEADER *ChildFvHeader;
> + EFI_FIRMWARE_VOLUME_HEADER *MigratedFvHeader;
> + EFI_FIRMWARE_VOLUME_HEADER *MigratedChildFvHeader;
> +
> + PEI_CORE_FV_HANDLE PeiCoreFvHandle;
> + EFI_PEI_CORE_FV_LOCATION_PPI *PeiCoreFvLocationPpi;
> +
> + ASSERT (Private->PeiMemoryInstalled);
> +
> + DEBUG ((DEBUG_VERBOSE, "Beginning evacuation of content in temporary
> RAM.\n"));
> +
> + //
> + // Migrate PPI Pointers of PEI_CORE from temporary memory to newly loaded
> PEI_CORE in permanent memory.
> + //
> + Status = PeiLocatePpi ((CONST EFI_PEI_SERVICES **) &Private->Ps,
> &gEfiPeiCoreFvLocationPpiGuid, 0, NULL, (VOID **) &PeiCoreFvLocationPpi);
> + if (!EFI_ERROR (Status) && (PeiCoreFvLocationPpi->PeiCoreFvLocation !=
> NULL)) {
> + PeiCoreFvHandle.FvHandle = (EFI_PEI_FV_HANDLE) PeiCoreFvLocationPpi-
> >PeiCoreFvLocation;
> + } else {
> + PeiCoreFvHandle.FvHandle = (EFI_PEI_FV_HANDLE) SecCoreData-
> >BootFirmwareVolumeBase;
> + }
> + for (FvIndex = 0; FvIndex < Private->FvCount; FvIndex++) {
> + if (Private->Fv[FvIndex].FvHandle == PeiCoreFvHandle.FvHandle) {
> + PeiCoreFvHandle = Private->Fv[FvIndex];
> + break;
> + }
> + }
> + Status = EFI_SUCCESS;
> +
> + ConvertPeiCorePpiPointers (Private, PeiCoreFvHandle);
> +
> + for (FvIndex = 0; FvIndex < Private->FvCount; FvIndex++) {
> + FvHeader = Private->Fv[FvIndex].FvHeader;
> + ASSERT (FvHeader != NULL);
> + ASSERT (FvIndex < Private->FvCount);
> +
> + DEBUG ((DEBUG_VERBOSE, "FV[%02d] at 0x%x.\n", FvIndex, (UINTN)
> FvHeader));
> + if (
> + !(
> + ((EFI_PHYSICAL_ADDRESS)(UINTN) FvHeader >= Private-
> >PhysicalMemoryBegin) &&
> + (((EFI_PHYSICAL_ADDRESS)(UINTN) FvHeader + (FvHeader->FvLength - 1))
> < Private->FreePhysicalMemoryTop)
> + )
> + ) {
> + Status = PeiServicesAllocatePages (
> + EfiBootServicesCode,
> + EFI_SIZE_TO_PAGES ((UINTN) FvHeader->FvLength),
> + (EFI_PHYSICAL_ADDRESS *) &MigratedFvHeader
> + );
> + ASSERT_EFI_ERROR (Status);
> +
> + DEBUG ((
> + DEBUG_VERBOSE,
> + " Migrating FV[%d] from 0x%08X to 0x%08X\n",
> + FvIndex,
> + (UINTN) FvHeader,
> + (UINTN) MigratedFvHeader
> + ));
> +
> + CopyMem (MigratedFvHeader, FvHeader, (UINTN) FvHeader->FvLength);
> +
> + //
> + // Migrate any children for this FV now
> + //
> + for (FvChildIndex = FvIndex; FvChildIndex < Private->FvCount;
> FvChildIndex++) {
> + ChildFvHeader = Private->Fv[FvChildIndex].FvHeader;
> + if (
> + ((UINTN) ChildFvHeader > (UINTN) FvHeader) &&
> + (((UINTN) ChildFvHeader + ChildFvHeader->FvLength) < ((UINTN)
> FvHeader) + FvHeader->FvLength)
> + ) {
> + DEBUG ((DEBUG_VERBOSE, " Child FV[%02d] is being migrated.\n",
> FvChildIndex));
> + ChildFvOffset = (UINTN) ChildFvHeader - (UINTN) FvHeader;
> + DEBUG ((DEBUG_VERBOSE, " Child FV offset = 0x%x.\n", ChildFvOffset));
> + MigratedChildFvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN)
> MigratedFvHeader + ChildFvOffset);
> + Private->Fv[FvChildIndex].FvHeader = MigratedChildFvHeader;
> + Private->Fv[FvChildIndex].FvHandle = (EFI_PEI_FV_HANDLE)
> MigratedChildFvHeader;
> + DEBUG ((DEBUG_VERBOSE, " Child migrated FV header at 0x%x.\n",
> (UINTN) MigratedChildFvHeader));
> +
> + // @todo: find issue with file and section alignment in SEC PE32 images
> for migration
> + // (alignment in P32 is given as 32-bit when actual alignment is 16-bit)
> + // SEC PPIs are currently re-installed with a dedicated PEIM
> + // Status = MigrateSecModulesInFv (Private, FvChildIndex, (UINTN)
> ChildFvHeader);
> + // ASSERT_EFI_ERROR (Status);
13) Remove the code which have been commented out.
> + Status = MigratePeimsInFv (Private, FvChildIndex, (UINTN) ChildFvHeader,
> (UINTN) MigratedChildFvHeader);
> + ASSERT_EFI_ERROR (Status);
> +
> + ConvertPpiPointersFv (
> + Private,
> + (UINTN) ChildFvHeader,
> + (UINTN) MigratedChildFvHeader,
> + (UINTN) ChildFvHeader->FvLength - 1
> + );
> +
> + ConvertStatusCodeCallbacks (
> + (UINTN) ChildFvHeader,
> + (UINTN) MigratedChildFvHeader,
> + (UINTN) ChildFvHeader->FvLength - 1
> + );
> +
> + ConvertFvHob (Private, (UINTN) ChildFvHeader, (UINTN)
> MigratedChildFvHeader);
> + }
> + }
> + Private->Fv[FvIndex].FvHeader = MigratedFvHeader;
> + Private->Fv[FvIndex].FvHandle = (EFI_PEI_FV_HANDLE) MigratedFvHeader;
> +
> + // @todo: find issue with file and section alignment in SEC PE32 images for
> migration
> + // (alignment in P32 is given as 32-bit when actual alignment is 16-bit)
> + // SEC PPIs are currently re-installed with a dedicated PEIM
> + // Status = MigrateSecModulesInFv (Private, FvIndex, (UINTN) FvHeader);
> + // ASSERT_EFI_ERROR (Status);
14) Remove the code which have been commented out.
> + Status = MigratePeimsInFv (Private, FvIndex, (UINTN) FvHeader, (UINTN)
> MigratedFvHeader);
> + ASSERT_EFI_ERROR (Status);
> +
> + ConvertPpiPointersFv (
> + Private,
> + (UINTN) FvHeader,
> + (UINTN) MigratedFvHeader,
> + (UINTN) FvHeader->FvLength - 1
> + );
> +
> + ConvertStatusCodeCallbacks (
> + (UINTN) FvHeader,
> + (UINTN) MigratedFvHeader,
> + (UINTN) FvHeader->FvLength - 1
> + );
> +
> + ConvertFvHob (Private, (UINTN) FvHeader, (UINTN) MigratedFvHeader);
> + }
> + }
> +
> + RemoveFvHobsInTemporaryMemory (Private);
> +
> + return Status;
> +}
> +
> /**
> Conduct PEIM dispatch.
>
> diff --git a/MdeModulePkg/Core/Pei/Image/Image.c
> b/MdeModulePkg/Core/Pei/Image/Image.c
> index e3ee3699337f..612797722a3e 100644
> --- a/MdeModulePkg/Core/Pei/Image/Image.c
> +++ b/MdeModulePkg/Core/Pei/Image/Image.c
> @@ -444,6 +444,121 @@ LoadAndRelocatePeCoffImage (
> return ReturnStatus;
> }
>
> +/**
> + Loads and relocates a PE/COFF image in place.
> +
> + @param Pe32Data The base address of the PE/COFF file that is to be
> loaded and relocated
> + @param ImageAddress The base address of the relocated PE/COFF image
> +
> + @retval EFI_SUCCESS The file was loaded and relocated
15) There're other return values from PeCoffLoaderLoadImage()
and PeCoffLoaderRelocateImage().
> +
> +**/
> +EFI_STATUS
> +LoadAndRelocatePeCoffImageInPlace (
> + IN VOID *Pe32Data,
> + IN VOID *ImageAddress
> + )
> +{
> + EFI_STATUS Status;
> + PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
> +
> + ZeroMem (&ImageContext, sizeof (ImageContext));
> + ImageContext.Handle = Pe32Data;
> + ImageContext.ImageRead = PeiImageRead;
> +
> + Status = PeCoffLoaderGetImageInfo (&ImageContext);
> + if (EFI_ERROR (Status)) {
> + ASSERT_EFI_ERROR (Status);
> + return Status;
> + }
> +
> + ImageContext.ImageAddress = (PHYSICAL_ADDRESS)(UINTN) ImageAddress;
> +
> + //
> + // Load the image in place
> + //
> + Status = PeCoffLoaderLoadImage (&ImageContext);
> + if (EFI_ERROR (Status)) {
> + ASSERT_EFI_ERROR (Status);
> + return Status;
> + }
> +
> + //
> + // Relocate the image in place
> + //
> + Status = PeCoffLoaderRelocateImage (&ImageContext);
> + if (EFI_ERROR (Status)) {
> + ASSERT_EFI_ERROR (Status);
> + return Status;
> + }
> +
> + //
> + // Flush the instruction cache so the image data is written before we execute
> it
> + //
> + if (ImageContext.ImageAddress != (EFI_PHYSICAL_ADDRESS)(UINTN)
> Pe32Data) {
> + InvalidateInstructionCacheRange ((VOID
> *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);
> + }
> +
> + return Status;
> +}
> +
> +/**
> + Find the PE32 Data for an FFS file.
> +
> + @param FileHandle Pointer to the FFS file header of the image.
> + @param Pe32Data Pointer to a (VOID *) PE32 Data pointer.
> +
> + @retval EFI_SUCCESS Image is successfully loaded.
> + @retval EFI_NOT_FOUND Fail to locate PE32 Data.
> +
> +**/
> +EFI_STATUS
> +PeiGetPe32Data (
> + IN EFI_PEI_FILE_HANDLE FileHandle,
> + OUT VOID **Pe32Data
> + )
> +{
> + EFI_STATUS Status;
> + EFI_SECTION_TYPE SearchType1;
> + EFI_SECTION_TYPE SearchType2;
> + UINT32 AuthenticationState;
> +
> + *Pe32Data = NULL;
> +
> + if (FeaturePcdGet (PcdPeiCoreImageLoaderSearchTeSectionFirst)) {
> + SearchType1 = EFI_SECTION_TE;
> + SearchType2 = EFI_SECTION_PE32;
> + } else {
> + SearchType1 = EFI_SECTION_PE32;
> + SearchType2 = EFI_SECTION_TE;
> + }
> +
> + //
> + // Try to find a first exe section (if
> PcdPeiCoreImageLoaderSearchTeSectionFirst
> + // is true, TE will be searched first).
> + //
> + Status = PeiServicesFfsFindSectionData3 (
> + SearchType1,
> + 0,
> + FileHandle,
> + Pe32Data,
> + &AuthenticationState
> + );
> + //
> + // If we didn't find a first exe section, try to find the second exe section.
> + //
> + if (EFI_ERROR (Status)) {
> + Status = PeiServicesFfsFindSectionData3 (
> + SearchType2,
> + 0,
> + FileHandle,
> + Pe32Data,
> + &AuthenticationState
> + );
> + }
> + return Status;
> +}
> +
> /**
> Loads a PEIM into memory for subsequent execution. If there are compressed
> images or images that need to be relocated into memory for performance
> reasons,
> diff --git a/MdeModulePkg/Core/Pei/Memory/MemoryServices.c
> b/MdeModulePkg/Core/Pei/Memory/MemoryServices.c
> index 6b3a64a811cd..9d933f0393a8 100644
> --- a/MdeModulePkg/Core/Pei/Memory/MemoryServices.c
> +++ b/MdeModulePkg/Core/Pei/Memory/MemoryServices.c
> @@ -166,6 +166,88 @@ MigrateMemoryPages (
> Private->FreePhysicalMemoryTop = NewMemPagesBase;
> }
>
> +/**
> + Removes any FV HOBs whose base address is not in PEI installed memory.
> +
> + @param[in] Private Pointer to PeiCore's private data structure.
> +
> +**/
> +VOID
> +RemoveFvHobsInTemporaryMemory (
> + IN PEI_CORE_INSTANCE *Private
> + )
> +{
> + EFI_PEI_HOB_POINTERS Hob;
> + EFI_HOB_FIRMWARE_VOLUME *FirmwareVolumeHob;
> +
> + DEBUG ((DEBUG_INFO, "Removing FVs in FV HOB not already migrated to
> permanent memory.\n"));
> +
> + for (Hob.Raw = GetHobList (); !END_OF_HOB_LIST (Hob); Hob.Raw =
> GET_NEXT_HOB (Hob)) {
> + if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV || GET_HOB_TYPE (Hob) ==
> EFI_HOB_TYPE_FV2 || GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV3) {
> + FirmwareVolumeHob = Hob.FirmwareVolume;
> + DEBUG ((DEBUG_INFO, " Found FV HOB.\n"));
> + DEBUG ((
> + DEBUG_INFO,
> + " BA=%016lx L=%016lx\n",
> + FirmwareVolumeHob->BaseAddress,
> + FirmwareVolumeHob->Length
> + ));
> + if (
> + !(
> + ((EFI_PHYSICAL_ADDRESS) (UINTN) FirmwareVolumeHob-
> >BaseAddress >= Private->PhysicalMemoryBegin) &&
> + (((EFI_PHYSICAL_ADDRESS) (UINTN) FirmwareVolumeHob->BaseAddress
> + (FirmwareVolumeHob->Length - 1)) < Private->FreePhysicalMemoryTop)
> + )
> + ) {
> + DEBUG ((DEBUG_INFO, " Removing FV HOB to an FV in T-RAM (was not
> migrated).\n"));
> + Hob.Header->HobType = EFI_HOB_TYPE_UNUSED;
> + }
> + }
> + }
> +}
> +
> +/**
> + Migrate the base address in firmware volume allocation HOBs
> + from temporary memory to PEI installed memory.
> +
> + @param[in] PrivateData Pointer to PeiCore's private data structure.
> + @param[in] OrgFvHandle Address of FV Handle in temporary memory.
> + @param[in] FvHandle Address of FV Handle in permanent memory.
> +
> +**/
> +VOID
> +ConvertFvHob (
> + IN PEI_CORE_INSTANCE *PrivateData,
> + IN UINTN OrgFvHandle,
> + IN UINTN FvHandle
> + )
> +{
> + EFI_PEI_HOB_POINTERS Hob;
> + EFI_HOB_FIRMWARE_VOLUME *FirmwareVolumeHob;
> + EFI_HOB_FIRMWARE_VOLUME2 *FirmwareVolume2Hob;
> + EFI_HOB_FIRMWARE_VOLUME3 *FirmwareVolume3Hob;
> +
> + DEBUG ((DEBUG_INFO, "Converting FVs in FV HOB.\n"));
> +
> + for (Hob.Raw = GetHobList (); !END_OF_HOB_LIST (Hob); Hob.Raw =
> GET_NEXT_HOB (Hob)) {
> + if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV) {
> + FirmwareVolumeHob = Hob.FirmwareVolume;
> + if (FirmwareVolumeHob->BaseAddress == OrgFvHandle) {
> + FirmwareVolumeHob->BaseAddress = FvHandle;
> + }
> + } else if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV2) {
> + FirmwareVolume2Hob = Hob.FirmwareVolume2;
> + if (FirmwareVolume2Hob->BaseAddress == OrgFvHandle) {
> + FirmwareVolume2Hob->BaseAddress = FvHandle;
> + }
> + } else if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV3) {
> + FirmwareVolume3Hob = Hob.FirmwareVolume3;
> + if (FirmwareVolume3Hob->BaseAddress == OrgFvHandle) {
> + FirmwareVolume3Hob->BaseAddress = FvHandle;
> + }
> + }
> + }
> +}
> +
> /**
> Migrate MemoryBaseAddress in memory allocation HOBs
> from the temporary memory to PEI installed memory.
> diff --git a/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c
> b/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c
> index cca57c4c0686..4a0671f87604 100644
> --- a/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c
> +++ b/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c
> @@ -176,6 +176,9 @@ PeiCore (
> EFI_HOB_HANDOFF_INFO_TABLE *HandoffInformationTable;
> EFI_PEI_TEMPORARY_RAM_DONE_PPI *TemporaryRamDonePpi;
> UINTN Index;
> + BOOLEAN Shadow;
16) Suggest to use different name other than Shadow. It's mainly for migrate
temporary ram, not exactly the same as PcdShadowPeimOnBoot.
Regards,
Jian
> +
> + Shadow = FALSE;
>
> //
> // Retrieve context passed into PEI Core
> @@ -418,6 +421,27 @@ PeiCore (
> ProcessPpiListFromSec ((CONST EFI_PEI_SERVICES **) &PrivateData.Ps,
> PpiList);
> }
> } else {
> + if (PcdGetBool (PcdMigrateTemporaryRamFirmwareVolumes)) {
> + if (PrivateData.HobList.HandoffInformationTable->BootMode ==
> BOOT_ON_S3_RESUME) {
> + Shadow = PcdGetBool (PcdShadowPeimOnS3Boot);
> + } else {
> + Shadow = PcdGetBool (PcdShadowPeimOnBoot);
> + }
> + }
> +
> + if (Shadow) {
> + DEBUG ((DEBUG_VERBOSE, "PPI lists before temporary RAM
> evacuation:\n"));
> + DumpPpiList (&PrivateData);
> +
> + //
> + // Migrate installed content from Temporary RAM to Permanent RAM
> + //
> + EvacuateTempRam (&PrivateData, SecCoreData);
> +
> + DEBUG ((DEBUG_VERBOSE, "PPI lists after temporary RAM evacuation:\n"));
> + DumpPpiList (&PrivateData);
> + }
> +
> //
> // Try to locate Temporary RAM Done Ppi.
> //
> diff --git a/MdeModulePkg/Core/Pei/Ppi/Ppi.c
> b/MdeModulePkg/Core/Pei/Ppi/Ppi.c
> index 1ffe718c4702..018b25f86470 100644
> --- a/MdeModulePkg/Core/Pei/Ppi/Ppi.c
> +++ b/MdeModulePkg/Core/Pei/Ppi/Ppi.c
> @@ -198,6 +198,227 @@ ConvertPpiPointers (
> }
> }
>
> +/**
> +
> + Migrate Notify Pointers inside an FV from temporary memory to permanent
> memory.
> +
> + @param PrivateData Pointer to PeiCore's private data structure.
> + @param OrgFvHandle Address of FV Handle in temporary memory.
> + @param FvHandle Address of FV Handle in permanent memory.
> + @param FvSize Size of the FV.
> +
> +**/
> +VOID
> +ConvertPpiPointersFv (
> + IN PEI_CORE_INSTANCE *PrivateData,
> + IN UINTN OrgFvHandle,
> + IN UINTN FvHandle,
> + IN UINTN FvSize
> + )
> +{
> + UINT8 Index;
> + UINTN Offset;
> + BOOLEAN OffsetPositive;
> + EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *FvInfoPpi;
> + UINT8 GuidIndex;
> + EFI_GUID *Guid;
> + EFI_GUID *GuidCheckList[2];
> +
> + GuidCheckList[0] = &gEfiPeiFirmwareVolumeInfoPpiGuid;
> + GuidCheckList[1] = &gEfiPeiFirmwareVolumeInfo2PpiGuid;
> +
> + if (FvHandle > OrgFvHandle) {
> + OffsetPositive = TRUE;
> + Offset = FvHandle - OrgFvHandle;
> + } else {
> + OffsetPositive = FALSE;
> + Offset = OrgFvHandle - FvHandle;
> + }
> +
> + DEBUG ((DEBUG_VERBOSE, "Converting PPI pointers in FV.\n"));
> + DEBUG ((
> + DEBUG_VERBOSE,
> + " OrgFvHandle at 0x%08x. FvHandle at 0x%08x. FvSize = 0x%x\n",
> + (UINTN) OrgFvHandle,
> + (UINTN) FvHandle,
> + FvSize
> + ));
> + DEBUG ((
> + DEBUG_VERBOSE,
> + " OrgFvHandle range: 0x%08x - 0x%08x\n",
> + OrgFvHandle,
> + OrgFvHandle + FvSize
> + ));
> +
> + for (Index = 0; Index < PrivateData->PpiData.CallbackNotifyList.CurrentCount;
> Index++) {
> + ConvertPointer (
> + (VOID **) &PrivateData-
> >PpiData.CallbackNotifyList.NotifyPtrs[Index].Raw,
> + OrgFvHandle,
> + OrgFvHandle + FvSize,
> + Offset,
> + OffsetPositive
> + );
> + ConvertPointer (
> + (VOID **) &PrivateData-
> >PpiData.CallbackNotifyList.NotifyPtrs[Index].Notify->Guid,
> + OrgFvHandle,
> + OrgFvHandle + FvSize,
> + Offset,
> + OffsetPositive
> + );
> + ConvertPointer (
> + (VOID **) &PrivateData-
> >PpiData.CallbackNotifyList.NotifyPtrs[Index].Notify->Notify,
> + OrgFvHandle,
> + OrgFvHandle + FvSize,
> + Offset,
> + OffsetPositive
> + );
> + }
> +
> + for (Index = 0; Index < PrivateData->PpiData.DispatchNotifyList.CurrentCount;
> Index++) {
> + ConvertPointer (
> + (VOID **) &PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].Raw,
> + OrgFvHandle,
> + OrgFvHandle + FvSize,
> + Offset,
> + OffsetPositive
> + );
> + ConvertPointer (
> + (VOID **) &PrivateData-
> >PpiData.DispatchNotifyList.NotifyPtrs[Index].Notify->Guid,
> + OrgFvHandle,
> + OrgFvHandle + FvSize,
> + Offset,
> + OffsetPositive
> + );
> + ConvertPointer (
> + (VOID **) &PrivateData-
> >PpiData.DispatchNotifyList.NotifyPtrs[Index].Notify->Notify,
> + OrgFvHandle,
> + OrgFvHandle + FvSize,
> + Offset,
> + OffsetPositive
> + );
> + }
> +
> + for (Index = 0; Index < PrivateData->PpiData.PpiList.CurrentCount; Index++) {
> + ConvertPointer (
> + (VOID **) &PrivateData->PpiData.PpiList.PpiPtrs[Index].Raw,
> + OrgFvHandle,
> + OrgFvHandle + FvSize,
> + Offset,
> + OffsetPositive
> + );
> + ConvertPointer (
> + (VOID **) &PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi->Guid,
> + OrgFvHandle,
> + OrgFvHandle + FvSize,
> + Offset,
> + OffsetPositive
> + );
> + ConvertPointer (
> + (VOID **) &PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi->Ppi,
> + OrgFvHandle,
> + OrgFvHandle + FvSize,
> + Offset,
> + OffsetPositive
> + );
> +
> + Guid = PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi->Guid;
> + for (GuidIndex = 0; GuidIndex < ARRAY_SIZE (GuidCheckList); ++GuidIndex) {
> + //
> + // Don't use CompareGuid function here for performance reasons.
> + // Instead we compare the GUID as INT32 at a time and branch
> + // on the first failed comparison.
> + //
> + if ((((INT32 *)Guid)[0] == ((INT32 *)GuidCheckList[GuidIndex])[0]) &&
> + (((INT32 *)Guid)[1] == ((INT32 *)GuidCheckList[GuidIndex])[1]) &&
> + (((INT32 *)Guid)[2] == ((INT32 *)GuidCheckList[GuidIndex])[2]) &&
> + (((INT32 *)Guid)[3] == ((INT32 *)GuidCheckList[GuidIndex])[3])) {
> + FvInfoPpi = PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi->Ppi;
> + DEBUG ((DEBUG_VERBOSE, " FvInfo: %p -> ", FvInfoPpi->FvInfo));
> + if ((UINTN)FvInfoPpi->FvInfo == OrgFvHandle) {
> + ConvertPointer (
> + (VOID **)&FvInfoPpi->FvInfo,
> + OrgFvHandle,
> + OrgFvHandle + FvSize,
> + Offset,
> + OffsetPositive
> + );
> + DEBUG ((DEBUG_VERBOSE, "%p", FvInfoPpi->FvInfo));
> + }
> + DEBUG ((DEBUG_VERBOSE, "\n"));
> + break;
> + }
> + }
> + }
> +}
> +
> +/**
> +
> + Dumps the PPI lists to debug output.
> +
> + @param PrivateData Points to PeiCore's private instance data.
> +
> +**/
> +VOID
> +DumpPpiList (
> + IN PEI_CORE_INSTANCE *PrivateData
> + )
> +{
> + DEBUG_CODE_BEGIN ();
> + UINTN Index;
> +
> + if (PrivateData == NULL) {
> + return;
> + }
> +
> + for (Index = 0; Index < PrivateData->PpiData.CallbackNotifyList.CurrentCount;
> Index++) {
> + DEBUG ((
> + DEBUG_VERBOSE,
> + "CallbackNotify[%2d] {%g} at 0x%x (%a)\n",
> + Index,
> + PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index].Notify->Guid,
> + (UINTN) PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index].Raw,
> + (
> + !(
> + ((EFI_PHYSICAL_ADDRESS) (UINTN) PrivateData-
> >PpiData.CallbackNotifyList.NotifyPtrs[Index].Raw >= PrivateData-
> >PhysicalMemoryBegin) &&
> + (((EFI_PHYSICAL_ADDRESS) ((UINTN) PrivateData-
> >PpiData.CallbackNotifyList.NotifyPtrs[Index].Raw) + sizeof
> (EFI_PEI_NOTIFY_DESCRIPTOR)) < PrivateData->FreePhysicalMemoryTop)
> + )
> + ? "CAR" : "Post-Memory"
> + )
> + ));
> + }
> + for (Index = 0; Index < PrivateData->PpiData.DispatchNotifyList.CurrentCount;
> Index++) {
> + DEBUG ((DEBUG_VERBOSE,
> + "DispatchNotify[%2d] {%g} at 0x%x (%a)\n",
> + Index,
> + PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].Notify->Guid,
> + (UINTN) PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].Raw,
> + (
> + !(
> + ((EFI_PHYSICAL_ADDRESS) (UINTN) PrivateData-
> >PpiData.DispatchNotifyList.NotifyPtrs[Index].Raw >=PrivateData-
> >PhysicalMemoryBegin) &&
> + (((EFI_PHYSICAL_ADDRESS) ((UINTN) PrivateData-
> >PpiData.DispatchNotifyList.NotifyPtrs[Index].Raw) + sizeof
> (EFI_PEI_NOTIFY_DESCRIPTOR)) < PrivateData->FreePhysicalMemoryTop)
> + )
> + ? "CAR" : "Post-Memory"
> + )
> + ));
> + }
> + for (Index = 0; Index < PrivateData->PpiData.PpiList.CurrentCount; Index++) {
> + DEBUG ((DEBUG_VERBOSE,
> + "PPI[%2d] {%g} at 0x%x (%a)\n",
> + Index,
> + PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi->Guid,
> + (UINTN) PrivateData->PpiData.PpiList.PpiPtrs[Index].Raw,
> + (
> + !(
> + ((EFI_PHYSICAL_ADDRESS) (UINTN) PrivateData-
> >PpiData.PpiList.PpiPtrs[Index].Raw >= PrivateData->PhysicalMemoryBegin) &&
> + (((EFI_PHYSICAL_ADDRESS) ((UINTN) PrivateData-
> >PpiData.PpiList.PpiPtrs[Index].Raw) + sizeof (EFI_PEI_PPI_DESCRIPTOR)) <
> PrivateData->FreePhysicalMemoryTop)
> + )
> + ? "CAR" : "Post-Memory"
> + )
> + ));
> + }
> + DEBUG_CODE_END ();
> +}
> +
> /**
>
> This function installs an interface in the PEI PPI database by GUID.
> @@ -830,3 +1051,69 @@ ProcessPpiListFromSec (
> }
> }
>
> +/**
> +
> + Migrate PPI Pointers of PEI_CORE from temporary memory to permanent
> memory.
> +
> + @param PrivateData Pointer to PeiCore's private data structure.
> + @param CoreFvHandle Address of PEI_CORE FV Handle in temporary
> memory.
> +
> +**/
> +
> +VOID
> +ConvertPeiCorePpiPointers (
> + IN PEI_CORE_INSTANCE *PrivateData,
> + PEI_CORE_FV_HANDLE CoreFvHandle
> + )
> +{
> + EFI_FV_FILE_INFO FileInfo;
> + EFI_PHYSICAL_ADDRESS OrgImageBase;
> + EFI_PHYSICAL_ADDRESS MigratedImageBase;
> + UINTN PeiCoreModuleSize;
> + EFI_PEI_FILE_HANDLE PeiCoreFileHandle;
> + VOID *PeiCoreImageBase;
> + VOID *PeiCoreEntryPoint;
> + EFI_STATUS Status;
> +
> + PeiCoreFileHandle = NULL;
> +
> + //
> + // Find the PEI Core in the BFV in temporary memory.
> + //
> + Status = CoreFvHandle.FvPpi->FindFileByType (
> + CoreFvHandle.FvPpi,
> + EFI_FV_FILETYPE_PEI_CORE,
> + CoreFvHandle.FvHandle,
> + &PeiCoreFileHandle
> + );
> + ASSERT_EFI_ERROR (Status);
> +
> + if (!EFI_ERROR (Status)) {
> + Status = CoreFvHandle.FvPpi->GetFileInfo (CoreFvHandle.FvPpi,
> PeiCoreFileHandle, &FileInfo);
> + ASSERT_EFI_ERROR (Status);
> +
> + Status = PeiGetPe32Data (PeiCoreFileHandle, &PeiCoreImageBase);
> + ASSERT_EFI_ERROR (Status);
> +
> + //
> + // Find PEI Core EntryPoint in the BFV in temporary memory.
> + //
> + Status = PeCoffLoaderGetEntryPoint ((VOID *) (UINTN) PeiCoreImageBase,
> &PeiCoreEntryPoint);
> + ASSERT_EFI_ERROR (Status);
> +
> + OrgImageBase = (UINTN) PeiCoreImageBase;
> + MigratedImageBase = (UINTN) _ModuleEntryPoint - ((UINTN)
> PeiCoreEntryPoint - (UINTN) PeiCoreImageBase);
> +
> + //
> + // Size of loaded PEI_CORE in permanent memory.
> + //
> + PeiCoreModuleSize = (UINTN)FileInfo.BufferSize - ((UINTN) OrgImageBase -
> (UINTN) FileInfo.Buffer);
> +
> + //
> + // Migrate PEI_CORE PPI pointers from temporary memory to newly
> + // installed PEI_CORE in permanent memory.
> + //
> + ConvertPpiPointersFv (PrivateData, (UINTN) OrgImageBase, (UINTN)
> MigratedImageBase, PeiCoreModuleSize);
> + }
> +}
> +
> --
> 2.25.1.windows.1
>
>
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [edk2-devel] [PATCH v5 2/9] MdeModulePkg/PeiCore: Enable T-RAM evacuation in PeiCore (CVE-2019-11098)
2020-07-13 6:38 ` Wang, Jian J
@ 2020-07-22 22:43 ` Laszlo Ersek
0 siblings, 0 replies; 24+ messages in thread
From: Laszlo Ersek @ 2020-07-22 22:43 UTC (permalink / raw)
To: devel, jian.j.wang, Jiang, Guomin
Cc: Michael Kubacki, Wu, Hao A, Bi, Dandan, Gao, Liming, De, Debkumar,
Han, Harry, West, Catharine
On 07/13/20 08:38, Wang, Jian J wrote:
>> +VOID
>> +ConvertStatusCodeCallbacks (
>> + IN UINTN OrgFvHandle,
>> + IN UINTN FvHandle,
>> + IN UINTN FvSize
>> + )
>> +{
>> + EFI_PEI_HOB_POINTERS Hob;
>> + UINTN *NumberOfEntries;
>> + UINTN *CallbackEntry;
>> + UINTN Index;
>> +
>> + Hob.Raw = GetFirstGuidHob (&gStatusCodeCallbackGuid);
>> + while (Hob.Raw != NULL) {
>> + NumberOfEntries = GET_GUID_HOB_DATA (Hob);
>> + CallbackEntry = NumberOfEntries + 1;
>> + for (Index = 0; Index < *NumberOfEntries; Index++) {
>> + if (((VOID *) CallbackEntry[Index]) != NULL) {
>> + if ((CallbackEntry[Index] >= OrgFvHandle) && (CallbackEntry[Index] <
>> (OrgFvHandle + FvSize))) {
>> + DEBUG ((DEBUG_INFO, "Migrating CallbackEntry[%d] from 0x%08X to ",
>> Index, CallbackEntry[Index]));
> CallbackEntry is defined as pointer to UINTN, which is 4-byte with 32-bit PEI.
> Using %08X might be not a good idea. Suggest to use %p instead.
>
For portability between 32-bit (such as IA32 and ARM) and 64-bit (such
as X64 and AARCH64), UINTN values should be printed as follows:
- cast them to UINT64
- print them with %Lx or %Lu
In the above message, we have two UINTN objects, Index and
CallbackEntry[Index]. Therefore, all of %d, %X, and %p are wrong. The
proper way is this:
DEBUG ((
DEBUG_INFO,
"Migrating CallbackEntry[%Lu] from 0x%016Lx to ",
(UINT64)Index,
(UINT64)CallbackEntry[Index]
));
If you want to zero-pad to 8 nibbles only (not 16) on ARM and IA32,
that's possible too. Replace the constant field width "16" with "*", and
pass the field width explicitly, as a parameter:
DEBUG ((
DEBUG_INFO,
"Migrating CallbackEntry[%Lu] from 0x%0*Lx to ",
(UINT64)Index,
(sizeof CallbackEntry[Index]) * 2,
(UINT64)CallbackEntry[Index]
));
The field width specifier "*" takes an extra parameter, which needs to
be of type UINTN in edk2 (see BasePrintLibSPrintMarker()). The sizeof
operator produces an UINTN.
The following example:
UINTN Foo;
Foo = 0xABCD;
DEBUG ((DEBUG_INFO, "Foo=0x%0*Lx\n", (sizeof Foo) * 2, (UINT64)Foo));
produces the following output on IA32:
Foo=0x0000ABCD
and on X64:
Foo=0x000000000000ABCD
Thanks,
Laszlo
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v5 3/9] UefiCpuPkg/CpuMpPei: Add GDT and IDT migration support (CVE-2019-11098)
2020-07-09 1:56 [PATCH v5 0/9] Add new feature that evacuate temporary to permanent memory (CVE-2019-11098) Guomin Jiang
2020-07-09 1:56 ` [PATCH v5 1/9] MdeModulePkg: Add new PCD to control the evacuate temporary memory feature (CVE-2019-11098) Guomin Jiang
2020-07-09 1:56 ` [PATCH v5 2/9] MdeModulePkg/PeiCore: Enable T-RAM evacuation in PeiCore (CVE-2019-11098) Guomin Jiang
@ 2020-07-09 1:56 ` Guomin Jiang
2020-07-09 11:04 ` [edk2-devel] " Laszlo Ersek
2020-07-09 1:56 ` [PATCH v5 4/9] UefiCpuPkg/SecMigrationPei: Add initial PEIM (CVE-2019-11098) Guomin Jiang
` (6 subsequent siblings)
9 siblings, 1 reply; 24+ messages in thread
From: Guomin Jiang @ 2020-07-09 1:56 UTC (permalink / raw)
To: devel; +Cc: Michael Kubacki, Eric Dong, Ray Ni, Laszlo Ersek, Rahul Kumar
From: Michael Kubacki <michael.a.kubacki@intel.com>
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=1614
Moves the GDT and IDT to permanent memory in a memory discovered
callback. This is done to ensure the GDT and IDT authenticated in
pre-memory is not fetched from outside a verified location after
the permanent memory transition.
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
---
UefiCpuPkg/CpuMpPei/CpuMpPei.inf | 1 +
UefiCpuPkg/CpuMpPei/CpuMpPei.h | 12 +++++++++++
UefiCpuPkg/CpuMpPei/CpuMpPei.c | 37 ++++++++++++++++++++++++++++++++
UefiCpuPkg/CpuMpPei/CpuPaging.c | 12 +++++++++--
4 files changed, 60 insertions(+), 2 deletions(-)
diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.inf b/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
index caead3ce34d4..f4d11b861f77 100644
--- a/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
+++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
@@ -63,6 +63,7 @@ [Pcd]
gUefiCpuPkgTokenSpaceGuid.PcdCpuStackSwitchExceptionList ## SOMETIMES_CONSUMES
gUefiCpuPkgTokenSpaceGuid.PcdCpuKnownGoodStackSize ## SOMETIMES_CONSUMES
gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize ## SOMETIMES_CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMigrateTemporaryRamFirmwareVolumes ## CONSUMES
[Depex]
TRUE
diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.h b/UefiCpuPkg/CpuMpPei/CpuMpPei.h
index 7d5c527d6006..309478cbe14c 100644
--- a/UefiCpuPkg/CpuMpPei/CpuMpPei.h
+++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.h
@@ -397,6 +397,18 @@ SecPlatformInformation2 (
OUT EFI_SEC_PLATFORM_INFORMATION_RECORD2 *PlatformInformationRecord2
);
+/**
+ Migrates the Global Descriptor Table (GDT) to permanent memory.
+
+ @retval EFI_SUCCESS The GDT was migrated successfully.
+ @retval EFI_OUT_OF_RESOURCES The GDT could not be migrated due to lack of available memory.
+
+**/
+EFI_STATUS
+MigrateGdt (
+ VOID
+ );
+
/**
Initializes MP and exceptions handlers.
diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.c b/UefiCpuPkg/CpuMpPei/CpuMpPei.c
index 07ccbe7c6a91..d07540cf7471 100644
--- a/UefiCpuPkg/CpuMpPei/CpuMpPei.c
+++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.c
@@ -429,6 +429,43 @@ GetGdtr (
AsmReadGdtr ((IA32_DESCRIPTOR *)Buffer);
}
+/**
+ Migrates the Global Descriptor Table (GDT) to permanent memory.
+
+ @retval EFI_SUCCESS The GDT was migrated successfully.
+ @retval EFI_OUT_OF_RESOURCES The GDT could not be migrated due to lack of available memory.
+
+**/
+EFI_STATUS
+MigrateGdt (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN GdtBufferSize;
+ IA32_DESCRIPTOR Gdtr;
+ VOID *GdtBuffer;
+
+ AsmReadGdtr ((IA32_DESCRIPTOR *) &Gdtr);
+ GdtBufferSize = sizeof (IA32_SEGMENT_DESCRIPTOR) -1 + Gdtr.Limit + 1;
+
+ Status = PeiServicesAllocatePool (
+ GdtBufferSize,
+ &GdtBuffer
+ );
+ ASSERT (GdtBuffer != NULL);
+ if (EFI_ERROR (Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ GdtBuffer = ALIGN_POINTER (GdtBuffer, sizeof (IA32_SEGMENT_DESCRIPTOR));
+ CopyMem (GdtBuffer, (VOID *) Gdtr.Base, Gdtr.Limit + 1);
+ Gdtr.Base = (UINTN) GdtBuffer;
+ AsmWriteGdtr (&Gdtr);
+
+ return EFI_SUCCESS;
+}
+
/**
Initializes CPU exceptions handlers for the sake of stack switch requirement.
diff --git a/UefiCpuPkg/CpuMpPei/CpuPaging.c b/UefiCpuPkg/CpuMpPei/CpuPaging.c
index a462e7ee1e38..3bf0574b34c6 100644
--- a/UefiCpuPkg/CpuMpPei/CpuPaging.c
+++ b/UefiCpuPkg/CpuMpPei/CpuPaging.c
@@ -602,8 +602,16 @@ MemoryDiscoveredPpiNotifyCallback (
IN VOID *Ppi
)
{
- EFI_STATUS Status;
- BOOLEAN InitStackGuard;
+ EFI_STATUS Status;
+ BOOLEAN InitStackGuard;
+ BOOLEAN InterruptState;
+
+ if (PcdGetBool (PcdMigrateTemporaryRamFirmwareVolumes)) {
+ InterruptState = SaveAndDisableInterrupts ();
+ Status = MigrateGdt ();
+ ASSERT_EFI_ERROR (Status);
+ SetInterruptState (InterruptState);
+ }
//
// Paging must be setup first. Otherwise the exception TSS setup during MP
--
2.25.1.windows.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [edk2-devel] [PATCH v5 3/9] UefiCpuPkg/CpuMpPei: Add GDT and IDT migration support (CVE-2019-11098)
2020-07-09 1:56 ` [PATCH v5 3/9] UefiCpuPkg/CpuMpPei: Add GDT and IDT migration support (CVE-2019-11098) Guomin Jiang
@ 2020-07-09 11:04 ` Laszlo Ersek
0 siblings, 0 replies; 24+ messages in thread
From: Laszlo Ersek @ 2020-07-09 11:04 UTC (permalink / raw)
To: devel, guomin.jiang; +Cc: Michael Kubacki, Eric Dong, Ray Ni, Rahul Kumar
On 07/09/20 03:56, Guomin Jiang wrote:
> From: Michael Kubacki <michael.a.kubacki@intel.com>
>
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=1614
>
> Moves the GDT and IDT to permanent memory in a memory discovered
> callback. This is done to ensure the GDT and IDT authenticated in
> pre-memory is not fetched from outside a verified location after
> the permanent memory transition.
>
> Cc: Eric Dong <eric.dong@intel.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Rahul Kumar <rahul1.kumar@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
> ---
> UefiCpuPkg/CpuMpPei/CpuMpPei.inf | 1 +
> UefiCpuPkg/CpuMpPei/CpuMpPei.h | 12 +++++++++++
> UefiCpuPkg/CpuMpPei/CpuMpPei.c | 37 ++++++++++++++++++++++++++++++++
> UefiCpuPkg/CpuMpPei/CpuPaging.c | 12 +++++++++--
> 4 files changed, 60 insertions(+), 2 deletions(-)
sorry, a question -- the subject line and the commit message reference
the IDT, not just the GDT. But the code handles the GDT only. Is this
intentional? Should the code handle the IDT, or should we remove the IDT
mentions from the subject and the commit message?
Thanks
Laszlo
> diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.inf b/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
> index caead3ce34d4..f4d11b861f77 100644
> --- a/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
> +++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
> @@ -63,6 +63,7 @@ [Pcd]
> gUefiCpuPkgTokenSpaceGuid.PcdCpuStackSwitchExceptionList ## SOMETIMES_CONSUMES
> gUefiCpuPkgTokenSpaceGuid.PcdCpuKnownGoodStackSize ## SOMETIMES_CONSUMES
> gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize ## SOMETIMES_CONSUMES
> + gEfiMdeModulePkgTokenSpaceGuid.PcdMigrateTemporaryRamFirmwareVolumes ## CONSUMES
>
> [Depex]
> TRUE
> diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.h b/UefiCpuPkg/CpuMpPei/CpuMpPei.h
> index 7d5c527d6006..309478cbe14c 100644
> --- a/UefiCpuPkg/CpuMpPei/CpuMpPei.h
> +++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.h
> @@ -397,6 +397,18 @@ SecPlatformInformation2 (
> OUT EFI_SEC_PLATFORM_INFORMATION_RECORD2 *PlatformInformationRecord2
> );
>
> +/**
> + Migrates the Global Descriptor Table (GDT) to permanent memory.
> +
> + @retval EFI_SUCCESS The GDT was migrated successfully.
> + @retval EFI_OUT_OF_RESOURCES The GDT could not be migrated due to lack of available memory.
> +
> +**/
> +EFI_STATUS
> +MigrateGdt (
> + VOID
> + );
> +
> /**
> Initializes MP and exceptions handlers.
>
> diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.c b/UefiCpuPkg/CpuMpPei/CpuMpPei.c
> index 07ccbe7c6a91..d07540cf7471 100644
> --- a/UefiCpuPkg/CpuMpPei/CpuMpPei.c
> +++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.c
> @@ -429,6 +429,43 @@ GetGdtr (
> AsmReadGdtr ((IA32_DESCRIPTOR *)Buffer);
> }
>
> +/**
> + Migrates the Global Descriptor Table (GDT) to permanent memory.
> +
> + @retval EFI_SUCCESS The GDT was migrated successfully.
> + @retval EFI_OUT_OF_RESOURCES The GDT could not be migrated due to lack of available memory.
> +
> +**/
> +EFI_STATUS
> +MigrateGdt (
> + VOID
> + )
> +{
> + EFI_STATUS Status;
> + UINTN GdtBufferSize;
> + IA32_DESCRIPTOR Gdtr;
> + VOID *GdtBuffer;
> +
> + AsmReadGdtr ((IA32_DESCRIPTOR *) &Gdtr);
> + GdtBufferSize = sizeof (IA32_SEGMENT_DESCRIPTOR) -1 + Gdtr.Limit + 1;
> +
> + Status = PeiServicesAllocatePool (
> + GdtBufferSize,
> + &GdtBuffer
> + );
> + ASSERT (GdtBuffer != NULL);
> + if (EFI_ERROR (Status)) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + GdtBuffer = ALIGN_POINTER (GdtBuffer, sizeof (IA32_SEGMENT_DESCRIPTOR));
> + CopyMem (GdtBuffer, (VOID *) Gdtr.Base, Gdtr.Limit + 1);
> + Gdtr.Base = (UINTN) GdtBuffer;
> + AsmWriteGdtr (&Gdtr);
> +
> + return EFI_SUCCESS;
> +}
> +
> /**
> Initializes CPU exceptions handlers for the sake of stack switch requirement.
>
> diff --git a/UefiCpuPkg/CpuMpPei/CpuPaging.c b/UefiCpuPkg/CpuMpPei/CpuPaging.c
> index a462e7ee1e38..3bf0574b34c6 100644
> --- a/UefiCpuPkg/CpuMpPei/CpuPaging.c
> +++ b/UefiCpuPkg/CpuMpPei/CpuPaging.c
> @@ -602,8 +602,16 @@ MemoryDiscoveredPpiNotifyCallback (
> IN VOID *Ppi
> )
> {
> - EFI_STATUS Status;
> - BOOLEAN InitStackGuard;
> + EFI_STATUS Status;
> + BOOLEAN InitStackGuard;
> + BOOLEAN InterruptState;
> +
> + if (PcdGetBool (PcdMigrateTemporaryRamFirmwareVolumes)) {
> + InterruptState = SaveAndDisableInterrupts ();
> + Status = MigrateGdt ();
> + ASSERT_EFI_ERROR (Status);
> + SetInterruptState (InterruptState);
> + }
>
> //
> // Paging must be setup first. Otherwise the exception TSS setup during MP
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v5 4/9] UefiCpuPkg/SecMigrationPei: Add initial PEIM (CVE-2019-11098)
2020-07-09 1:56 [PATCH v5 0/9] Add new feature that evacuate temporary to permanent memory (CVE-2019-11098) Guomin Jiang
` (2 preceding siblings ...)
2020-07-09 1:56 ` [PATCH v5 3/9] UefiCpuPkg/CpuMpPei: Add GDT and IDT migration support (CVE-2019-11098) Guomin Jiang
@ 2020-07-09 1:56 ` Guomin Jiang
2020-07-09 11:01 ` [edk2-devel] " Laszlo Ersek
2020-07-13 6:56 ` Wang, Jian J
2020-07-09 1:56 ` [PATCH v5 5/9] MdeModulePkg/Core: Create Migrated FV Info Hob for calculating hash (CVE-2019-11098) Guomin Jiang
` (5 subsequent siblings)
9 siblings, 2 replies; 24+ messages in thread
From: Guomin Jiang @ 2020-07-09 1:56 UTC (permalink / raw)
To: devel
Cc: Michael Kubacki, Eric Dong, Ray Ni, Laszlo Ersek, Rahul Kumar,
Debkumar De, Harry Han, Catharine West
From: Michael Kubacki <michael.a.kubacki@intel.com>
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=1614
Adds a PEIM that republishes structures produced in SEC. This
is done because SEC modules may not be shadowed in some platforms
due to space constraints or special alignment requirements. The
SecMigrationPei module locates interfaces that may be published in
SEC and reinstalls the interface with permanent memory addresses.
This is important if pre-memory address access is forbidden after
memory initialization and data such as a PPI descriptor, PPI GUID,
or PPI inteface reside in pre-memory.
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Debkumar De <debkumar.de@intel.com>
Cc: Harry Han <harry.han@intel.com>
Cc: Catharine West <catharine.west@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
---
UefiCpuPkg/UefiCpuPkg.dec | 4 +
UefiCpuPkg/UefiCpuPkg.dsc | 1 +
UefiCpuPkg/SecCore/SecCore.inf | 2 +
.../SecMigrationPei/SecMigrationPei.inf | 67 +++
UefiCpuPkg/Include/Ppi/RepublishSecPpi.h | 54 +++
UefiCpuPkg/SecCore/SecMain.h | 1 +
UefiCpuPkg/SecMigrationPei/SecMigrationPei.h | 154 +++++++
UefiCpuPkg/SecCore/SecMain.c | 26 +-
UefiCpuPkg/SecMigrationPei/SecMigrationPei.c | 381 ++++++++++++++++++
.../SecMigrationPei/SecMigrationPei.uni | 13 +
10 files changed, 701 insertions(+), 2 deletions(-)
create mode 100644 UefiCpuPkg/SecMigrationPei/SecMigrationPei.inf
create mode 100644 UefiCpuPkg/Include/Ppi/RepublishSecPpi.h
create mode 100644 UefiCpuPkg/SecMigrationPei/SecMigrationPei.h
create mode 100644 UefiCpuPkg/SecMigrationPei/SecMigrationPei.c
create mode 100644 UefiCpuPkg/SecMigrationPei/SecMigrationPei.uni
diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec
index 762badf5d239..0a005bd20311 100644
--- a/UefiCpuPkg/UefiCpuPkg.dec
+++ b/UefiCpuPkg/UefiCpuPkg.dec
@@ -66,6 +66,10 @@ [Guids]
## Include/Guid/MicrocodePatchHob.h
gEdkiiMicrocodePatchHobGuid = { 0xd178f11d, 0x8716, 0x418e, { 0xa1, 0x31, 0x96, 0x7d, 0x2a, 0xc4, 0x28, 0x43 }}
+[Ppis]
+ ## Include/Ppi/RepublishSecPpi.h
+ gRepublishSecPpiPpiGuid = { 0x27a71b1e, 0x73ee, 0x43d6, { 0xac, 0xe3, 0x52, 0x1a, 0x2d, 0xc5, 0xd0, 0x92 }}
+
[Protocols]
## Include/Protocol/SmmCpuService.h
gEfiSmmCpuServiceProtocolGuid = { 0x1d202cab, 0xc8ab, 0x4d5c, { 0x94, 0xf7, 0x3c, 0xfc, 0xc0, 0xd3, 0xd3, 0x35 }}
diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc
index afa304128221..964720048dd7 100644
--- a/UefiCpuPkg/UefiCpuPkg.dsc
+++ b/UefiCpuPkg/UefiCpuPkg.dsc
@@ -146,6 +146,7 @@ [Components.IA32, Components.X64]
UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf
UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf
UefiCpuPkg/SecCore/SecCore.inf
+ UefiCpuPkg/SecMigrationPei/SecMigrationPei.inf
UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf {
<Defines>
diff --git a/UefiCpuPkg/SecCore/SecCore.inf b/UefiCpuPkg/SecCore/SecCore.inf
index 0562820c95e0..545781d6b4b3 100644
--- a/UefiCpuPkg/SecCore/SecCore.inf
+++ b/UefiCpuPkg/SecCore/SecCore.inf
@@ -68,6 +68,8 @@ [Ppis]
## SOMETIMES_CONSUMES
gPeiSecPerformancePpiGuid
gEfiPeiCoreFvLocationPpiGuid
+ ## CONSUMES
+ gRepublishSecPpiPpiGuid
[Guids]
## SOMETIMES_PRODUCES ## HOB
diff --git a/UefiCpuPkg/SecMigrationPei/SecMigrationPei.inf b/UefiCpuPkg/SecMigrationPei/SecMigrationPei.inf
new file mode 100644
index 000000000000..f4c2f6b658fb
--- /dev/null
+++ b/UefiCpuPkg/SecMigrationPei/SecMigrationPei.inf
@@ -0,0 +1,67 @@
+## @file
+# Migrates SEC structures after permanent memory is installed.
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SecMigrationPei
+ MODULE_UNI_FILE = SecMigrationPei.uni
+ FILE_GUID = 58B35361-8922-41BC-B313-EF7ED9ADFDF7
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ ENTRY_POINT = SecMigrationPeiInitialize
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[Sources]
+ SecMigrationPei.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ HobLib
+ MemoryAllocationLib
+ PeimEntryPoint
+ PeiServicesLib
+ PeiServicesTablePointerLib
+
+[Ppis]
+ ## PRODUCES
+ gRepublishSecPpiPpiGuid
+
+ ## SOMETIMES_PRODUCES
+ gEfiTemporaryRamDonePpiGuid
+
+ ## SOMETIME_PRODUCES
+ gEfiTemporaryRamSupportPpiGuid
+
+ ## SOMETIMES_PRODUCES
+ gPeiSecPerformancePpiGuid
+
+ ## SOMETIMES_CONSUMES
+ ## PRODUCES
+ gEfiSecPlatformInformationPpiGuid
+
+ ## SOMETIMES_CONSUMES
+ ## SOMETIMES_PRODUCES
+ gEfiSecPlatformInformation2PpiGuid
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMigrateTemporaryRamFirmwareVolumes ## CONSUMES
+
+[Depex]
+ TRUE
diff --git a/UefiCpuPkg/Include/Ppi/RepublishSecPpi.h b/UefiCpuPkg/Include/Ppi/RepublishSecPpi.h
new file mode 100644
index 000000000000..ea865acbb5c8
--- /dev/null
+++ b/UefiCpuPkg/Include/Ppi/RepublishSecPpi.h
@@ -0,0 +1,54 @@
+/** @file
+ This file declares Sec Platform Information PPI.
+
+ This service is the primary handoff state into the PEI Foundation.
+ The Security (SEC) component creates the early, transitory memory
+ environment and also encapsulates knowledge of at least the
+ location of the Boot Firmware Volume (BFV).
+
+ Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Revision Reference:
+ This PPI is introduced in PI Version 1.0.
+
+**/
+
+#ifndef __REPUBLISH_SEC_PPI_H__
+#define __REPUBLISH_SEC_PPI_H__
+
+#include <Pi/PiPeiCis.h>
+
+#define REPUBLISH_SEC_PPI_PPI_GUID \
+ { \
+ 0x27a71b1e, 0x73ee, 0x43d6, { 0xac, 0xe3, 0x52, 0x1a, 0x2d, 0xc5, 0xd0, 0x92 } \
+ }
+
+typedef struct _REPUBLISH_SEC_PPI_PPI REPUBLISH_SEC_PPI_PPI;
+
+/**
+ This interface re-installs PPIs installed in SecCore from a post-memory PEIM.
+
+ This is to allow a platform that may not support relocation of SecCore to update the PPI instance to a post-memory
+ copy from a PEIM that has been shadowed to permanent memory.
+
+ @retval EFI_SUCCESS The SecCore PPIs were re-installed successfully.
+ @retval Others An error occurred re-installing the SecCore PPIs.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *REPUBLISH_SEC_PPI_REPUBLISH_SEC_PPIS)(
+ VOID
+ );
+
+///
+/// Republish SEC PPIs
+///
+struct _REPUBLISH_SEC_PPI_PPI {
+ REPUBLISH_SEC_PPI_REPUBLISH_SEC_PPIS RepublishSecPpis;
+};
+
+extern EFI_GUID gRepublishSecPpiPpiGuid;
+
+#endif
diff --git a/UefiCpuPkg/SecCore/SecMain.h b/UefiCpuPkg/SecCore/SecMain.h
index e8c05d713668..e20bcf86532c 100644
--- a/UefiCpuPkg/SecCore/SecMain.h
+++ b/UefiCpuPkg/SecCore/SecMain.h
@@ -15,6 +15,7 @@
#include <Ppi/TemporaryRamDone.h>
#include <Ppi/SecPerformance.h>
#include <Ppi/PeiCoreFvLocation.h>
+#include <Ppi/RepublishSecPpi.h>
#include <Guid/FirmwarePerformance.h>
diff --git a/UefiCpuPkg/SecMigrationPei/SecMigrationPei.h b/UefiCpuPkg/SecMigrationPei/SecMigrationPei.h
new file mode 100644
index 000000000000..414672a5afe6
--- /dev/null
+++ b/UefiCpuPkg/SecMigrationPei/SecMigrationPei.h
@@ -0,0 +1,154 @@
+/** @file
+ Migrates SEC structures after permanent memory is installed.
+
+ Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __SEC_MIGRATION_H__
+#define __SEC_MIGRATION_H__
+
+#include <Base.h>
+
+#include <Pi/PiPeiCis.h>
+#include <Ppi/RepublishSecPpi.h>
+#include <Ppi/SecPerformance.h>
+#include <Ppi/SecPlatformInformation.h>
+#include <Ppi/SecPlatformInformation2.h>
+#include <Ppi/TemporaryRamDone.h>
+#include <Ppi/TemporaryRamSupport.h>
+
+/**
+ This interface conveys state information out of the Security (SEC) phase into PEI.
+
+ @param[in] PeiServices Pointer to the PEI Services Table.
+ @param[in,out] StructureSize Pointer to the variable describing size of the input buffer.
+ @param[out] PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD.
+
+ @retval EFI_SUCCESS The data was successfully returned.
+ @retval EFI_BUFFER_TOO_SMALL The buffer was too small.
+
+**/
+EFI_STATUS
+EFIAPI
+SecPlatformInformationPostMemory (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN OUT UINT64 *StructureSize,
+ OUT EFI_SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord
+ );
+
+/**
+ Re-installs the SEC Platform Information PPIs to implementation in this module to support post-memory.
+
+ @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
+ @param[in] NotifyDescriptor Address of the notification descriptor data structure.
+ @param[in] Ppi Address of the PPI that was installed.
+
+ @retval EFI_SUCCESS The SEC Platform Information PPI could not be re-installed.
+ @return Others An error occurred during PPI re-install.
+
+**/
+EFI_STATUS
+EFIAPI
+SecPlatformInformationPpiNotifyCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ );
+
+/**
+ This interface re-installs PPIs installed in SecCore from a post-memory PEIM.
+
+ This is to allow a platform that may not support relocation of SecCore to update the PPI instance to a post-memory
+ copy from a PEIM that has been shadowed to permanent memory.
+
+ @retval EFI_SUCCESS The SecCore PPIs were re-installed successfully.
+ @retval Others An error occurred re-installing the SecCore PPIs.
+
+**/
+EFI_STATUS
+EFIAPI
+RepublishSecPpis (
+ VOID
+ );
+
+/**
+ Disables the use of Temporary RAM.
+
+ If present, this service is invoked by the PEI Foundation after
+ the EFI_PEI_PERMANANT_MEMORY_INSTALLED_PPI is installed.
+
+ @retval EFI_SUCCESS Use of Temporary RAM was disabled.
+ @retval EFI_INVALID_PARAMETER Temporary RAM could not be disabled.
+
+**/
+EFI_STATUS
+EFIAPI
+SecTemporaryRamDonePostMemory (
+ VOID
+ );
+
+/**
+ This service of the EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI that migrates temporary RAM into
+ permanent memory.
+
+ @param PeiServices Pointer to the PEI Services Table.
+ @param TemporaryMemoryBase Source Address in temporary memory from which the SEC or PEIM will copy the
+ Temporary RAM contents.
+ @param PermanentMemoryBase Destination Address in permanent memory into which the SEC or PEIM will copy the
+ Temporary RAM contents.
+ @param CopySize Amount of memory to migrate from temporary to permanent memory.
+
+ @retval EFI_SUCCESS The data was successfully returned.
+ @retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize > TemporaryMemoryBase when
+ TemporaryMemoryBase > PermanentMemoryBase.
+
+**/
+EFI_STATUS
+EFIAPI
+SecTemporaryRamSupportPostMemory (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
+ IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
+ IN UINTN CopySize
+ );
+
+/**
+ This interface conveys performance information out of the Security (SEC) phase into PEI.
+
+ This service is published by the SEC phase. The SEC phase handoff has an optional
+ EFI_PEI_PPI_DESCRIPTOR list as its final argument when control is passed from SEC into the
+ PEI Foundation. As such, if the platform supports collecting performance data in SEC,
+ this information is encapsulated into the data structure abstracted by this service.
+ This information is collected for the boot-strap processor (BSP) on IA-32.
+
+ @param[in] PeiServices The pointer to the PEI Services Table.
+ @param[in] This The pointer to this instance of the PEI_SEC_PERFORMANCE_PPI.
+ @param[out] Performance The pointer to performance data collected in SEC phase.
+
+ @retval EFI_SUCCESS The performance data was successfully returned.
+
+**/
+EFI_STATUS
+EFIAPI
+GetPerformancePostMemory (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN PEI_SEC_PERFORMANCE_PPI *This,
+ OUT FIRMWARE_SEC_PERFORMANCE *Performance
+ );
+
+typedef struct {
+ UINT64 StructureSize;
+ EFI_SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord;
+} SEC_PLATFORM_INFORMATION_CONTEXT;
+
+typedef struct {
+ EFI_HOB_GUID_TYPE Header;
+ UINT8 Revision;
+ UINT8 Reserved[3];
+ FIRMWARE_SEC_PERFORMANCE FirmwareSecPerformance;
+ SEC_PLATFORM_INFORMATION_CONTEXT Context;
+} SEC_PLATFORM_INFORMATION_CONTEXT_HOB;
+
+#endif
diff --git a/UefiCpuPkg/SecCore/SecMain.c b/UefiCpuPkg/SecCore/SecMain.c
index 5d5e7f17dced..155be49a6011 100644
--- a/UefiCpuPkg/SecCore/SecMain.c
+++ b/UefiCpuPkg/SecCore/SecMain.c
@@ -370,13 +370,35 @@ SecTemporaryRamDone (
VOID
)
{
- BOOLEAN State;
+ EFI_STATUS Status;
+ EFI_STATUS Status2;
+ UINTN Index;
+ BOOLEAN State;
+ EFI_PEI_PPI_DESCRIPTOR *PeiPpiDescriptor;
+ REPUBLISH_SEC_PPI_PPI *RepublishSecPpiPpi;
//
// Republish Sec Platform Information(2) PPI
//
RepublishSecPlatformInformationPpi ();
+ //
+ // Re-install SEC PPIs using a PEIM produced service if published
+ //
+ for (Index = 0, Status = EFI_SUCCESS; Status == EFI_SUCCESS; Index++) {
+ Status = PeiServicesLocatePpi (
+ &gRepublishSecPpiPpiGuid,
+ Index,
+ &PeiPpiDescriptor,
+ (VOID **) &RepublishSecPpiPpi
+ );
+ if (!EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_INFO, "Calling RepublishSecPpi instance %d.\n", Index));
+ Status2 = RepublishSecPpiPpi->RepublishSecPpis ();
+ ASSERT_EFI_ERROR (Status2);
+ }
+ }
+
//
// Migrate DebugAgentContext.
//
@@ -385,7 +407,7 @@ SecTemporaryRamDone (
//
// Disable interrupts and save current interrupt state
//
- State = SaveAndDisableInterrupts();
+ State = SaveAndDisableInterrupts ();
//
// Disable Temporary RAM after Stack and Heap have been migrated at this point.
diff --git a/UefiCpuPkg/SecMigrationPei/SecMigrationPei.c b/UefiCpuPkg/SecMigrationPei/SecMigrationPei.c
new file mode 100644
index 000000000000..a62d50bcbb0d
--- /dev/null
+++ b/UefiCpuPkg/SecMigrationPei/SecMigrationPei.c
@@ -0,0 +1,381 @@
+/** @file
+ Migrates SEC structures after permanent memory is installed.
+
+ Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Base.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+
+#include "SecMigrationPei.h"
+
+STATIC REPUBLISH_SEC_PPI_PPI mEdkiiRepublishSecPpiPpi = {
+ RepublishSecPpis
+ };
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_SEC_PLATFORM_INFORMATION_PPI mSecPlatformInformationPostMemoryPpi = {
+ SecPlatformInformationPostMemory
+ };
+
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_PEI_TEMPORARY_RAM_DONE_PPI mSecTemporaryRamDonePostMemoryPpi = {
+ SecTemporaryRamDonePostMemory
+ };
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mSecTemporaryRamSupportPostMemoryPpi = {
+ SecTemporaryRamSupportPostMemory
+ };
+
+GLOBAL_REMOVE_IF_UNREFERENCED PEI_SEC_PERFORMANCE_PPI mSecPerformancePpi = {
+ GetPerformancePostMemory
+ };
+
+STATIC EFI_PEI_PPI_DESCRIPTOR mEdkiiRepublishSecPpiDescriptor = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gRepublishSecPpiPpiGuid,
+ &mEdkiiRepublishSecPpiPpi
+ };
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_PEI_PPI_DESCRIPTOR mSecPlatformInformationPostMemoryDescriptor = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiSecPlatformInformationPpiGuid,
+ &mSecPlatformInformationPostMemoryPpi
+ };
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_PEI_PPI_DESCRIPTOR mSecTemporaryRamDonePostMemoryDescriptor = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiTemporaryRamDonePpiGuid,
+ &mSecTemporaryRamDonePostMemoryPpi
+ };
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_PEI_PPI_DESCRIPTOR mSecTemporaryRamSupportPostMemoryDescriptor = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiTemporaryRamSupportPpiGuid,
+ &mSecTemporaryRamSupportPostMemoryPpi
+ };
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_PEI_PPI_DESCRIPTOR mSecPerformancePpiDescriptor = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gPeiSecPerformancePpiGuid,
+ &mSecPerformancePpi
+ };
+
+/**
+ Disables the use of Temporary RAM.
+
+ If present, this service is invoked by the PEI Foundation after
+ the EFI_PEI_PERMANANT_MEMORY_INSTALLED_PPI is installed.
+
+ @retval EFI_SUCCESS Use of Temporary RAM was disabled.
+ @retval EFI_INVALID_PARAMETER Temporary RAM could not be disabled.
+
+**/
+EFI_STATUS
+EFIAPI
+SecTemporaryRamDonePostMemory (
+ VOID
+ )
+{
+ //
+ // Temporary RAM Done is already done in post-memory
+ // install a stub function that is located in permanent memory
+ //
+ return EFI_SUCCESS;
+}
+
+/**
+ This service of the EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI that migrates temporary RAM into
+ permanent memory.
+
+ @param PeiServices Pointer to the PEI Services Table.
+ @param TemporaryMemoryBase Source Address in temporary memory from which the SEC or PEIM will copy the
+ Temporary RAM contents.
+ @param PermanentMemoryBase Destination Address in permanent memory into which the SEC or PEIM will copy the
+ Temporary RAM contents.
+ @param CopySize Amount of memory to migrate from temporary to permanent memory.
+
+ @retval EFI_SUCCESS The data was successfully returned.
+ @retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize > TemporaryMemoryBase when
+ TemporaryMemoryBase > PermanentMemoryBase.
+
+**/
+EFI_STATUS
+EFIAPI
+SecTemporaryRamSupportPostMemory (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
+ IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
+ IN UINTN CopySize
+ )
+{
+ //
+ // Temporary RAM Support is already done in post-memory
+ // install a stub function that is located in permanent memory
+ //
+ return EFI_SUCCESS;
+}
+
+/**
+ This interface conveys performance information out of the Security (SEC) phase into PEI.
+
+ This service is published by the SEC phase. The SEC phase handoff has an optional
+ EFI_PEI_PPI_DESCRIPTOR list as its final argument when control is passed from SEC into the
+ PEI Foundation. As such, if the platform supports collecting performance data in SEC,
+ this information is encapsulated into the data structure abstracted by this service.
+ This information is collected for the boot-strap processor (BSP) on IA-32.
+
+ @param[in] PeiServices The pointer to the PEI Services Table.
+ @param[in] This The pointer to this instance of the PEI_SEC_PERFORMANCE_PPI.
+ @param[out] Performance The pointer to performance data collected in SEC phase.
+
+ @retval EFI_SUCCESS The performance data was successfully returned.
+
+**/
+EFI_STATUS
+EFIAPI
+GetPerformancePostMemory (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN PEI_SEC_PERFORMANCE_PPI *This,
+ OUT FIRMWARE_SEC_PERFORMANCE *Performance
+ )
+{
+ SEC_PLATFORM_INFORMATION_CONTEXT_HOB *SecPlatformInformationContexHob;
+
+ if (This == NULL || Performance == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ SecPlatformInformationContexHob = GetFirstGuidHob (&gEfiCallerIdGuid);
+ if (SecPlatformInformationContexHob == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ Performance->ResetEnd = SecPlatformInformationContexHob->FirmwareSecPerformance.ResetEnd;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This interface conveys state information out of the Security (SEC) phase into PEI.
+
+ @param[in] PeiServices Pointer to the PEI Services Table.
+ @param[in,out] StructureSize Pointer to the variable describing size of the input buffer.
+ @param[out] PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD.
+
+ @retval EFI_SUCCESS The data was successfully returned.
+ @retval EFI_BUFFER_TOO_SMALL The buffer was too small.
+
+**/
+EFI_STATUS
+EFIAPI
+SecPlatformInformationPostMemory (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN OUT UINT64 *StructureSize,
+ OUT EFI_SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord
+ )
+{
+ SEC_PLATFORM_INFORMATION_CONTEXT_HOB *SecPlatformInformationContexHob;
+
+ if (StructureSize == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ SecPlatformInformationContexHob = GetFirstGuidHob (&gEfiCallerIdGuid);
+ if (SecPlatformInformationContexHob == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ if (*StructureSize < SecPlatformInformationContexHob->Context.StructureSize) {
+ *StructureSize = SecPlatformInformationContexHob->Context.StructureSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ if (PlatformInformationRecord == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *StructureSize = SecPlatformInformationContexHob->Context.StructureSize;
+ CopyMem (
+ (VOID *) PlatformInformationRecord,
+ (VOID *) SecPlatformInformationContexHob->Context.PlatformInformationRecord,
+ (UINTN) SecPlatformInformationContexHob->Context.StructureSize
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This interface re-installs PPIs installed in SecCore from a post-memory PEIM.
+
+ This is to allow a platform that may not support relocation of SecCore to update the PPI instance to a post-memory
+ copy from a PEIM that has been shadowed to permanent memory.
+
+ @retval EFI_SUCCESS The SecCore PPIs were re-installed successfully.
+ @retval Others An error occurred re-installing the SecCore PPIs.
+
+**/
+EFI_STATUS
+EFIAPI
+RepublishSecPpis (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_PPI_DESCRIPTOR *PeiPpiDescriptor;
+ VOID *PeiPpi;
+ SEC_PLATFORM_INFORMATION_CONTEXT_HOB *SecPlatformInformationContextHob;
+ EFI_SEC_PLATFORM_INFORMATION_RECORD *SecPlatformInformationPtr;
+ UINT64 SecStructureSize;
+
+ SecPlatformInformationPtr = NULL;
+ SecStructureSize = 0;
+
+ Status = PeiServicesLocatePpi (
+ &gEfiTemporaryRamDonePpiGuid,
+ 0,
+ &PeiPpiDescriptor,
+ (VOID **) &PeiPpi
+ );
+ if (!EFI_ERROR (Status)) {
+ Status = PeiServicesReInstallPpi (
+ PeiPpiDescriptor,
+ &mSecTemporaryRamDonePostMemoryDescriptor
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ Status = PeiServicesLocatePpi (
+ &gEfiTemporaryRamSupportPpiGuid,
+ 0,
+ &PeiPpiDescriptor,
+ (VOID **) &PeiPpi
+ );
+ if (!EFI_ERROR (Status)) {
+ Status = PeiServicesReInstallPpi (
+ PeiPpiDescriptor,
+ &mSecTemporaryRamSupportPostMemoryDescriptor
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ Status = PeiServicesCreateHob (
+ EFI_HOB_TYPE_GUID_EXTENSION,
+ sizeof (SEC_PLATFORM_INFORMATION_CONTEXT_HOB),
+ (VOID **) &SecPlatformInformationContextHob
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "SecPlatformInformation Context HOB could not be created.\n"));
+ return Status;
+ }
+
+ SecPlatformInformationContextHob->Header.Name = gEfiCallerIdGuid;
+ SecPlatformInformationContextHob->Revision = 1;
+
+ Status = PeiServicesLocatePpi (
+ &gPeiSecPerformancePpiGuid,
+ 0,
+ &PeiPpiDescriptor,
+ (VOID **) &PeiPpi
+ );
+ if (!EFI_ERROR (Status)) {
+ Status = ((PEI_SEC_PERFORMANCE_PPI *) PeiPpi)->GetPerformance (
+ GetPeiServicesTablePointer (),
+ (PEI_SEC_PERFORMANCE_PPI *) PeiPpi,
+ &SecPlatformInformationContextHob->FirmwareSecPerformance
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (!EFI_ERROR (Status)) {
+ Status = PeiServicesReInstallPpi (
+ PeiPpiDescriptor,
+ &mSecPerformancePpiDescriptor
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+
+ Status = PeiServicesLocatePpi (
+ &gEfiSecPlatformInformationPpiGuid,
+ 0,
+ &PeiPpiDescriptor,
+ (VOID **) &PeiPpi
+ );
+ if (!EFI_ERROR (Status)) {
+ Status = ((EFI_SEC_PLATFORM_INFORMATION_PPI *) PeiPpi)->PlatformInformation (
+ GetPeiServicesTablePointer (),
+ &SecStructureSize,
+ SecPlatformInformationPtr
+ );
+ ASSERT (Status == EFI_BUFFER_TOO_SMALL);
+ if (Status != EFI_BUFFER_TOO_SMALL) {
+ return EFI_NOT_FOUND;
+ }
+
+ ZeroMem ((VOID *) &(SecPlatformInformationContextHob->Context), sizeof (SEC_PLATFORM_INFORMATION_CONTEXT));
+ SecPlatformInformationContextHob->Context.PlatformInformationRecord = AllocatePool ((UINTN) SecStructureSize);
+ ASSERT (SecPlatformInformationContextHob->Context.PlatformInformationRecord != NULL);
+ if (SecPlatformInformationContextHob->Context.PlatformInformationRecord == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ SecPlatformInformationContextHob->Context.StructureSize = SecStructureSize;
+
+ Status = ((EFI_SEC_PLATFORM_INFORMATION_PPI *) PeiPpi)->PlatformInformation (
+ GetPeiServicesTablePointer (),
+ &(SecPlatformInformationContextHob->Context.StructureSize),
+ SecPlatformInformationContextHob->Context.PlatformInformationRecord
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (!EFI_ERROR (Status)) {
+ Status = PeiServicesReInstallPpi (
+ PeiPpiDescriptor,
+ &mSecPlatformInformationPostMemoryDescriptor
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function is the entry point which installs an instance of REPUBLISH_SEC_PPI_PPI.
+
+ It install the RepublishSecPpi depent on PcdMigrateTemporaryRamFirmwareVolumes, install
+ the PPI when the PcdMigrateTemporaryRamFirmwareVolumes enabled.
+
+ @param[in] FileHandle Pointer to image file handle.
+ @param[in] PeiServices Pointer to PEI Services Table
+
+ @retval EFI_ABORTED Disable evacuate temporary memory feature by disable
+ PcdMigrateTemporaryRamFirmwareVolumes.
+ EFI_SUCCESS An instance of REPUBLISH_SEC_PPI_PPI was installed successfully.
+ @retval Others An error occurred installing and instance of REPUBLISH_SEC_PPI_PPI.
+
+**/
+EFI_STATUS
+EFIAPI
+SecMigrationPeiInitialize (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EFI_ABORTED;
+
+ if (PcdGetBool (PcdMigrateTemporaryRamFirmwareVolumes)) {
+ Status = PeiServicesInstallPpi (&mEdkiiRepublishSecPpiDescriptor);
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ return Status;
+}
diff --git a/UefiCpuPkg/SecMigrationPei/SecMigrationPei.uni b/UefiCpuPkg/SecMigrationPei/SecMigrationPei.uni
new file mode 100644
index 000000000000..62c2064ba217
--- /dev/null
+++ b/UefiCpuPkg/SecMigrationPei/SecMigrationPei.uni
@@ -0,0 +1,13 @@
+// /** @file
+// Migrates SEC structures after permanent memory is installed.
+//
+// Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Migrates SEC structures after permanent memory is installed"
+
+#string STR_MODULE_DESCRIPTION #language en-US "Migrates SEC structures after permanent memory is installed."
+
--
2.25.1.windows.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [edk2-devel] [PATCH v5 4/9] UefiCpuPkg/SecMigrationPei: Add initial PEIM (CVE-2019-11098)
2020-07-09 1:56 ` [PATCH v5 4/9] UefiCpuPkg/SecMigrationPei: Add initial PEIM (CVE-2019-11098) Guomin Jiang
@ 2020-07-09 11:01 ` Laszlo Ersek
2020-07-13 6:56 ` Wang, Jian J
1 sibling, 0 replies; 24+ messages in thread
From: Laszlo Ersek @ 2020-07-09 11:01 UTC (permalink / raw)
To: devel, guomin.jiang
Cc: Michael Kubacki, Eric Dong, Ray Ni, Rahul Kumar, Debkumar De,
Harry Han, Catharine West
On 07/09/20 03:56, Guomin Jiang wrote:
> From: Michael Kubacki <michael.a.kubacki@intel.com>
>
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=1614
>
> Adds a PEIM that republishes structures produced in SEC. This
> is done because SEC modules may not be shadowed in some platforms
> due to space constraints or special alignment requirements. The
> SecMigrationPei module locates interfaces that may be published in
> SEC and reinstalls the interface with permanent memory addresses.
>
> This is important if pre-memory address access is forbidden after
> memory initialization and data such as a PPI descriptor, PPI GUID,
> or PPI inteface reside in pre-memory.
>
> Cc: Eric Dong <eric.dong@intel.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Rahul Kumar <rahul1.kumar@intel.com>
> Cc: Debkumar De <debkumar.de@intel.com>
> Cc: Harry Han <harry.han@intel.com>
> Cc: Catharine West <catharine.west@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> Acked-by: Laszlo Ersek <lersek@redhat.com>
> ---
> UefiCpuPkg/UefiCpuPkg.dec | 4 +
> UefiCpuPkg/UefiCpuPkg.dsc | 1 +
> UefiCpuPkg/SecCore/SecCore.inf | 2 +
> .../SecMigrationPei/SecMigrationPei.inf | 67 +++
> UefiCpuPkg/Include/Ppi/RepublishSecPpi.h | 54 +++
> UefiCpuPkg/SecCore/SecMain.h | 1 +
> UefiCpuPkg/SecMigrationPei/SecMigrationPei.h | 154 +++++++
> UefiCpuPkg/SecCore/SecMain.c | 26 +-
> UefiCpuPkg/SecMigrationPei/SecMigrationPei.c | 381 ++++++++++++++++++
> .../SecMigrationPei/SecMigrationPei.uni | 13 +
> 10 files changed, 701 insertions(+), 2 deletions(-)
> create mode 100644 UefiCpuPkg/SecMigrationPei/SecMigrationPei.inf
> create mode 100644 UefiCpuPkg/Include/Ppi/RepublishSecPpi.h
> create mode 100644 UefiCpuPkg/SecMigrationPei/SecMigrationPei.h
> create mode 100644 UefiCpuPkg/SecMigrationPei/SecMigrationPei.c
> create mode 100644 UefiCpuPkg/SecMigrationPei/SecMigrationPei.uni
> +/**
> + This function is the entry point which installs an instance of REPUBLISH_SEC_PPI_PPI.
> +
> + It install the RepublishSecPpi depent on PcdMigrateTemporaryRamFirmwareVolumes, install
> + the PPI when the PcdMigrateTemporaryRamFirmwareVolumes enabled.
> +
> + @param[in] FileHandle Pointer to image file handle.
> + @param[in] PeiServices Pointer to PEI Services Table
> +
> + @retval EFI_ABORTED Disable evacuate temporary memory feature by disable
> + PcdMigrateTemporaryRamFirmwareVolumes.
> + EFI_SUCCESS An instance of REPUBLISH_SEC_PPI_PPI was installed successfully.
I think "@retval" should be used in front of every single return value,
that is, EFI_SUCCESS as well.
But, please do not resubmit the series just because of this remark; it's
not important enough.
If you need to post a v6 for another reason, then please consider adding
the "@retval" word here.
My Acked-by stands with or without "@retval".
Thanks!
Laszlo
> + @retval Others An error occurred installing and instance of REPUBLISH_SEC_PPI_PPI.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SecMigrationPeiInitialize (
> + IN EFI_PEI_FILE_HANDLE FileHandle,
> + IN CONST EFI_PEI_SERVICES **PeiServices
> + )
> +{
> + EFI_STATUS Status;
> +
> + Status = EFI_ABORTED;
> +
> + if (PcdGetBool (PcdMigrateTemporaryRamFirmwareVolumes)) {
> + Status = PeiServicesInstallPpi (&mEdkiiRepublishSecPpiDescriptor);
> + ASSERT_EFI_ERROR (Status);
> + }
> +
> + return Status;
> +}
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [edk2-devel] [PATCH v5 4/9] UefiCpuPkg/SecMigrationPei: Add initial PEIM (CVE-2019-11098)
2020-07-09 1:56 ` [PATCH v5 4/9] UefiCpuPkg/SecMigrationPei: Add initial PEIM (CVE-2019-11098) Guomin Jiang
2020-07-09 11:01 ` [edk2-devel] " Laszlo Ersek
@ 2020-07-13 6:56 ` Wang, Jian J
1 sibling, 0 replies; 24+ messages in thread
From: Wang, Jian J @ 2020-07-13 6:56 UTC (permalink / raw)
To: devel@edk2.groups.io, Jiang, Guomin
Cc: Michael Kubacki, Dong, Eric, Ni, Ray, Laszlo Ersek, Kumar, Rahul1,
De, Debkumar, Han, Harry, West, Catharine
Guomin,
Just one minor comment below.
Regards,
Jian
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Guomin
> Jiang
> Sent: Thursday, July 09, 2020 9:57 AM
> To: devel@edk2.groups.io
> Cc: Michael Kubacki <michael.a.kubacki@intel.com>; Dong, Eric
> <eric.dong@intel.com>; Ni, Ray <ray.ni@intel.com>; Laszlo Ersek
> <lersek@redhat.com>; Kumar, Rahul1 <rahul1.kumar@intel.com>; De,
> Debkumar <debkumar.de@intel.com>; Han, Harry <harry.han@intel.com>;
> West, Catharine <catharine.west@intel.com>
> Subject: [edk2-devel] [PATCH v5 4/9] UefiCpuPkg/SecMigrationPei: Add initial
> PEIM (CVE-2019-11098)
>
> From: Michael Kubacki <michael.a.kubacki@intel.com>
>
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=1614
>
> Adds a PEIM that republishes structures produced in SEC. This
> is done because SEC modules may not be shadowed in some platforms
> due to space constraints or special alignment requirements. The
> SecMigrationPei module locates interfaces that may be published in
> SEC and reinstalls the interface with permanent memory addresses.
>
> This is important if pre-memory address access is forbidden after
> memory initialization and data such as a PPI descriptor, PPI GUID,
> or PPI inteface reside in pre-memory.
>
> Cc: Eric Dong <eric.dong@intel.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Rahul Kumar <rahul1.kumar@intel.com>
> Cc: Debkumar De <debkumar.de@intel.com>
> Cc: Harry Han <harry.han@intel.com>
> Cc: Catharine West <catharine.west@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> Acked-by: Laszlo Ersek <lersek@redhat.com>
> ---
> UefiCpuPkg/UefiCpuPkg.dec | 4 +
> UefiCpuPkg/UefiCpuPkg.dsc | 1 +
> UefiCpuPkg/SecCore/SecCore.inf | 2 +
> .../SecMigrationPei/SecMigrationPei.inf | 67 +++
> UefiCpuPkg/Include/Ppi/RepublishSecPpi.h | 54 +++
> UefiCpuPkg/SecCore/SecMain.h | 1 +
> UefiCpuPkg/SecMigrationPei/SecMigrationPei.h | 154 +++++++
> UefiCpuPkg/SecCore/SecMain.c | 26 +-
> UefiCpuPkg/SecMigrationPei/SecMigrationPei.c | 381 ++++++++++++++++++
> .../SecMigrationPei/SecMigrationPei.uni | 13 +
> 10 files changed, 701 insertions(+), 2 deletions(-)
> create mode 100644 UefiCpuPkg/SecMigrationPei/SecMigrationPei.inf
> create mode 100644 UefiCpuPkg/Include/Ppi/RepublishSecPpi.h
> create mode 100644 UefiCpuPkg/SecMigrationPei/SecMigrationPei.h
> create mode 100644 UefiCpuPkg/SecMigrationPei/SecMigrationPei.c
> create mode 100644 UefiCpuPkg/SecMigrationPei/SecMigrationPei.uni
>
> diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec
> index 762badf5d239..0a005bd20311 100644
> --- a/UefiCpuPkg/UefiCpuPkg.dec
> +++ b/UefiCpuPkg/UefiCpuPkg.dec
> @@ -66,6 +66,10 @@ [Guids]
> ## Include/Guid/MicrocodePatchHob.h
> gEdkiiMicrocodePatchHobGuid = { 0xd178f11d, 0x8716, 0x418e, { 0xa1, 0x31,
> 0x96, 0x7d, 0x2a, 0xc4, 0x28, 0x43 }}
>
> +[Ppis]
> + ## Include/Ppi/RepublishSecPpi.h
> + gRepublishSecPpiPpiGuid = { 0x27a71b1e, 0x73ee, 0x43d6, { 0xac, 0xe3, 0x52,
> 0x1a, 0x2d, 0xc5, 0xd0, 0x92 }}
> +
Instead of adding a new [Ppis] section, you can add this PPI definition in the [Ppis]
section already defined below.
> [Protocols]
> ## Include/Protocol/SmmCpuService.h
> gEfiSmmCpuServiceProtocolGuid = { 0x1d202cab, 0xc8ab, 0x4d5c, { 0x94, 0xf7,
> 0x3c, 0xfc, 0xc0, 0xd3, 0xd3, 0x35 }}
> diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc
> index afa304128221..964720048dd7 100644
> --- a/UefiCpuPkg/UefiCpuPkg.dsc
> +++ b/UefiCpuPkg/UefiCpuPkg.dsc
> @@ -146,6 +146,7 @@ [Components.IA32, Components.X64]
> UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf
> UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf
> UefiCpuPkg/SecCore/SecCore.inf
> + UefiCpuPkg/SecMigrationPei/SecMigrationPei.inf
> UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
> UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf {
> <Defines>
> diff --git a/UefiCpuPkg/SecCore/SecCore.inf b/UefiCpuPkg/SecCore/SecCore.inf
> index 0562820c95e0..545781d6b4b3 100644
> --- a/UefiCpuPkg/SecCore/SecCore.inf
> +++ b/UefiCpuPkg/SecCore/SecCore.inf
> @@ -68,6 +68,8 @@ [Ppis]
> ## SOMETIMES_CONSUMES
> gPeiSecPerformancePpiGuid
> gEfiPeiCoreFvLocationPpiGuid
> + ## CONSUMES
> + gRepublishSecPpiPpiGuid
>
> [Guids]
> ## SOMETIMES_PRODUCES ## HOB
> diff --git a/UefiCpuPkg/SecMigrationPei/SecMigrationPei.inf
> b/UefiCpuPkg/SecMigrationPei/SecMigrationPei.inf
> new file mode 100644
> index 000000000000..f4c2f6b658fb
> --- /dev/null
> +++ b/UefiCpuPkg/SecMigrationPei/SecMigrationPei.inf
> @@ -0,0 +1,67 @@
> +## @file
> +# Migrates SEC structures after permanent memory is installed.
> +#
> +# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = SecMigrationPei
> + MODULE_UNI_FILE = SecMigrationPei.uni
> + FILE_GUID = 58B35361-8922-41BC-B313-EF7ED9ADFDF7
> + MODULE_TYPE = PEIM
> + VERSION_STRING = 1.0
> + ENTRY_POINT = SecMigrationPeiInitialize
> +
> +#
> +# The following information is for reference only and not required by the build
> tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64 EBC
> +#
> +
> +[Sources]
> + SecMigrationPei.c
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + MdeModulePkg/MdeModulePkg.dec
> + UefiCpuPkg/UefiCpuPkg.dec
> +
> +[LibraryClasses]
> + BaseLib
> + BaseMemoryLib
> + DebugLib
> + HobLib
> + MemoryAllocationLib
> + PeimEntryPoint
> + PeiServicesLib
> + PeiServicesTablePointerLib
> +
> +[Ppis]
> + ## PRODUCES
> + gRepublishSecPpiPpiGuid
> +
> + ## SOMETIMES_PRODUCES
> + gEfiTemporaryRamDonePpiGuid
> +
> + ## SOMETIME_PRODUCES
> + gEfiTemporaryRamSupportPpiGuid
> +
> + ## SOMETIMES_PRODUCES
> + gPeiSecPerformancePpiGuid
> +
> + ## SOMETIMES_CONSUMES
> + ## PRODUCES
> + gEfiSecPlatformInformationPpiGuid
> +
> + ## SOMETIMES_CONSUMES
> + ## SOMETIMES_PRODUCES
> + gEfiSecPlatformInformation2PpiGuid
> +
> +[Pcd]
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdMigrateTemporaryRamFirmwareVolum
> es ## CONSUMES
> +
> +[Depex]
> + TRUE
> diff --git a/UefiCpuPkg/Include/Ppi/RepublishSecPpi.h
> b/UefiCpuPkg/Include/Ppi/RepublishSecPpi.h
> new file mode 100644
> index 000000000000..ea865acbb5c8
> --- /dev/null
> +++ b/UefiCpuPkg/Include/Ppi/RepublishSecPpi.h
> @@ -0,0 +1,54 @@
> +/** @file
> + This file declares Sec Platform Information PPI.
> +
> + This service is the primary handoff state into the PEI Foundation.
> + The Security (SEC) component creates the early, transitory memory
> + environment and also encapsulates knowledge of at least the
> + location of the Boot Firmware Volume (BFV).
> +
> + Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> + @par Revision Reference:
> + This PPI is introduced in PI Version 1.0.
> +
> +**/
> +
> +#ifndef __REPUBLISH_SEC_PPI_H__
> +#define __REPUBLISH_SEC_PPI_H__
> +
> +#include <Pi/PiPeiCis.h>
> +
> +#define REPUBLISH_SEC_PPI_PPI_GUID \
> + { \
> + 0x27a71b1e, 0x73ee, 0x43d6, { 0xac, 0xe3, 0x52, 0x1a, 0x2d, 0xc5, 0xd0,
> 0x92 } \
> + }
> +
> +typedef struct _REPUBLISH_SEC_PPI_PPI REPUBLISH_SEC_PPI_PPI;
> +
> +/**
> + This interface re-installs PPIs installed in SecCore from a post-memory PEIM.
> +
> + This is to allow a platform that may not support relocation of SecCore to
> update the PPI instance to a post-memory
> + copy from a PEIM that has been shadowed to permanent memory.
> +
> + @retval EFI_SUCCESS The SecCore PPIs were re-installed successfully.
> + @retval Others An error occurred re-installing the SecCore PPIs.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *REPUBLISH_SEC_PPI_REPUBLISH_SEC_PPIS)(
> + VOID
> + );
> +
> +///
> +/// Republish SEC PPIs
> +///
> +struct _REPUBLISH_SEC_PPI_PPI {
> + REPUBLISH_SEC_PPI_REPUBLISH_SEC_PPIS RepublishSecPpis;
> +};
> +
> +extern EFI_GUID gRepublishSecPpiPpiGuid;
> +
> +#endif
> diff --git a/UefiCpuPkg/SecCore/SecMain.h b/UefiCpuPkg/SecCore/SecMain.h
> index e8c05d713668..e20bcf86532c 100644
> --- a/UefiCpuPkg/SecCore/SecMain.h
> +++ b/UefiCpuPkg/SecCore/SecMain.h
> @@ -15,6 +15,7 @@
> #include <Ppi/TemporaryRamDone.h>
> #include <Ppi/SecPerformance.h>
> #include <Ppi/PeiCoreFvLocation.h>
> +#include <Ppi/RepublishSecPpi.h>
>
> #include <Guid/FirmwarePerformance.h>
>
> diff --git a/UefiCpuPkg/SecMigrationPei/SecMigrationPei.h
> b/UefiCpuPkg/SecMigrationPei/SecMigrationPei.h
> new file mode 100644
> index 000000000000..414672a5afe6
> --- /dev/null
> +++ b/UefiCpuPkg/SecMigrationPei/SecMigrationPei.h
> @@ -0,0 +1,154 @@
> +/** @file
> + Migrates SEC structures after permanent memory is installed.
> +
> + Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef __SEC_MIGRATION_H__
> +#define __SEC_MIGRATION_H__
> +
> +#include <Base.h>
> +
> +#include <Pi/PiPeiCis.h>
> +#include <Ppi/RepublishSecPpi.h>
> +#include <Ppi/SecPerformance.h>
> +#include <Ppi/SecPlatformInformation.h>
> +#include <Ppi/SecPlatformInformation2.h>
> +#include <Ppi/TemporaryRamDone.h>
> +#include <Ppi/TemporaryRamSupport.h>
> +
> +/**
> + This interface conveys state information out of the Security (SEC) phase into
> PEI.
> +
> + @param[in] PeiServices Pointer to the PEI Services Table.
> + @param[in,out] StructureSize Pointer to the variable describing size of
> the input buffer.
> + @param[out] PlatformInformationRecord Pointer to the
> EFI_SEC_PLATFORM_INFORMATION_RECORD.
> +
> + @retval EFI_SUCCESS The data was successfully returned.
> + @retval EFI_BUFFER_TOO_SMALL The buffer was too small.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SecPlatformInformationPostMemory (
> + IN CONST EFI_PEI_SERVICES **PeiServices,
> + IN OUT UINT64 *StructureSize,
> + OUT EFI_SEC_PLATFORM_INFORMATION_RECORD
> *PlatformInformationRecord
> + );
> +
> +/**
> + Re-installs the SEC Platform Information PPIs to implementation in this
> module to support post-memory.
> +
> + @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table
> published by the PEI Foundation.
> + @param[in] NotifyDescriptor Address of the notification descriptor data
> structure.
> + @param[in] Ppi Address of the PPI that was installed.
> +
> + @retval EFI_SUCCESS The SEC Platform Information PPI could not be re-
> installed.
> + @return Others An error occurred during PPI re-install.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SecPlatformInformationPpiNotifyCallback (
> + IN EFI_PEI_SERVICES **PeiServices,
> + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
> + IN VOID *Ppi
> + );
> +
> +/**
> + This interface re-installs PPIs installed in SecCore from a post-memory PEIM.
> +
> + This is to allow a platform that may not support relocation of SecCore to
> update the PPI instance to a post-memory
> + copy from a PEIM that has been shadowed to permanent memory.
> +
> + @retval EFI_SUCCESS The SecCore PPIs were re-installed successfully.
> + @retval Others An error occurred re-installing the SecCore PPIs.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RepublishSecPpis (
> + VOID
> + );
> +
> +/**
> + Disables the use of Temporary RAM.
> +
> + If present, this service is invoked by the PEI Foundation after
> + the EFI_PEI_PERMANANT_MEMORY_INSTALLED_PPI is installed.
> +
> + @retval EFI_SUCCESS Use of Temporary RAM was disabled.
> + @retval EFI_INVALID_PARAMETER Temporary RAM could not be disabled.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SecTemporaryRamDonePostMemory (
> + VOID
> + );
> +
> +/**
> + This service of the EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI that migrates
> temporary RAM into
> + permanent memory.
> +
> + @param PeiServices Pointer to the PEI Services Table.
> + @param TemporaryMemoryBase Source Address in temporary memory
> from which the SEC or PEIM will copy the
> + Temporary RAM contents.
> + @param PermanentMemoryBase Destination Address in permanent memory
> into which the SEC or PEIM will copy the
> + Temporary RAM contents.
> + @param CopySize Amount of memory to migrate from temporary to
> permanent memory.
> +
> + @retval EFI_SUCCESS The data was successfully returned.
> + @retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize >
> TemporaryMemoryBase when
> + TemporaryMemoryBase > PermanentMemoryBase.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SecTemporaryRamSupportPostMemory (
> + IN CONST EFI_PEI_SERVICES **PeiServices,
> + IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
> + IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
> + IN UINTN CopySize
> + );
> +
> +/**
> + This interface conveys performance information out of the Security (SEC)
> phase into PEI.
> +
> + This service is published by the SEC phase. The SEC phase handoff has an
> optional
> + EFI_PEI_PPI_DESCRIPTOR list as its final argument when control is passed
> from SEC into the
> + PEI Foundation. As such, if the platform supports collecting performance data
> in SEC,
> + this information is encapsulated into the data structure abstracted by this
> service.
> + This information is collected for the boot-strap processor (BSP) on IA-32.
> +
> + @param[in] PeiServices The pointer to the PEI Services Table.
> + @param[in] This The pointer to this instance of the
> PEI_SEC_PERFORMANCE_PPI.
> + @param[out] Performance The pointer to performance data collected in SEC
> phase.
> +
> + @retval EFI_SUCCESS The performance data was successfully returned.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetPerformancePostMemory (
> + IN CONST EFI_PEI_SERVICES **PeiServices,
> + IN PEI_SEC_PERFORMANCE_PPI *This,
> + OUT FIRMWARE_SEC_PERFORMANCE *Performance
> + );
> +
> +typedef struct {
> + UINT64 StructureSize;
> + EFI_SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord;
> +} SEC_PLATFORM_INFORMATION_CONTEXT;
> +
> +typedef struct {
> + EFI_HOB_GUID_TYPE Header;
> + UINT8 Revision;
> + UINT8 Reserved[3];
> + FIRMWARE_SEC_PERFORMANCE FirmwareSecPerformance;
> + SEC_PLATFORM_INFORMATION_CONTEXT Context;
> +} SEC_PLATFORM_INFORMATION_CONTEXT_HOB;
> +
> +#endif
> diff --git a/UefiCpuPkg/SecCore/SecMain.c b/UefiCpuPkg/SecCore/SecMain.c
> index 5d5e7f17dced..155be49a6011 100644
> --- a/UefiCpuPkg/SecCore/SecMain.c
> +++ b/UefiCpuPkg/SecCore/SecMain.c
> @@ -370,13 +370,35 @@ SecTemporaryRamDone (
> VOID
> )
> {
> - BOOLEAN State;
> + EFI_STATUS Status;
> + EFI_STATUS Status2;
> + UINTN Index;
> + BOOLEAN State;
> + EFI_PEI_PPI_DESCRIPTOR *PeiPpiDescriptor;
> + REPUBLISH_SEC_PPI_PPI *RepublishSecPpiPpi;
>
> //
> // Republish Sec Platform Information(2) PPI
> //
> RepublishSecPlatformInformationPpi ();
>
> + //
> + // Re-install SEC PPIs using a PEIM produced service if published
> + //
> + for (Index = 0, Status = EFI_SUCCESS; Status == EFI_SUCCESS; Index++) {
> + Status = PeiServicesLocatePpi (
> + &gRepublishSecPpiPpiGuid,
> + Index,
> + &PeiPpiDescriptor,
> + (VOID **) &RepublishSecPpiPpi
> + );
> + if (!EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_INFO, "Calling RepublishSecPpi instance %d.\n", Index));
> + Status2 = RepublishSecPpiPpi->RepublishSecPpis ();
> + ASSERT_EFI_ERROR (Status2);
> + }
> + }
> +
> //
> // Migrate DebugAgentContext.
> //
> @@ -385,7 +407,7 @@ SecTemporaryRamDone (
> //
> // Disable interrupts and save current interrupt state
> //
> - State = SaveAndDisableInterrupts();
> + State = SaveAndDisableInterrupts ();
>
> //
> // Disable Temporary RAM after Stack and Heap have been migrated at this
> point.
> diff --git a/UefiCpuPkg/SecMigrationPei/SecMigrationPei.c
> b/UefiCpuPkg/SecMigrationPei/SecMigrationPei.c
> new file mode 100644
> index 000000000000..a62d50bcbb0d
> --- /dev/null
> +++ b/UefiCpuPkg/SecMigrationPei/SecMigrationPei.c
> @@ -0,0 +1,381 @@
> +/** @file
> + Migrates SEC structures after permanent memory is installed.
> +
> + Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Base.h>
> +
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/PeiServicesTablePointerLib.h>
> +
> +#include "SecMigrationPei.h"
> +
> +STATIC REPUBLISH_SEC_PPI_PPI mEdkiiRepublishSecPpiPpi = {
> + RepublishSecPpis
> + };
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED
> EFI_SEC_PLATFORM_INFORMATION_PPI
> mSecPlatformInformationPostMemoryPpi = {
> + SecPlatformInformationPostMemory
> + };
> +
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_PEI_TEMPORARY_RAM_DONE_PPI
> mSecTemporaryRamDonePostMemoryPpi = {
> + SecTemporaryRamDonePostMemory
> + };
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED
> EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI
> mSecTemporaryRamSupportPostMemoryPpi = {
> + SecTemporaryRamSupportPostMemory
> + };
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED PEI_SEC_PERFORMANCE_PPI
> mSecPerformancePpi = {
> + GetPerformancePostMemory
> + };
> +
> +STATIC EFI_PEI_PPI_DESCRIPTOR mEdkiiRepublishSecPpiDescriptor = {
> + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
> + &gRepublishSecPpiPpiGuid,
> + &mEdkiiRepublishSecPpiPpi
> + };
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_PEI_PPI_DESCRIPTOR
> mSecPlatformInformationPostMemoryDescriptor = {
> + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
> + &gEfiSecPlatformInformationPpiGuid,
> + &mSecPlatformInformationPostMemoryPpi
> + };
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_PEI_PPI_DESCRIPTOR
> mSecTemporaryRamDonePostMemoryDescriptor = {
> + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
> + &gEfiTemporaryRamDonePpiGuid,
> + &mSecTemporaryRamDonePostMemoryPpi
> + };
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_PEI_PPI_DESCRIPTOR
> mSecTemporaryRamSupportPostMemoryDescriptor = {
> + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
> + &gEfiTemporaryRamSupportPpiGuid,
> + &mSecTemporaryRamSupportPostMemoryPpi
> + };
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_PEI_PPI_DESCRIPTOR
> mSecPerformancePpiDescriptor = {
> + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
> + &gPeiSecPerformancePpiGuid,
> + &mSecPerformancePpi
> + };
> +
> +/**
> + Disables the use of Temporary RAM.
> +
> + If present, this service is invoked by the PEI Foundation after
> + the EFI_PEI_PERMANANT_MEMORY_INSTALLED_PPI is installed.
> +
> + @retval EFI_SUCCESS Use of Temporary RAM was disabled.
> + @retval EFI_INVALID_PARAMETER Temporary RAM could not be disabled.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SecTemporaryRamDonePostMemory (
> + VOID
> + )
> +{
> + //
> + // Temporary RAM Done is already done in post-memory
> + // install a stub function that is located in permanent memory
> + //
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + This service of the EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI that migrates
> temporary RAM into
> + permanent memory.
> +
> + @param PeiServices Pointer to the PEI Services Table.
> + @param TemporaryMemoryBase Source Address in temporary memory
> from which the SEC or PEIM will copy the
> + Temporary RAM contents.
> + @param PermanentMemoryBase Destination Address in permanent memory
> into which the SEC or PEIM will copy the
> + Temporary RAM contents.
> + @param CopySize Amount of memory to migrate from temporary to
> permanent memory.
> +
> + @retval EFI_SUCCESS The data was successfully returned.
> + @retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize >
> TemporaryMemoryBase when
> + TemporaryMemoryBase > PermanentMemoryBase.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SecTemporaryRamSupportPostMemory (
> + IN CONST EFI_PEI_SERVICES **PeiServices,
> + IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
> + IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
> + IN UINTN CopySize
> + )
> +{
> + //
> + // Temporary RAM Support is already done in post-memory
> + // install a stub function that is located in permanent memory
> + //
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + This interface conveys performance information out of the Security (SEC)
> phase into PEI.
> +
> + This service is published by the SEC phase. The SEC phase handoff has an
> optional
> + EFI_PEI_PPI_DESCRIPTOR list as its final argument when control is passed
> from SEC into the
> + PEI Foundation. As such, if the platform supports collecting performance data
> in SEC,
> + this information is encapsulated into the data structure abstracted by this
> service.
> + This information is collected for the boot-strap processor (BSP) on IA-32.
> +
> + @param[in] PeiServices The pointer to the PEI Services Table.
> + @param[in] This The pointer to this instance of the
> PEI_SEC_PERFORMANCE_PPI.
> + @param[out] Performance The pointer to performance data collected in SEC
> phase.
> +
> + @retval EFI_SUCCESS The performance data was successfully returned.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetPerformancePostMemory (
> + IN CONST EFI_PEI_SERVICES **PeiServices,
> + IN PEI_SEC_PERFORMANCE_PPI *This,
> + OUT FIRMWARE_SEC_PERFORMANCE *Performance
> + )
> +{
> + SEC_PLATFORM_INFORMATION_CONTEXT_HOB
> *SecPlatformInformationContexHob;
> +
> + if (This == NULL || Performance == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + SecPlatformInformationContexHob = GetFirstGuidHob (&gEfiCallerIdGuid);
> + if (SecPlatformInformationContexHob == NULL) {
> + return EFI_NOT_FOUND;
> + }
> +
> + Performance->ResetEnd = SecPlatformInformationContexHob-
> >FirmwareSecPerformance.ResetEnd;
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + This interface conveys state information out of the Security (SEC) phase into
> PEI.
> +
> + @param[in] PeiServices Pointer to the PEI Services Table.
> + @param[in,out] StructureSize Pointer to the variable describing size of
> the input buffer.
> + @param[out] PlatformInformationRecord Pointer to the
> EFI_SEC_PLATFORM_INFORMATION_RECORD.
> +
> + @retval EFI_SUCCESS The data was successfully returned.
> + @retval EFI_BUFFER_TOO_SMALL The buffer was too small.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SecPlatformInformationPostMemory (
> + IN CONST EFI_PEI_SERVICES **PeiServices,
> + IN OUT UINT64 *StructureSize,
> + OUT EFI_SEC_PLATFORM_INFORMATION_RECORD
> *PlatformInformationRecord
> + )
> +{
> + SEC_PLATFORM_INFORMATION_CONTEXT_HOB
> *SecPlatformInformationContexHob;
> +
> + if (StructureSize == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + SecPlatformInformationContexHob = GetFirstGuidHob (&gEfiCallerIdGuid);
> + if (SecPlatformInformationContexHob == NULL) {
> + return EFI_NOT_FOUND;
> + }
> +
> + if (*StructureSize < SecPlatformInformationContexHob-
> >Context.StructureSize) {
> + *StructureSize = SecPlatformInformationContexHob->Context.StructureSize;
> + return EFI_BUFFER_TOO_SMALL;
> + }
> +
> + if (PlatformInformationRecord == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + *StructureSize = SecPlatformInformationContexHob->Context.StructureSize;
> + CopyMem (
> + (VOID *) PlatformInformationRecord,
> + (VOID *) SecPlatformInformationContexHob-
> >Context.PlatformInformationRecord,
> + (UINTN) SecPlatformInformationContexHob->Context.StructureSize
> + );
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + This interface re-installs PPIs installed in SecCore from a post-memory PEIM.
> +
> + This is to allow a platform that may not support relocation of SecCore to
> update the PPI instance to a post-memory
> + copy from a PEIM that has been shadowed to permanent memory.
> +
> + @retval EFI_SUCCESS The SecCore PPIs were re-installed successfully.
> + @retval Others An error occurred re-installing the SecCore PPIs.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RepublishSecPpis (
> + VOID
> + )
> +{
> + EFI_STATUS Status;
> + EFI_PEI_PPI_DESCRIPTOR *PeiPpiDescriptor;
> + VOID *PeiPpi;
> + SEC_PLATFORM_INFORMATION_CONTEXT_HOB
> *SecPlatformInformationContextHob;
> + EFI_SEC_PLATFORM_INFORMATION_RECORD *SecPlatformInformationPtr;
> + UINT64 SecStructureSize;
> +
> + SecPlatformInformationPtr = NULL;
> + SecStructureSize = 0;
> +
> + Status = PeiServicesLocatePpi (
> + &gEfiTemporaryRamDonePpiGuid,
> + 0,
> + &PeiPpiDescriptor,
> + (VOID **) &PeiPpi
> + );
> + if (!EFI_ERROR (Status)) {
> + Status = PeiServicesReInstallPpi (
> + PeiPpiDescriptor,
> + &mSecTemporaryRamDonePostMemoryDescriptor
> + );
> + ASSERT_EFI_ERROR (Status);
> + }
> +
> + Status = PeiServicesLocatePpi (
> + &gEfiTemporaryRamSupportPpiGuid,
> + 0,
> + &PeiPpiDescriptor,
> + (VOID **) &PeiPpi
> + );
> + if (!EFI_ERROR (Status)) {
> + Status = PeiServicesReInstallPpi (
> + PeiPpiDescriptor,
> + &mSecTemporaryRamSupportPostMemoryDescriptor
> + );
> + ASSERT_EFI_ERROR (Status);
> + }
> +
> + Status = PeiServicesCreateHob (
> + EFI_HOB_TYPE_GUID_EXTENSION,
> + sizeof (SEC_PLATFORM_INFORMATION_CONTEXT_HOB),
> + (VOID **) &SecPlatformInformationContextHob
> + );
> + ASSERT_EFI_ERROR (Status);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "SecPlatformInformation Context HOB could not
> be created.\n"));
> + return Status;
> + }
> +
> + SecPlatformInformationContextHob->Header.Name = gEfiCallerIdGuid;
> + SecPlatformInformationContextHob->Revision = 1;
> +
> + Status = PeiServicesLocatePpi (
> + &gPeiSecPerformancePpiGuid,
> + 0,
> + &PeiPpiDescriptor,
> + (VOID **) &PeiPpi
> + );
> + if (!EFI_ERROR (Status)) {
> + Status = ((PEI_SEC_PERFORMANCE_PPI *) PeiPpi)->GetPerformance (
> + GetPeiServicesTablePointer (),
> + (PEI_SEC_PERFORMANCE_PPI *) PeiPpi,
> + &SecPlatformInformationContextHob-
> >FirmwareSecPerformance
> + );
> + ASSERT_EFI_ERROR (Status);
> + if (!EFI_ERROR (Status)) {
> + Status = PeiServicesReInstallPpi (
> + PeiPpiDescriptor,
> + &mSecPerformancePpiDescriptor
> + );
> + ASSERT_EFI_ERROR (Status);
> + }
> + }
> +
> + Status = PeiServicesLocatePpi (
> + &gEfiSecPlatformInformationPpiGuid,
> + 0,
> + &PeiPpiDescriptor,
> + (VOID **) &PeiPpi
> + );
> + if (!EFI_ERROR (Status)) {
> + Status = ((EFI_SEC_PLATFORM_INFORMATION_PPI *) PeiPpi)-
> >PlatformInformation (
> + GetPeiServicesTablePointer (),
> + &SecStructureSize,
> + SecPlatformInformationPtr
> + );
> + ASSERT (Status == EFI_BUFFER_TOO_SMALL);
> + if (Status != EFI_BUFFER_TOO_SMALL) {
> + return EFI_NOT_FOUND;
> + }
> +
> + ZeroMem ((VOID *) &(SecPlatformInformationContextHob->Context), sizeof
> (SEC_PLATFORM_INFORMATION_CONTEXT));
> + SecPlatformInformationContextHob->Context.PlatformInformationRecord =
> AllocatePool ((UINTN) SecStructureSize);
> + ASSERT (SecPlatformInformationContextHob-
> >Context.PlatformInformationRecord != NULL);
> + if (SecPlatformInformationContextHob-
> >Context.PlatformInformationRecord == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> + SecPlatformInformationContextHob->Context.StructureSize =
> SecStructureSize;
> +
> + Status = ((EFI_SEC_PLATFORM_INFORMATION_PPI *) PeiPpi)-
> >PlatformInformation (
> + GetPeiServicesTablePointer (),
> + &(SecPlatformInformationContextHob-
> >Context.StructureSize),
> + SecPlatformInformationContextHob-
> >Context.PlatformInformationRecord
> + );
> + ASSERT_EFI_ERROR (Status);
> + if (!EFI_ERROR (Status)) {
> + Status = PeiServicesReInstallPpi (
> + PeiPpiDescriptor,
> + &mSecPlatformInformationPostMemoryDescriptor
> + );
> + ASSERT_EFI_ERROR (Status);
> + }
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + This function is the entry point which installs an instance of
> REPUBLISH_SEC_PPI_PPI.
> +
> + It install the RepublishSecPpi depent on
> PcdMigrateTemporaryRamFirmwareVolumes, install
> + the PPI when the PcdMigrateTemporaryRamFirmwareVolumes enabled.
> +
> + @param[in] FileHandle Pointer to image file handle.
> + @param[in] PeiServices Pointer to PEI Services Table
> +
> + @retval EFI_ABORTED Disable evacuate temporary memory feature by
> disable
> + PcdMigrateTemporaryRamFirmwareVolumes.
> + EFI_SUCCESS An instance of REPUBLISH_SEC_PPI_PPI was installed
> successfully.
> + @retval Others An error occurred installing and instance of
> REPUBLISH_SEC_PPI_PPI.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SecMigrationPeiInitialize (
> + IN EFI_PEI_FILE_HANDLE FileHandle,
> + IN CONST EFI_PEI_SERVICES **PeiServices
> + )
> +{
> + EFI_STATUS Status;
> +
> + Status = EFI_ABORTED;
> +
> + if (PcdGetBool (PcdMigrateTemporaryRamFirmwareVolumes)) {
> + Status = PeiServicesInstallPpi (&mEdkiiRepublishSecPpiDescriptor);
> + ASSERT_EFI_ERROR (Status);
> + }
> +
> + return Status;
> +}
> diff --git a/UefiCpuPkg/SecMigrationPei/SecMigrationPei.uni
> b/UefiCpuPkg/SecMigrationPei/SecMigrationPei.uni
> new file mode 100644
> index 000000000000..62c2064ba217
> --- /dev/null
> +++ b/UefiCpuPkg/SecMigrationPei/SecMigrationPei.uni
> @@ -0,0 +1,13 @@
> +// /** @file
> +// Migrates SEC structures after permanent memory is installed.
> +//
> +// Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +// **/
> +
> +
> +#string STR_MODULE_ABSTRACT #language en-US "Migrates SEC structures
> after permanent memory is installed"
> +
> +#string STR_MODULE_DESCRIPTION #language en-US "Migrates SEC
> structures after permanent memory is installed."
> +
> --
> 2.25.1.windows.1
>
>
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v5 5/9] MdeModulePkg/Core: Create Migrated FV Info Hob for calculating hash (CVE-2019-11098)
2020-07-09 1:56 [PATCH v5 0/9] Add new feature that evacuate temporary to permanent memory (CVE-2019-11098) Guomin Jiang
` (3 preceding siblings ...)
2020-07-09 1:56 ` [PATCH v5 4/9] UefiCpuPkg/SecMigrationPei: Add initial PEIM (CVE-2019-11098) Guomin Jiang
@ 2020-07-09 1:56 ` Guomin Jiang
2020-07-13 7:05 ` Wang, Jian J
2020-07-09 1:56 ` [PATCH v5 6/9] SecurityPkg/Tcg2Pei: Use " Guomin Jiang
` (4 subsequent siblings)
9 siblings, 1 reply; 24+ messages in thread
From: Guomin Jiang @ 2020-07-09 1:56 UTC (permalink / raw)
To: devel
Cc: Jian J Wang, Hao A Wu, Dandan Bi, Liming Gao, Debkumar De,
Harry Han, Catharine West, Laszlo Ersek
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=1614
When we allocate pool to save the rebased PEIMs, the address will change
randomly, therefore the hash will change and result PCR0 change as well.
To avoid this, we save the raw PEIMs and use it to calculate hash.
The MigratedFvInfo HOB will never produce when
PcdMigrateTemporaryRamFirmwareVolumes is FALSE, because the PCD control
the total feature.
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Hao A Wu <hao.a.wu@intel.com>
Cc: Dandan Bi <dandan.bi@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Debkumar De <debkumar.de@intel.com>
Cc: Harry Han <harry.han@intel.com>
Cc: Catharine West <catharine.west@intel.com>
Signed-off-by: Guomin Jiang <guomin.jiang@intel.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
---
MdeModulePkg/MdeModulePkg.dec | 3 ++
MdeModulePkg/Core/Pei/PeiMain.inf | 1 +
MdeModulePkg/Core/Pei/PeiMain.h | 1 +
MdeModulePkg/Include/Guid/MigratedFvInfo.h | 22 +++++++++++++++
MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c | 28 +++++++++++++++++++
5 files changed, 55 insertions(+)
create mode 100644 MdeModulePkg/Include/Guid/MigratedFvInfo.h
diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
index 16db17d0a873..40197dba862c 100644
--- a/MdeModulePkg/MdeModulePkg.dec
+++ b/MdeModulePkg/MdeModulePkg.dec
@@ -389,6 +389,9 @@ [Guids]
## GUID indicates the capsule is to store Capsule On Disk file names.
gEdkiiCapsuleOnDiskNameGuid = { 0x98c80a4f, 0xe16b, 0x4d11, { 0x93, 0x9a, 0xab, 0xe5, 0x61, 0x26, 0x3, 0x30 } }
+ ## Include/Guid/MigratedFvInfo.h
+ gEdkiiMigratedFvInfoGuid = { 0xc1ab12f7, 0x74aa, 0x408d, { 0xa2, 0xf4, 0xc6, 0xce, 0xfd, 0x17, 0x98, 0x71 } }
+
[Ppis]
## Include/Ppi/AtaController.h
gPeiAtaControllerPpiGuid = { 0xa45e60d1, 0xc719, 0x44aa, { 0xb0, 0x7a, 0xaa, 0x77, 0x7f, 0x85, 0x90, 0x6d }}
diff --git a/MdeModulePkg/Core/Pei/PeiMain.inf b/MdeModulePkg/Core/Pei/PeiMain.inf
index 5b36d516b3fa..0cf357371a16 100644
--- a/MdeModulePkg/Core/Pei/PeiMain.inf
+++ b/MdeModulePkg/Core/Pei/PeiMain.inf
@@ -77,6 +77,7 @@ [Guids]
## CONSUMES ## GUID # Used to compare with FV's file system GUID and get the FV's file system format
gEfiFirmwareFileSystem3Guid
gStatusCodeCallbackGuid
+ gEdkiiMigratedFvInfoGuid ## SOMETIMES_PRODUCES ## HOB
[Ppis]
gEfiPeiStatusCodePpiGuid ## SOMETIMES_CONSUMES # PeiReportStatusService is not ready if this PPI doesn't exist
diff --git a/MdeModulePkg/Core/Pei/PeiMain.h b/MdeModulePkg/Core/Pei/PeiMain.h
index b0101dba5e30..cbf74d5b9d9a 100644
--- a/MdeModulePkg/Core/Pei/PeiMain.h
+++ b/MdeModulePkg/Core/Pei/PeiMain.h
@@ -44,6 +44,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Guid/FirmwareFileSystem2.h>
#include <Guid/FirmwareFileSystem3.h>
#include <Guid/AprioriFileName.h>
+#include <Guid/MigratedFvInfo.h>
///
/// It is an FFS type extension used for PeiFindFileEx. It indicates current
diff --git a/MdeModulePkg/Include/Guid/MigratedFvInfo.h b/MdeModulePkg/Include/Guid/MigratedFvInfo.h
new file mode 100644
index 000000000000..061c17ed0e48
--- /dev/null
+++ b/MdeModulePkg/Include/Guid/MigratedFvInfo.h
@@ -0,0 +1,22 @@
+/** @file
+ Migrated FV information
+
+Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __EDKII_MIGRATED_FV_INFO_GUID_H__
+#define __EDKII_MIGRATED_FV_INFO_GUID_H__
+
+typedef struct {
+ UINT32 FvOrgBase; // original FV address
+ UINT32 FvNewBase; // new FV address
+ UINT32 FvDataBase; // original FV data
+ UINT32 FvLength; // Fv Length
+} EDKII_MIGRATED_FV_INFO;
+
+extern EFI_GUID gEdkiiMigratedFvInfoGuid;
+
+#endif // #ifndef __EDKII_MIGRATED_FV_INFO_GUID_H__
+
diff --git a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
index ef88b3423376..f654cea15c59 100644
--- a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
+++ b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
@@ -1223,10 +1223,12 @@ EvacuateTempRam (
EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
EFI_FIRMWARE_VOLUME_HEADER *ChildFvHeader;
EFI_FIRMWARE_VOLUME_HEADER *MigratedFvHeader;
+ EFI_FIRMWARE_VOLUME_HEADER *RawDataFvHeader;
EFI_FIRMWARE_VOLUME_HEADER *MigratedChildFvHeader;
PEI_CORE_FV_HANDLE PeiCoreFvHandle;
EFI_PEI_CORE_FV_LOCATION_PPI *PeiCoreFvLocationPpi;
+ EDKII_MIGRATED_FV_INFO MigratedFvInfo;
ASSERT (Private->PeiMemoryInstalled);
@@ -1263,6 +1265,9 @@ EvacuateTempRam (
(((EFI_PHYSICAL_ADDRESS)(UINTN) FvHeader + (FvHeader->FvLength - 1)) < Private->FreePhysicalMemoryTop)
)
) {
+ //
+ // Allocate page to save the rebased PEIMs, the PEIMs will get control later
+ //
Status = PeiServicesAllocatePages (
EfiBootServicesCode,
EFI_SIZE_TO_PAGES ((UINTN) FvHeader->FvLength),
@@ -1270,6 +1275,17 @@ EvacuateTempRam (
);
ASSERT_EFI_ERROR (Status);
+ //
+ // Allocate pool to save the raw PEIMs, it used to keep consistent context across
+ // multiple boot and PCR0 will keep same no matter if allocate random page address.
+ //
+ Status = PeiServicesAllocatePages (
+ EfiBootServicesCode,
+ EFI_SIZE_TO_PAGES ((UINTN) FvHeader->FvLength),
+ (EFI_PHYSICAL_ADDRESS *) &RawDataFvHeader
+ );
+ ASSERT_EFI_ERROR (Status);
+
DEBUG ((
DEBUG_VERBOSE,
" Migrating FV[%d] from 0x%08X to 0x%08X\n",
@@ -1278,7 +1294,19 @@ EvacuateTempRam (
(UINTN) MigratedFvHeader
));
+ //
+ // Copy the context to the rebased pages and raw pages, and create hob to save the
+ // information. the MigratedFvInfo HOB will never produce when
+ // PcdMigrateTemporaryRamFirmwareVolumes is FALSE, because the PCD control the
+ // feature.
+ //
CopyMem (MigratedFvHeader, FvHeader, (UINTN) FvHeader->FvLength);
+ CopyMem (RawDataFvHeader, MigratedFvHeader, (UINTN) FvHeader->FvLength);
+ MigratedFvInfo.FvOrgBase = (UINT32) (UINTN) FvHeader;
+ MigratedFvInfo.FvNewBase = (UINT32) (UINTN) MigratedFvHeader;
+ MigratedFvInfo.FvDataBase = (UINT32) (UINTN) RawDataFvHeader;
+ MigratedFvInfo.FvLength = (UINT32) (UINTN) FvHeader->FvLength;
+ BuildGuidDataHob (&gEdkiiMigratedFvInfoGuid, &MigratedFvInfo, sizeof (MigratedFvInfo));
//
// Migrate any children for this FV now
--
2.25.1.windows.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH v5 5/9] MdeModulePkg/Core: Create Migrated FV Info Hob for calculating hash (CVE-2019-11098)
2020-07-09 1:56 ` [PATCH v5 5/9] MdeModulePkg/Core: Create Migrated FV Info Hob for calculating hash (CVE-2019-11098) Guomin Jiang
@ 2020-07-13 7:05 ` Wang, Jian J
0 siblings, 0 replies; 24+ messages in thread
From: Wang, Jian J @ 2020-07-13 7:05 UTC (permalink / raw)
To: Jiang, Guomin, devel@edk2.groups.io
Cc: Wu, Hao A, Bi, Dandan, Gao, Liming, De, Debkumar, Han, Harry,
West, Catharine, Laszlo Ersek
Guomin,
Some typo or syntax issues below.
> -----Original Message-----
> From: Jiang, Guomin <guomin.jiang@intel.com>
> Sent: Thursday, July 09, 2020 9:57 AM
> To: devel@edk2.groups.io
> Cc: Wang, Jian J <jian.j.wang@intel.com>; Wu, Hao A <hao.a.wu@intel.com>;
> Bi, Dandan <dandan.bi@intel.com>; Gao, Liming <liming.gao@intel.com>; De,
> Debkumar <debkumar.de@intel.com>; Han, Harry <harry.han@intel.com>;
> West, Catharine <catharine.west@intel.com>; Laszlo Ersek <lersek@redhat.com>
> Subject: [PATCH v5 5/9] MdeModulePkg/Core: Create Migrated FV Info Hob for
> calculating hash (CVE-2019-11098)
>
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=1614
>
> When we allocate pool to save the rebased PEIMs, the address will change
> randomly, therefore the hash will change and result PCR0 change as well.
> To avoid this, we save the raw PEIMs and use it to calculate hash.
>
> The MigratedFvInfo HOB will never produce when
> PcdMigrateTemporaryRamFirmwareVolumes is FALSE, because the PCD control
> the total feature.
>
> Cc: Jian J Wang <jian.j.wang@intel.com>
> Cc: Hao A Wu <hao.a.wu@intel.com>
> Cc: Dandan Bi <dandan.bi@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Debkumar De <debkumar.de@intel.com>
> Cc: Harry Han <harry.han@intel.com>
> Cc: Catharine West <catharine.west@intel.com>
> Signed-off-by: Guomin Jiang <guomin.jiang@intel.com>
> Acked-by: Laszlo Ersek <lersek@redhat.com>
> ---
> MdeModulePkg/MdeModulePkg.dec | 3 ++
> MdeModulePkg/Core/Pei/PeiMain.inf | 1 +
> MdeModulePkg/Core/Pei/PeiMain.h | 1 +
> MdeModulePkg/Include/Guid/MigratedFvInfo.h | 22 +++++++++++++++
> MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c | 28 +++++++++++++++++++
> 5 files changed, 55 insertions(+)
> create mode 100644 MdeModulePkg/Include/Guid/MigratedFvInfo.h
>
> diff --git a/MdeModulePkg/MdeModulePkg.dec
> b/MdeModulePkg/MdeModulePkg.dec
> index 16db17d0a873..40197dba862c 100644
> --- a/MdeModulePkg/MdeModulePkg.dec
> +++ b/MdeModulePkg/MdeModulePkg.dec
> @@ -389,6 +389,9 @@ [Guids]
> ## GUID indicates the capsule is to store Capsule On Disk file names.
> gEdkiiCapsuleOnDiskNameGuid = { 0x98c80a4f, 0xe16b, 0x4d11, { 0x93, 0x9a,
> 0xab, 0xe5, 0x61, 0x26, 0x3, 0x30 } }
>
> + ## Include/Guid/MigratedFvInfo.h
> + gEdkiiMigratedFvInfoGuid = { 0xc1ab12f7, 0x74aa, 0x408d, { 0xa2, 0xf4, 0xc6,
> 0xce, 0xfd, 0x17, 0x98, 0x71 } }
> +
> [Ppis]
> ## Include/Ppi/AtaController.h
> gPeiAtaControllerPpiGuid = { 0xa45e60d1, 0xc719, 0x44aa, { 0xb0, 0x7a,
> 0xaa, 0x77, 0x7f, 0x85, 0x90, 0x6d }}
> diff --git a/MdeModulePkg/Core/Pei/PeiMain.inf
> b/MdeModulePkg/Core/Pei/PeiMain.inf
> index 5b36d516b3fa..0cf357371a16 100644
> --- a/MdeModulePkg/Core/Pei/PeiMain.inf
> +++ b/MdeModulePkg/Core/Pei/PeiMain.inf
> @@ -77,6 +77,7 @@ [Guids]
> ## CONSUMES ## GUID # Used to compare with FV's file system GUID and
> get the FV's file system format
> gEfiFirmwareFileSystem3Guid
> gStatusCodeCallbackGuid
> + gEdkiiMigratedFvInfoGuid ## SOMETIMES_PRODUCES ## HOB
>
> [Ppis]
> gEfiPeiStatusCodePpiGuid ## SOMETIMES_CONSUMES #
> PeiReportStatusService is not ready if this PPI doesn't exist
> diff --git a/MdeModulePkg/Core/Pei/PeiMain.h
> b/MdeModulePkg/Core/Pei/PeiMain.h
> index b0101dba5e30..cbf74d5b9d9a 100644
> --- a/MdeModulePkg/Core/Pei/PeiMain.h
> +++ b/MdeModulePkg/Core/Pei/PeiMain.h
> @@ -44,6 +44,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
> #include <Guid/FirmwareFileSystem2.h>
> #include <Guid/FirmwareFileSystem3.h>
> #include <Guid/AprioriFileName.h>
> +#include <Guid/MigratedFvInfo.h>
>
> ///
> /// It is an FFS type extension used for PeiFindFileEx. It indicates current
> diff --git a/MdeModulePkg/Include/Guid/MigratedFvInfo.h
> b/MdeModulePkg/Include/Guid/MigratedFvInfo.h
> new file mode 100644
> index 000000000000..061c17ed0e48
> --- /dev/null
> +++ b/MdeModulePkg/Include/Guid/MigratedFvInfo.h
> @@ -0,0 +1,22 @@
> +/** @file
> + Migrated FV information
> +
> +Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef __EDKII_MIGRATED_FV_INFO_GUID_H__
> +#define __EDKII_MIGRATED_FV_INFO_GUID_H__
> +
> +typedef struct {
> + UINT32 FvOrgBase; // original FV address
> + UINT32 FvNewBase; // new FV address
> + UINT32 FvDataBase; // original FV data
> + UINT32 FvLength; // Fv Length
> +} EDKII_MIGRATED_FV_INFO;
> +
> +extern EFI_GUID gEdkiiMigratedFvInfoGuid;
> +
> +#endif // #ifndef __EDKII_MIGRATED_FV_INFO_GUID_H__
> +
> diff --git a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
> b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
> index ef88b3423376..f654cea15c59 100644
> --- a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
> +++ b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
> @@ -1223,10 +1223,12 @@ EvacuateTempRam (
> EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
> EFI_FIRMWARE_VOLUME_HEADER *ChildFvHeader;
> EFI_FIRMWARE_VOLUME_HEADER *MigratedFvHeader;
> + EFI_FIRMWARE_VOLUME_HEADER *RawDataFvHeader;
> EFI_FIRMWARE_VOLUME_HEADER *MigratedChildFvHeader;
>
> PEI_CORE_FV_HANDLE PeiCoreFvHandle;
> EFI_PEI_CORE_FV_LOCATION_PPI *PeiCoreFvLocationPpi;
> + EDKII_MIGRATED_FV_INFO MigratedFvInfo;
>
> ASSERT (Private->PeiMemoryInstalled);
>
> @@ -1263,6 +1265,9 @@ EvacuateTempRam (
> (((EFI_PHYSICAL_ADDRESS)(UINTN) FvHeader + (FvHeader->FvLength - 1)) <
> Private->FreePhysicalMemoryTop)
> )
> ) {
> + //
> + // Allocate page to save the rebased PEIMs, the PEIMs will get control later
Do you mean 'control' -> 'dispatched'?
> + //
> Status = PeiServicesAllocatePages (
> EfiBootServicesCode,
> EFI_SIZE_TO_PAGES ((UINTN) FvHeader->FvLength),
> @@ -1270,6 +1275,17 @@ EvacuateTempRam (
> );
> ASSERT_EFI_ERROR (Status);
>
> + //
> + // Allocate pool to save the raw PEIMs, it used to keep consistent context
> across
> + // multiple boot and PCR0 will keep same no matter if allocate random page
> address.
Consider to revise the statement:
'no matter if ...' -> 'no matter if the address of allocated page is changed'
> + //
> + Status = PeiServicesAllocatePages (
> + EfiBootServicesCode,
> + EFI_SIZE_TO_PAGES ((UINTN) FvHeader->FvLength),
> + (EFI_PHYSICAL_ADDRESS *) &RawDataFvHeader
> + );
> + ASSERT_EFI_ERROR (Status);
> +
> DEBUG ((
> DEBUG_VERBOSE,
> " Migrating FV[%d] from 0x%08X to 0x%08X\n",
> @@ -1278,7 +1294,19 @@ EvacuateTempRam (
> (UINTN) MigratedFvHeader
> ));
>
> + //
> + // Copy the context to the rebased pages and raw pages, and create hob to
> save the
> + // information. the MigratedFvInfo HOB will never produce when
'the' -> 'The'
'produce' -> 'be produced'
Regards,
Jian
> + // PcdMigrateTemporaryRamFirmwareVolumes is FALSE, because the PCD
> control the
> + // feature.
> + //
> CopyMem (MigratedFvHeader, FvHeader, (UINTN) FvHeader->FvLength);
> + CopyMem (RawDataFvHeader, MigratedFvHeader, (UINTN) FvHeader-
> >FvLength);
> + MigratedFvInfo.FvOrgBase = (UINT32) (UINTN) FvHeader;
> + MigratedFvInfo.FvNewBase = (UINT32) (UINTN) MigratedFvHeader;
> + MigratedFvInfo.FvDataBase = (UINT32) (UINTN) RawDataFvHeader;
> + MigratedFvInfo.FvLength = (UINT32) (UINTN) FvHeader->FvLength;
> + BuildGuidDataHob (&gEdkiiMigratedFvInfoGuid, &MigratedFvInfo, sizeof
> (MigratedFvInfo));
>
> //
> // Migrate any children for this FV now
> --
> 2.25.1.windows.1
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v5 6/9] SecurityPkg/Tcg2Pei: Use Migrated FV Info Hob for calculating hash (CVE-2019-11098)
2020-07-09 1:56 [PATCH v5 0/9] Add new feature that evacuate temporary to permanent memory (CVE-2019-11098) Guomin Jiang
` (4 preceding siblings ...)
2020-07-09 1:56 ` [PATCH v5 5/9] MdeModulePkg/Core: Create Migrated FV Info Hob for calculating hash (CVE-2019-11098) Guomin Jiang
@ 2020-07-09 1:56 ` Guomin Jiang
2020-07-13 7:09 ` Wang, Jian J
2020-07-09 1:56 ` [PATCH v5 7/9] UefiCpuPkg/CpuMpPei: Enable paging and set NP flag to avoid TOCTOU (CVE-2019-11098) Guomin Jiang
` (3 subsequent siblings)
9 siblings, 1 reply; 24+ messages in thread
From: Guomin Jiang @ 2020-07-09 1:56 UTC (permalink / raw)
To: devel; +Cc: Jiewen Yao, Jian J Wang, Chao Zhang, Qi Zhang, Rahul Kumar
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=1614
When we allocate pool to save rebased the PEIMs, the address will change
randomly, therefore the hash will change and result PCR0 change as well.
To avoid this, we save the raw PEIMs and use it to calculate hash.
The Tcg2Pei calculate the hash and it use the Migrated FV Info.
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Chao Zhang <chao.b.zhang@intel.com>
Cc: Qi Zhang <qi1.zhang@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Signed-off-by: Guomin Jiang <guomin.jiang@intel.com>
---
SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf | 1 +
SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c | 31 ++++++++++++++++++++++++++---
2 files changed, 29 insertions(+), 3 deletions(-)
diff --git a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf
index 3d361e8859e7..367df21eedaf 100644
--- a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf
+++ b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf
@@ -63,6 +63,7 @@ [Guids]
gTcgEvent2EntryHobGuid ## PRODUCES ## HOB
gEfiTpmDeviceInstanceNoneGuid ## SOMETIMES_PRODUCES ## GUID # TPM device identifier
gEfiTpmDeviceInstanceTpm12Guid ## SOMETIMES_PRODUCES ## GUID # TPM device identifier
+ gEdkiiMigratedFvInfoGuid ## SOMETIMES_CONSUMES ## HOB
[Ppis]
gEfiPeiFirmwareVolumeInfoPpiGuid ## SOMETIMES_CONSUMES ## NOTIFY
diff --git a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
index 4852d8690617..651a60c1f0e2 100644
--- a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
+++ b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
@@ -21,6 +21,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Guid/TcgEventHob.h>
#include <Guid/MeasuredFvHob.h>
#include <Guid/TpmInstance.h>
+#include <Guid/MigratedFvInfo.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
@@ -536,6 +537,10 @@ MeasureFvImage (
EDKII_PEI_FIRMWARE_VOLUME_INFO_PREHASHED_FV_PPI *PrehashedFvPpi;
HASH_INFO *PreHashInfo;
UINT32 HashAlgoMask;
+ EFI_PHYSICAL_ADDRESS FvOrgBase;
+ EFI_PHYSICAL_ADDRESS FvDataBase;
+ EFI_PEI_HOB_POINTERS Hob;
+ EDKII_MIGRATED_FV_INFO *MigratedFvInfo;
//
// Check Excluded FV list
@@ -621,6 +626,26 @@ MeasureFvImage (
Instance++;
} while (!EFI_ERROR(Status));
+ //
+ // Search the matched migration FV info
+ //
+ FvOrgBase = FvBase;
+ FvDataBase = FvBase;
+ Hob.Raw = GetFirstGuidHob (&gEdkiiMigratedFvInfoGuid);
+ while (Hob.Raw != NULL) {
+ MigratedFvInfo = GET_GUID_HOB_DATA (Hob);
+ if ((MigratedFvInfo->FvNewBase == (UINT32) FvBase) && (MigratedFvInfo->FvLength == (UINT32) FvLength)) {
+ //
+ // Found the migrated FV info
+ //
+ FvOrgBase = (EFI_PHYSICAL_ADDRESS) (UINTN) MigratedFvInfo->FvOrgBase;
+ FvDataBase = (EFI_PHYSICAL_ADDRESS) (UINTN) MigratedFvInfo->FvDataBase;
+ break;
+ }
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ Hob.Raw = GetNextGuidHob (&gEdkiiMigratedFvInfoGuid, Hob.Raw);
+ }
+
//
// Init the log event for FV measurement
//
@@ -631,13 +656,13 @@ MeasureFvImage (
if (FvName != NULL) {
AsciiSPrint ((CHAR8 *)FvBlob2.BlobDescription, sizeof(FvBlob2.BlobDescription), "Fv(%g)", FvName);
}
- FvBlob2.BlobBase = FvBase;
+ FvBlob2.BlobBase = FvOrgBase;
FvBlob2.BlobLength = FvLength;
TcgEventHdr.EventType = EV_EFI_PLATFORM_FIRMWARE_BLOB2;
TcgEventHdr.EventSize = sizeof (FvBlob2);
EventData = &FvBlob2;
} else {
- FvBlob.BlobBase = FvBase;
+ FvBlob.BlobBase = FvOrgBase;
FvBlob.BlobLength = FvLength;
TcgEventHdr.PCRIndex = 0;
TcgEventHdr.EventType = EV_EFI_PLATFORM_FIRMWARE_BLOB;
@@ -672,7 +697,7 @@ MeasureFvImage (
//
Status = HashLogExtendEvent (
0,
- (UINT8*) (UINTN) FvBase, // HashData
+ (UINT8*) (UINTN) FvDataBase, // HashData
(UINTN) FvLength, // HashDataLen
&TcgEventHdr, // EventHdr
EventData // EventData
--
2.25.1.windows.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH v5 6/9] SecurityPkg/Tcg2Pei: Use Migrated FV Info Hob for calculating hash (CVE-2019-11098)
2020-07-09 1:56 ` [PATCH v5 6/9] SecurityPkg/Tcg2Pei: Use " Guomin Jiang
@ 2020-07-13 7:09 ` Wang, Jian J
0 siblings, 0 replies; 24+ messages in thread
From: Wang, Jian J @ 2020-07-13 7:09 UTC (permalink / raw)
To: Jiang, Guomin, devel@edk2.groups.io
Cc: Yao, Jiewen, Zhang, Chao B, Zhang, Qi1, Kumar, Rahul1
Reviewed-by: Jian J Wang <jian.j.wang@intel.com>
Regards,
Jian
> -----Original Message-----
> From: Jiang, Guomin <guomin.jiang@intel.com>
> Sent: Thursday, July 09, 2020 9:57 AM
> To: devel@edk2.groups.io
> Cc: Yao, Jiewen <jiewen.yao@intel.com>; Wang, Jian J <jian.j.wang@intel.com>;
> Zhang, Chao B <chao.b.zhang@intel.com>; Zhang, Qi1 <qi1.zhang@intel.com>;
> Kumar, Rahul1 <rahul1.kumar@intel.com>
> Subject: [PATCH v5 6/9] SecurityPkg/Tcg2Pei: Use Migrated FV Info Hob for
> calculating hash (CVE-2019-11098)
>
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=1614
>
> When we allocate pool to save rebased the PEIMs, the address will change
> randomly, therefore the hash will change and result PCR0 change as well.
> To avoid this, we save the raw PEIMs and use it to calculate hash.
> The Tcg2Pei calculate the hash and it use the Migrated FV Info.
>
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Jian J Wang <jian.j.wang@intel.com>
> Cc: Chao Zhang <chao.b.zhang@intel.com>
> Cc: Qi Zhang <qi1.zhang@intel.com>
> Cc: Rahul Kumar <rahul1.kumar@intel.com>
> Signed-off-by: Guomin Jiang <guomin.jiang@intel.com>
> ---
> SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf | 1 +
> SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c | 31 ++++++++++++++++++++++++++---
> 2 files changed, 29 insertions(+), 3 deletions(-)
>
> diff --git a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf
> b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf
> index 3d361e8859e7..367df21eedaf 100644
> --- a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf
> +++ b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf
> @@ -63,6 +63,7 @@ [Guids]
> gTcgEvent2EntryHobGuid ## PRODUCES ##
> HOB
> gEfiTpmDeviceInstanceNoneGuid ##
> SOMETIMES_PRODUCES ## GUID # TPM device identifier
> gEfiTpmDeviceInstanceTpm12Guid ##
> SOMETIMES_PRODUCES ## GUID # TPM device identifier
> + gEdkiiMigratedFvInfoGuid ##
> SOMETIMES_CONSUMES ## HOB
>
> [Ppis]
> gEfiPeiFirmwareVolumeInfoPpiGuid ##
> SOMETIMES_CONSUMES ## NOTIFY
> diff --git a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
> b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
> index 4852d8690617..651a60c1f0e2 100644
> --- a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
> +++ b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
> @@ -21,6 +21,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
> #include <Guid/TcgEventHob.h>
> #include <Guid/MeasuredFvHob.h>
> #include <Guid/TpmInstance.h>
> +#include <Guid/MigratedFvInfo.h>
>
> #include <Library/DebugLib.h>
> #include <Library/BaseMemoryLib.h>
> @@ -536,6 +537,10 @@ MeasureFvImage (
> EDKII_PEI_FIRMWARE_VOLUME_INFO_PREHASHED_FV_PPI
> *PrehashedFvPpi;
> HASH_INFO *PreHashInfo;
> UINT32 HashAlgoMask;
> + EFI_PHYSICAL_ADDRESS FvOrgBase;
> + EFI_PHYSICAL_ADDRESS FvDataBase;
> + EFI_PEI_HOB_POINTERS Hob;
> + EDKII_MIGRATED_FV_INFO *MigratedFvInfo;
>
> //
> // Check Excluded FV list
> @@ -621,6 +626,26 @@ MeasureFvImage (
> Instance++;
> } while (!EFI_ERROR(Status));
>
> + //
> + // Search the matched migration FV info
> + //
> + FvOrgBase = FvBase;
> + FvDataBase = FvBase;
> + Hob.Raw = GetFirstGuidHob (&gEdkiiMigratedFvInfoGuid);
> + while (Hob.Raw != NULL) {
> + MigratedFvInfo = GET_GUID_HOB_DATA (Hob);
> + if ((MigratedFvInfo->FvNewBase == (UINT32) FvBase) && (MigratedFvInfo-
> >FvLength == (UINT32) FvLength)) {
> + //
> + // Found the migrated FV info
> + //
> + FvOrgBase = (EFI_PHYSICAL_ADDRESS) (UINTN) MigratedFvInfo-
> >FvOrgBase;
> + FvDataBase = (EFI_PHYSICAL_ADDRESS) (UINTN) MigratedFvInfo-
> >FvDataBase;
> + break;
> + }
> + Hob.Raw = GET_NEXT_HOB (Hob);
> + Hob.Raw = GetNextGuidHob (&gEdkiiMigratedFvInfoGuid, Hob.Raw);
> + }
> +
> //
> // Init the log event for FV measurement
> //
> @@ -631,13 +656,13 @@ MeasureFvImage (
> if (FvName != NULL) {
> AsciiSPrint ((CHAR8 *)FvBlob2.BlobDescription,
> sizeof(FvBlob2.BlobDescription), "Fv(%g)", FvName);
> }
> - FvBlob2.BlobBase = FvBase;
> + FvBlob2.BlobBase = FvOrgBase;
> FvBlob2.BlobLength = FvLength;
> TcgEventHdr.EventType = EV_EFI_PLATFORM_FIRMWARE_BLOB2;
> TcgEventHdr.EventSize = sizeof (FvBlob2);
> EventData = &FvBlob2;
> } else {
> - FvBlob.BlobBase = FvBase;
> + FvBlob.BlobBase = FvOrgBase;
> FvBlob.BlobLength = FvLength;
> TcgEventHdr.PCRIndex = 0;
> TcgEventHdr.EventType = EV_EFI_PLATFORM_FIRMWARE_BLOB;
> @@ -672,7 +697,7 @@ MeasureFvImage (
> //
> Status = HashLogExtendEvent (
> 0,
> - (UINT8*) (UINTN) FvBase, // HashData
> + (UINT8*) (UINTN) FvDataBase, // HashData
> (UINTN) FvLength, // HashDataLen
> &TcgEventHdr, // EventHdr
> EventData // EventData
> --
> 2.25.1.windows.1
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v5 7/9] UefiCpuPkg/CpuMpPei: Enable paging and set NP flag to avoid TOCTOU (CVE-2019-11098)
2020-07-09 1:56 [PATCH v5 0/9] Add new feature that evacuate temporary to permanent memory (CVE-2019-11098) Guomin Jiang
` (5 preceding siblings ...)
2020-07-09 1:56 ` [PATCH v5 6/9] SecurityPkg/Tcg2Pei: Use " Guomin Jiang
@ 2020-07-09 1:56 ` Guomin Jiang
2020-07-13 7:47 ` [edk2-devel] " Wang, Jian J
2020-07-09 1:56 ` [PATCH v5 8/9] UefiCpuPkg: Correct some typos Guomin Jiang
` (2 subsequent siblings)
9 siblings, 1 reply; 24+ messages in thread
From: Guomin Jiang @ 2020-07-09 1:56 UTC (permalink / raw)
To: devel; +Cc: Eric Dong, Ray Ni, Laszlo Ersek, Rahul Kumar
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=1614
To avoid the TOCTOU, enable paging and set Not Present flag so when
access any code in the flash range, it will trigger #NP exception.
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Signed-off-by: Guomin Jiang <guomin.jiang@intel.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
---
UefiCpuPkg/CpuMpPei/CpuMpPei.inf | 3 +++
UefiCpuPkg/CpuMpPei/CpuPaging.c | 26 ++++++++++++++++++++++++--
2 files changed, 27 insertions(+), 2 deletions(-)
diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.inf b/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
index f4d11b861f77..7e511325d8b8 100644
--- a/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
+++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
@@ -46,6 +46,9 @@ [LibraryClasses]
BaseMemoryLib
CpuLib
+[Guids]
+ gEdkiiMigratedFvInfoGuid ## SOMETIMES_CONSUMES ## HOB
+
[Ppis]
gEfiPeiMpServicesPpiGuid ## PRODUCES
gEfiSecPlatformInformationPpiGuid ## SOMETIMES_CONSUMES
diff --git a/UefiCpuPkg/CpuMpPei/CpuPaging.c b/UefiCpuPkg/CpuMpPei/CpuPaging.c
index 3bf0574b34c6..04a16fb2b620 100644
--- a/UefiCpuPkg/CpuMpPei/CpuPaging.c
+++ b/UefiCpuPkg/CpuMpPei/CpuPaging.c
@@ -12,6 +12,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/MemoryAllocationLib.h>
#include <Library/CpuLib.h>
#include <Library/BaseLib.h>
+#include <Guid/MigratedFvInfo.h>
#include "CpuMpPei.h"
@@ -605,6 +606,8 @@ MemoryDiscoveredPpiNotifyCallback (
EFI_STATUS Status;
BOOLEAN InitStackGuard;
BOOLEAN InterruptState;
+ EDKII_MIGRATED_FV_INFO *MigratedFvInfo;
+ EFI_PEI_HOB_POINTERS Hob;
if (PcdGetBool (PcdMigrateTemporaryRamFirmwareVolumes)) {
InterruptState = SaveAndDisableInterrupts ();
@@ -619,9 +622,14 @@ MemoryDiscoveredPpiNotifyCallback (
// the task switch (for the sake of stack switch).
//
InitStackGuard = FALSE;
- if (IsIa32PaeSupported () && PcdGetBool (PcdCpuStackGuard)) {
+ Hob.Raw = NULL;
+ if (IsIa32PaeSupported ()) {
+ Hob.Raw = GetFirstGuidHob (&gEdkiiMigratedFvInfoGuid);
+ InitStackGuard = PcdGetBool (PcdCpuStackGuard);
+ }
+
+ if (InitStackGuard || Hob.Raw != NULL) {
EnablePaging ();
- InitStackGuard = TRUE;
}
Status = InitializeCpuMpWorker ((CONST EFI_PEI_SERVICES **)PeiServices);
@@ -631,6 +639,20 @@ MemoryDiscoveredPpiNotifyCallback (
SetupStackGuardPage ();
}
+ while (Hob.Raw != NULL) {
+ MigratedFvInfo = GET_GUID_HOB_DATA (Hob);
+
+ //
+ // Enable #NP exception, so if the code access after disable NEM, it will generate
+ // to avoid potential vulnerability.
+ //
+ ConvertMemoryPageAttributes (MigratedFvInfo->FvOrgBase, MigratedFvInfo->FvLength, 0);
+
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ Hob.Raw = GetNextGuidHob (&gEdkiiMigratedFvInfoGuid, Hob.Raw);
+ }
+ CpuFlushTlb ();
+
return Status;
}
--
2.25.1.windows.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [edk2-devel] [PATCH v5 7/9] UefiCpuPkg/CpuMpPei: Enable paging and set NP flag to avoid TOCTOU (CVE-2019-11098)
2020-07-09 1:56 ` [PATCH v5 7/9] UefiCpuPkg/CpuMpPei: Enable paging and set NP flag to avoid TOCTOU (CVE-2019-11098) Guomin Jiang
@ 2020-07-13 7:47 ` Wang, Jian J
0 siblings, 0 replies; 24+ messages in thread
From: Wang, Jian J @ 2020-07-13 7:47 UTC (permalink / raw)
To: devel@edk2.groups.io, Jiang, Guomin
Cc: Dong, Eric, Ni, Ray, Laszlo Ersek, Kumar, Rahul1
Guomin,
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Guomin
> Jiang
> Sent: Thursday, July 09, 2020 9:57 AM
> To: devel@edk2.groups.io
> Cc: Dong, Eric <eric.dong@intel.com>; Ni, Ray <ray.ni@intel.com>; Laszlo Ersek
> <lersek@redhat.com>; Kumar, Rahul1 <rahul1.kumar@intel.com>
> Subject: [edk2-devel] [PATCH v5 7/9] UefiCpuPkg/CpuMpPei: Enable paging and
> set NP flag to avoid TOCTOU (CVE-2019-11098)
>
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=1614
>
> To avoid the TOCTOU, enable paging and set Not Present flag so when
> access any code in the flash range, it will trigger #NP exception.
It's #PF, not #NP.
>
> Cc: Eric Dong <eric.dong@intel.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Rahul Kumar <rahul1.kumar@intel.com>
> Signed-off-by: Guomin Jiang <guomin.jiang@intel.com>
> Acked-by: Laszlo Ersek <lersek@redhat.com>
> ---
> UefiCpuPkg/CpuMpPei/CpuMpPei.inf | 3 +++
> UefiCpuPkg/CpuMpPei/CpuPaging.c | 26 ++++++++++++++++++++++++--
> 2 files changed, 27 insertions(+), 2 deletions(-)
>
> diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
> b/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
> index f4d11b861f77..7e511325d8b8 100644
> --- a/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
> +++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
> @@ -46,6 +46,9 @@ [LibraryClasses]
> BaseMemoryLib
> CpuLib
>
> +[Guids]
> + gEdkiiMigratedFvInfoGuid ##
> SOMETIMES_CONSUMES ## HOB
> +
> [Ppis]
> gEfiPeiMpServicesPpiGuid ## PRODUCES
> gEfiSecPlatformInformationPpiGuid ## SOMETIMES_CONSUMES
> diff --git a/UefiCpuPkg/CpuMpPei/CpuPaging.c
> b/UefiCpuPkg/CpuMpPei/CpuPaging.c
> index 3bf0574b34c6..04a16fb2b620 100644
> --- a/UefiCpuPkg/CpuMpPei/CpuPaging.c
> +++ b/UefiCpuPkg/CpuMpPei/CpuPaging.c
> @@ -12,6 +12,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
> #include <Library/MemoryAllocationLib.h>
> #include <Library/CpuLib.h>
> #include <Library/BaseLib.h>
> +#include <Guid/MigratedFvInfo.h>
>
> #include "CpuMpPei.h"
>
> @@ -605,6 +606,8 @@ MemoryDiscoveredPpiNotifyCallback (
> EFI_STATUS Status;
> BOOLEAN InitStackGuard;
> BOOLEAN InterruptState;
> + EDKII_MIGRATED_FV_INFO *MigratedFvInfo;
> + EFI_PEI_HOB_POINTERS Hob;
>
Please align the variable names.
> if (PcdGetBool (PcdMigrateTemporaryRamFirmwareVolumes)) {
> InterruptState = SaveAndDisableInterrupts ();
> @@ -619,9 +622,14 @@ MemoryDiscoveredPpiNotifyCallback (
> // the task switch (for the sake of stack switch).
> //
> InitStackGuard = FALSE;
> - if (IsIa32PaeSupported () && PcdGetBool (PcdCpuStackGuard)) {
> + Hob.Raw = NULL;
> + if (IsIa32PaeSupported ()) {
> + Hob.Raw = GetFirstGuidHob (&gEdkiiMigratedFvInfoGuid);
> + InitStackGuard = PcdGetBool (PcdCpuStackGuard);
> + }
> +
PcdMigrateTemporaryRamFirmwareVolumes is only effective along
with PcdShadowPeimOnBoot or PcdShadowPeimOnS3Boot in PeiCore.
Using it here without other two doesn't make sense. Need further
discussion to clarify the usage of all of them.
> + if (InitStackGuard || Hob.Raw != NULL) {
> EnablePaging ();
> - InitStackGuard = TRUE;
> }
>
> Status = InitializeCpuMpWorker ((CONST EFI_PEI_SERVICES **)PeiServices);
> @@ -631,6 +639,20 @@ MemoryDiscoveredPpiNotifyCallback (
> SetupStackGuardPage ();
> }
>
> + while (Hob.Raw != NULL) {
> + MigratedFvInfo = GET_GUID_HOB_DATA (Hob);
> +
> + //
> + // Enable #NP exception, so if the code access after disable NEM, it will
> generate
It's #PF, not #NP.
> + // to avoid potential vulnerability.
> + //
> + ConvertMemoryPageAttributes (MigratedFvInfo->FvOrgBase,
> MigratedFvInfo->FvLength, 0);
> +
> + Hob.Raw = GET_NEXT_HOB (Hob);
> + Hob.Raw = GetNextGuidHob (&gEdkiiMigratedFvInfoGuid, Hob.Raw);
> + }
> + CpuFlushTlb ();
> +
> return Status;
> }
>
> --
> 2.25.1.windows.1
>
>
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v5 8/9] UefiCpuPkg: Correct some typos.
2020-07-09 1:56 [PATCH v5 0/9] Add new feature that evacuate temporary to permanent memory (CVE-2019-11098) Guomin Jiang
` (6 preceding siblings ...)
2020-07-09 1:56 ` [PATCH v5 7/9] UefiCpuPkg/CpuMpPei: Enable paging and set NP flag to avoid TOCTOU (CVE-2019-11098) Guomin Jiang
@ 2020-07-09 1:56 ` Guomin Jiang
2020-07-09 10:58 ` [edk2-devel] " Laszlo Ersek
2020-07-09 1:56 ` [PATCH v5 9/9] SecurityPkg/TcgPei: Use Migrated FV Info Hob for calculating hash (CVE-2019-11098) Guomin Jiang
2020-07-10 5:46 ` [edk2-devel] [PATCH v5 0/9] Add new feature that evacuate temporary to permanent memory (CVE-2019-11098) Laszlo Ersek
9 siblings, 1 reply; 24+ messages in thread
From: Guomin Jiang @ 2020-07-09 1:56 UTC (permalink / raw)
To: devel; +Cc: Eric Dong, Ray Ni, Laszlo Ersek, Rahul Kumar
Correct some typos.
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Signed-off-by: Guomin Jiang <guomin.jiang@intel.com>
---
UefiCpuPkg/CpuMpPei/CpuMpPei.h | 2 +-
.../Library/CpuExceptionHandlerLib/CpuExceptionCommon.h | 4 ++--
UefiCpuPkg/CpuMpPei/CpuPaging.c | 4 ++--
.../CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c | 4 ++--
.../Library/CpuExceptionHandlerLib/SecPeiCpuException.c | 2 +-
.../Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c | 4 ++--
6 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.h b/UefiCpuPkg/CpuMpPei/CpuMpPei.h
index 309478cbe14c..6a481a84dcc7 100644
--- a/UefiCpuPkg/CpuMpPei/CpuMpPei.h
+++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.h
@@ -424,7 +424,7 @@ InitializeCpuMpWorker (
);
/**
- Enabl/setup stack guard for each processor if PcdCpuStackGuard is set to TRUE.
+ Enable/setup stack guard for each processor if PcdCpuStackGuard is set to TRUE.
Doing this in the memory-discovered callback is to make sure the Stack Guard
feature to cover as most PEI code as possible.
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
index 805dd9cbb4ff..0544d6dba631 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
@@ -90,8 +90,8 @@ AsmGetTemplateAddressMap (
**/
VOID
ArchUpdateIdtEntry (
- IN IA32_IDT_GATE_DESCRIPTOR *IdtEntry,
- IN UINTN InterruptHandler
+ OUT IA32_IDT_GATE_DESCRIPTOR *IdtEntry,
+ IN UINTN InterruptHandler
);
/**
diff --git a/UefiCpuPkg/CpuMpPei/CpuPaging.c b/UefiCpuPkg/CpuMpPei/CpuPaging.c
index 04a16fb2b620..891d1ef50cac 100644
--- a/UefiCpuPkg/CpuMpPei/CpuPaging.c
+++ b/UefiCpuPkg/CpuMpPei/CpuPaging.c
@@ -153,7 +153,7 @@ GetPhysicalAddressWidth (
Get the type of top level page table.
@retval Page512G PML4 paging.
- @retval Page1G PAE paing.
+ @retval Page1G PAE paging.
**/
PAGE_ATTRIBUTE
@@ -583,7 +583,7 @@ SetupStackGuardPage (
}
/**
- Enabl/setup stack guard for each processor if PcdCpuStackGuard is set to TRUE.
+ Enable/setup stack guard for each processor if PcdCpuStackGuard is set to TRUE.
Doing this in the memory-discovered callback is to make sure the Stack Guard
feature to cover as most PEI code as possible.
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
index 1aafb7dac139..903449e0daa9 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
@@ -18,8 +18,8 @@
**/
VOID
ArchUpdateIdtEntry (
- IN IA32_IDT_GATE_DESCRIPTOR *IdtEntry,
- IN UINTN InterruptHandler
+ OUT IA32_IDT_GATE_DESCRIPTOR *IdtEntry,
+ IN UINTN InterruptHandler
)
{
IdtEntry->Bits.OffsetLow = (UINT16)(UINTN)InterruptHandler;
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c
index 20148db74cf8..d4ae153c5742 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c
@@ -87,7 +87,7 @@ InitializeCpuExceptionHandlers (
IdtEntryCount = (IdtDescriptor.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR);
if (IdtEntryCount > CPU_EXCEPTION_NUM) {
//
- // CPU exeption library only setup CPU_EXCEPTION_NUM exception handler at most
+ // CPU exception library only setup CPU_EXCEPTION_NUM exception handler at most
//
IdtEntryCount = CPU_EXCEPTION_NUM;
}
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
index 894c1cfb7533..d3da16e4dfa2 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
@@ -17,8 +17,8 @@
**/
VOID
ArchUpdateIdtEntry (
- IN IA32_IDT_GATE_DESCRIPTOR *IdtEntry,
- IN UINTN InterruptHandler
+ OUT IA32_IDT_GATE_DESCRIPTOR *IdtEntry,
+ IN UINTN InterruptHandler
)
{
IdtEntry->Bits.OffsetLow = (UINT16)(UINTN)InterruptHandler;
--
2.25.1.windows.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [edk2-devel] [PATCH v5 8/9] UefiCpuPkg: Correct some typos.
2020-07-09 1:56 ` [PATCH v5 8/9] UefiCpuPkg: Correct some typos Guomin Jiang
@ 2020-07-09 10:58 ` Laszlo Ersek
0 siblings, 0 replies; 24+ messages in thread
From: Laszlo Ersek @ 2020-07-09 10:58 UTC (permalink / raw)
To: devel, guomin.jiang; +Cc: Eric Dong, Ray Ni, Rahul Kumar
On 07/09/20 03:56, Guomin Jiang wrote:
> Correct some typos.
>
> Cc: Eric Dong <eric.dong@intel.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Rahul Kumar <rahul1.kumar@intel.com>
> Signed-off-by: Guomin Jiang <guomin.jiang@intel.com>
> ---
> UefiCpuPkg/CpuMpPei/CpuMpPei.h | 2 +-
> .../Library/CpuExceptionHandlerLib/CpuExceptionCommon.h | 4 ++--
> UefiCpuPkg/CpuMpPei/CpuPaging.c | 4 ++--
> .../CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c | 4 ++--
> .../Library/CpuExceptionHandlerLib/SecPeiCpuException.c | 2 +-
> .../Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c | 4 ++--
> 6 files changed, 10 insertions(+), 10 deletions(-)
>
> diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.h b/UefiCpuPkg/CpuMpPei/CpuMpPei.h
> index 309478cbe14c..6a481a84dcc7 100644
> --- a/UefiCpuPkg/CpuMpPei/CpuMpPei.h
> +++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.h
> @@ -424,7 +424,7 @@ InitializeCpuMpWorker (
> );
>
> /**
> - Enabl/setup stack guard for each processor if PcdCpuStackGuard is set to TRUE.
> + Enable/setup stack guard for each processor if PcdCpuStackGuard is set to TRUE.
>
> Doing this in the memory-discovered callback is to make sure the Stack Guard
> feature to cover as most PEI code as possible.
> diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
> index 805dd9cbb4ff..0544d6dba631 100644
> --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
> +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
> @@ -90,8 +90,8 @@ AsmGetTemplateAddressMap (
> **/
> VOID
> ArchUpdateIdtEntry (
> - IN IA32_IDT_GATE_DESCRIPTOR *IdtEntry,
> - IN UINTN InterruptHandler
> + OUT IA32_IDT_GATE_DESCRIPTOR *IdtEntry,
> + IN UINTN InterruptHandler
> );
>
> /**
> diff --git a/UefiCpuPkg/CpuMpPei/CpuPaging.c b/UefiCpuPkg/CpuMpPei/CpuPaging.c
> index 04a16fb2b620..891d1ef50cac 100644
> --- a/UefiCpuPkg/CpuMpPei/CpuPaging.c
> +++ b/UefiCpuPkg/CpuMpPei/CpuPaging.c
> @@ -153,7 +153,7 @@ GetPhysicalAddressWidth (
> Get the type of top level page table.
>
> @retval Page512G PML4 paging.
> - @retval Page1G PAE paing.
> + @retval Page1G PAE paging.
>
> **/
> PAGE_ATTRIBUTE
> @@ -583,7 +583,7 @@ SetupStackGuardPage (
> }
>
> /**
> - Enabl/setup stack guard for each processor if PcdCpuStackGuard is set to TRUE.
> + Enable/setup stack guard for each processor if PcdCpuStackGuard is set to TRUE.
>
> Doing this in the memory-discovered callback is to make sure the Stack Guard
> feature to cover as most PEI code as possible.
> diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
> index 1aafb7dac139..903449e0daa9 100644
> --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
> +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
> @@ -18,8 +18,8 @@
> **/
> VOID
> ArchUpdateIdtEntry (
> - IN IA32_IDT_GATE_DESCRIPTOR *IdtEntry,
> - IN UINTN InterruptHandler
> + OUT IA32_IDT_GATE_DESCRIPTOR *IdtEntry,
> + IN UINTN InterruptHandler
> )
> {
> IdtEntry->Bits.OffsetLow = (UINT16)(UINTN)InterruptHandler;
> diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c
> index 20148db74cf8..d4ae153c5742 100644
> --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c
> +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c
> @@ -87,7 +87,7 @@ InitializeCpuExceptionHandlers (
> IdtEntryCount = (IdtDescriptor.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR);
> if (IdtEntryCount > CPU_EXCEPTION_NUM) {
> //
> - // CPU exeption library only setup CPU_EXCEPTION_NUM exception handler at most
> + // CPU exception library only setup CPU_EXCEPTION_NUM exception handler at most
> //
> IdtEntryCount = CPU_EXCEPTION_NUM;
> }
> diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
> index 894c1cfb7533..d3da16e4dfa2 100644
> --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
> +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
> @@ -17,8 +17,8 @@
> **/
> VOID
> ArchUpdateIdtEntry (
> - IN IA32_IDT_GATE_DESCRIPTOR *IdtEntry,
> - IN UINTN InterruptHandler
> + OUT IA32_IDT_GATE_DESCRIPTOR *IdtEntry,
> + IN UINTN InterruptHandler
> )
> {
> IdtEntry->Bits.OffsetLow = (UINT16)(UINTN)InterruptHandler;
>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v5 9/9] SecurityPkg/TcgPei: Use Migrated FV Info Hob for calculating hash (CVE-2019-11098)
2020-07-09 1:56 [PATCH v5 0/9] Add new feature that evacuate temporary to permanent memory (CVE-2019-11098) Guomin Jiang
` (7 preceding siblings ...)
2020-07-09 1:56 ` [PATCH v5 8/9] UefiCpuPkg: Correct some typos Guomin Jiang
@ 2020-07-09 1:56 ` Guomin Jiang
2020-07-13 7:49 ` Wang, Jian J
2020-07-10 5:46 ` [edk2-devel] [PATCH v5 0/9] Add new feature that evacuate temporary to permanent memory (CVE-2019-11098) Laszlo Ersek
9 siblings, 1 reply; 24+ messages in thread
From: Guomin Jiang @ 2020-07-09 1:56 UTC (permalink / raw)
To: devel; +Cc: Jiewen Yao, Jian J Wang, Chao Zhang, Qi Zhang, Rahul Kumar
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=1614
When we allocate pool to save rebased the PEIMs, the address will change
randomly, therefore the hash will change and result PCR0 change as well.
To avoid this, we save the raw PEIMs and use it to calculate hash.
The TcgPei calculate the hash and it use the Migrated FV Info.
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Chao Zhang <chao.b.zhang@intel.com>
Cc: Qi Zhang <qi1.zhang@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Signed-off-by: Guomin Jiang <guomin.jiang@intel.com>
---
SecurityPkg/Tcg/TcgPei/TcgPei.inf | 1 +
SecurityPkg/Tcg/TcgPei/TcgPei.c | 29 +++++++++++++++++++++++++++--
2 files changed, 28 insertions(+), 2 deletions(-)
diff --git a/SecurityPkg/Tcg/TcgPei/TcgPei.inf b/SecurityPkg/Tcg/TcgPei/TcgPei.inf
index c0bff6e85e9d..6d1951f8ed65 100644
--- a/SecurityPkg/Tcg/TcgPei/TcgPei.inf
+++ b/SecurityPkg/Tcg/TcgPei/TcgPei.inf
@@ -58,6 +58,7 @@ [Guids]
gTpmErrorHobGuid ## SOMETIMES_PRODUCES ## HOB
gMeasuredFvHobGuid ## PRODUCES ## HOB
gEfiTpmDeviceInstanceTpm12Guid ## PRODUCES ## GUID # TPM device identifier
+ gEdkiiMigratedFvInfoGuid ## SOMETIMES_CONSUMES ## HOB
[Ppis]
gPeiLockPhysicalPresencePpiGuid ## SOMETIMES_CONSUMES ## NOTIFY
diff --git a/SecurityPkg/Tcg/TcgPei/TcgPei.c b/SecurityPkg/Tcg/TcgPei/TcgPei.c
index a9a808c9ecf3..9701bfe8715b 100644
--- a/SecurityPkg/Tcg/TcgPei/TcgPei.c
+++ b/SecurityPkg/Tcg/TcgPei/TcgPei.c
@@ -21,6 +21,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Guid/TcgEventHob.h>
#include <Guid/MeasuredFvHob.h>
#include <Guid/TpmInstance.h>
+#include <Guid/MigratedFvInfo.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
@@ -378,6 +379,10 @@ MeasureFvImage (
EFI_STATUS Status;
EFI_PLATFORM_FIRMWARE_BLOB FvBlob;
TCG_PCR_EVENT_HDR TcgEventHdr;
+ EFI_PHYSICAL_ADDRESS FvOrgBase;
+ EFI_PHYSICAL_ADDRESS FvDataBase;
+ EFI_PEI_HOB_POINTERS Hob;
+ EDKII_MIGRATED_FV_INFO *MigratedFvInfo;
//
// Check if it is in Excluded FV list
@@ -401,10 +406,30 @@ MeasureFvImage (
}
}
+ //
+ // Search the matched migration FV info
+ //
+ FvOrgBase = FvBase;
+ FvDataBase = FvBase;
+ Hob.Raw = GetFirstGuidHob (&gEdkiiMigratedFvInfoGuid);
+ while (Hob.Raw != NULL) {
+ MigratedFvInfo = GET_GUID_HOB_DATA (Hob);
+ if ((MigratedFvInfo->FvNewBase == (UINT32) FvBase) && (MigratedFvInfo->FvLength == (UINT32) FvLength)) {
+ //
+ // Found the migrated FV info
+ //
+ FvOrgBase = (EFI_PHYSICAL_ADDRESS) (UINTN) MigratedFvInfo->FvOrgBase;
+ FvDataBase = (EFI_PHYSICAL_ADDRESS) (UINTN) MigratedFvInfo->FvDataBase;
+ break;
+ }
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ Hob.Raw = GetNextGuidHob (&gEdkiiMigratedFvInfoGuid, Hob.Raw);
+ }
+
//
// Measure and record the FV to the TPM
//
- FvBlob.BlobBase = FvBase;
+ FvBlob.BlobBase = FvOrgBase;
FvBlob.BlobLength = FvLength;
DEBUG ((DEBUG_INFO, "The FV which is measured by TcgPei starts at: 0x%x\n", FvBlob.BlobBase));
@@ -416,7 +441,7 @@ MeasureFvImage (
Status = HashLogExtendEvent (
(EFI_PEI_SERVICES **) GetPeiServicesTablePointer(),
- (UINT8*) (UINTN) FvBlob.BlobBase,
+ (UINT8*) (UINTN) FvDataBase,
(UINTN) FvBlob.BlobLength,
&TcgEventHdr,
(UINT8*) &FvBlob
--
2.25.1.windows.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH v5 9/9] SecurityPkg/TcgPei: Use Migrated FV Info Hob for calculating hash (CVE-2019-11098)
2020-07-09 1:56 ` [PATCH v5 9/9] SecurityPkg/TcgPei: Use Migrated FV Info Hob for calculating hash (CVE-2019-11098) Guomin Jiang
@ 2020-07-13 7:49 ` Wang, Jian J
0 siblings, 0 replies; 24+ messages in thread
From: Wang, Jian J @ 2020-07-13 7:49 UTC (permalink / raw)
To: Jiang, Guomin, devel@edk2.groups.io
Cc: Yao, Jiewen, Zhang, Chao B, Zhang, Qi1, Kumar, Rahul1
Reviewed-by: Jian J Wang <jian.j.wang@intel.com>
Regards,
Jian
> -----Original Message-----
> From: Jiang, Guomin <guomin.jiang@intel.com>
> Sent: Thursday, July 09, 2020 9:57 AM
> To: devel@edk2.groups.io
> Cc: Yao, Jiewen <jiewen.yao@intel.com>; Wang, Jian J <jian.j.wang@intel.com>;
> Zhang, Chao B <chao.b.zhang@intel.com>; Zhang, Qi1 <qi1.zhang@intel.com>;
> Kumar, Rahul1 <rahul1.kumar@intel.com>
> Subject: [PATCH v5 9/9] SecurityPkg/TcgPei: Use Migrated FV Info Hob for
> calculating hash (CVE-2019-11098)
>
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=1614
>
> When we allocate pool to save rebased the PEIMs, the address will change
> randomly, therefore the hash will change and result PCR0 change as well.
> To avoid this, we save the raw PEIMs and use it to calculate hash.
> The TcgPei calculate the hash and it use the Migrated FV Info.
>
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Jian J Wang <jian.j.wang@intel.com>
> Cc: Chao Zhang <chao.b.zhang@intel.com>
> Cc: Qi Zhang <qi1.zhang@intel.com>
> Cc: Rahul Kumar <rahul1.kumar@intel.com>
> Signed-off-by: Guomin Jiang <guomin.jiang@intel.com>
> ---
> SecurityPkg/Tcg/TcgPei/TcgPei.inf | 1 +
> SecurityPkg/Tcg/TcgPei/TcgPei.c | 29 +++++++++++++++++++++++++++--
> 2 files changed, 28 insertions(+), 2 deletions(-)
>
> diff --git a/SecurityPkg/Tcg/TcgPei/TcgPei.inf
> b/SecurityPkg/Tcg/TcgPei/TcgPei.inf
> index c0bff6e85e9d..6d1951f8ed65 100644
> --- a/SecurityPkg/Tcg/TcgPei/TcgPei.inf
> +++ b/SecurityPkg/Tcg/TcgPei/TcgPei.inf
> @@ -58,6 +58,7 @@ [Guids]
> gTpmErrorHobGuid ## SOMETIMES_PRODUCES
> ## HOB
> gMeasuredFvHobGuid ## PRODUCES ##
> HOB
> gEfiTpmDeviceInstanceTpm12Guid ## PRODUCES
> ## GUID # TPM device identifier
> + gEdkiiMigratedFvInfoGuid ##
> SOMETIMES_CONSUMES ## HOB
>
> [Ppis]
> gPeiLockPhysicalPresencePpiGuid ##
> SOMETIMES_CONSUMES ## NOTIFY
> diff --git a/SecurityPkg/Tcg/TcgPei/TcgPei.c b/SecurityPkg/Tcg/TcgPei/TcgPei.c
> index a9a808c9ecf3..9701bfe8715b 100644
> --- a/SecurityPkg/Tcg/TcgPei/TcgPei.c
> +++ b/SecurityPkg/Tcg/TcgPei/TcgPei.c
> @@ -21,6 +21,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
> #include <Guid/TcgEventHob.h>
> #include <Guid/MeasuredFvHob.h>
> #include <Guid/TpmInstance.h>
> +#include <Guid/MigratedFvInfo.h>
>
> #include <Library/DebugLib.h>
> #include <Library/BaseMemoryLib.h>
> @@ -378,6 +379,10 @@ MeasureFvImage (
> EFI_STATUS Status;
> EFI_PLATFORM_FIRMWARE_BLOB FvBlob;
> TCG_PCR_EVENT_HDR TcgEventHdr;
> + EFI_PHYSICAL_ADDRESS FvOrgBase;
> + EFI_PHYSICAL_ADDRESS FvDataBase;
> + EFI_PEI_HOB_POINTERS Hob;
> + EDKII_MIGRATED_FV_INFO *MigratedFvInfo;
>
> //
> // Check if it is in Excluded FV list
> @@ -401,10 +406,30 @@ MeasureFvImage (
> }
> }
>
> + //
> + // Search the matched migration FV info
> + //
> + FvOrgBase = FvBase;
> + FvDataBase = FvBase;
> + Hob.Raw = GetFirstGuidHob (&gEdkiiMigratedFvInfoGuid);
> + while (Hob.Raw != NULL) {
> + MigratedFvInfo = GET_GUID_HOB_DATA (Hob);
> + if ((MigratedFvInfo->FvNewBase == (UINT32) FvBase) && (MigratedFvInfo-
> >FvLength == (UINT32) FvLength)) {
> + //
> + // Found the migrated FV info
> + //
> + FvOrgBase = (EFI_PHYSICAL_ADDRESS) (UINTN) MigratedFvInfo-
> >FvOrgBase;
> + FvDataBase = (EFI_PHYSICAL_ADDRESS) (UINTN) MigratedFvInfo-
> >FvDataBase;
> + break;
> + }
> + Hob.Raw = GET_NEXT_HOB (Hob);
> + Hob.Raw = GetNextGuidHob (&gEdkiiMigratedFvInfoGuid, Hob.Raw);
> + }
> +
> //
> // Measure and record the FV to the TPM
> //
> - FvBlob.BlobBase = FvBase;
> + FvBlob.BlobBase = FvOrgBase;
> FvBlob.BlobLength = FvLength;
>
> DEBUG ((DEBUG_INFO, "The FV which is measured by TcgPei starts at: 0x%x\n",
> FvBlob.BlobBase));
> @@ -416,7 +441,7 @@ MeasureFvImage (
>
> Status = HashLogExtendEvent (
> (EFI_PEI_SERVICES **) GetPeiServicesTablePointer(),
> - (UINT8*) (UINTN) FvBlob.BlobBase,
> + (UINT8*) (UINTN) FvDataBase,
> (UINTN) FvBlob.BlobLength,
> &TcgEventHdr,
> (UINT8*) &FvBlob
> --
> 2.25.1.windows.1
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [edk2-devel] [PATCH v5 0/9] Add new feature that evacuate temporary to permanent memory (CVE-2019-11098)
2020-07-09 1:56 [PATCH v5 0/9] Add new feature that evacuate temporary to permanent memory (CVE-2019-11098) Guomin Jiang
` (8 preceding siblings ...)
2020-07-09 1:56 ` [PATCH v5 9/9] SecurityPkg/TcgPei: Use Migrated FV Info Hob for calculating hash (CVE-2019-11098) Guomin Jiang
@ 2020-07-10 5:46 ` Laszlo Ersek
2020-07-10 6:57 ` Guomin Jiang
9 siblings, 1 reply; 24+ messages in thread
From: Laszlo Ersek @ 2020-07-10 5:46 UTC (permalink / raw)
To: devel, guomin.jiang
Cc: Jian J Wang, Hao A Wu, Dandan Bi, Liming Gao, Debkumar De,
Harry Han, Catharine West, Eric Dong, Ray Ni, Jordan Justen,
Andrew Fish, Ard Biesheuvel, Anthony Perard, Julien Grall,
Leif Lindholm, Rahul Kumar, Jiewen Yao, Chao Zhang, Qi Zhang
Guomin,
On 07/09/20 03:56, Guomin Jiang wrote:
> The TOCTOU vulnerability allow that the physical present person to replace the code with the normal BootGuard check and PCR0 value.
> The issue occur when BootGuard measure IBB and access flash code after NEM disable.
> the reason why we access the flash code is that we have some pointer to flash.
> To avoid this vulnerability, we need to convert those pointers, the patch series do this work and make sure that no code will access flash address.
>
> v2:
> Create gEdkiiMigratedFvInfoGuid HOB and add PcdMigrateTemporaryRamFirmwareVolumes to control whole feature.
>
> v3:
> Remove changes which is not related with the feature and disable the feature in virtual platform.
>
> v4:
> Disable the feature as default, Copy the Tcg2Pei behavior to TcgPei
>
> v5:
> Initialize local variable Shadow and return EFI_ABORTED when RepublishSecPpi not installed.
When you post a new version of a patch set to the list, and there is an
associated BZ ticket, please *always* (not just for this BZ) capture the
fact of posting the next version in a new BZ comment. Please record the
version of the patch series being posted, and also include a link to the
series blurb (patch 0), in the mailing list archive.
I did that for you, covering the first four versions (v1 throuogh v4) of
the series in comment 16 on TianoCore#1614:
https://bugzilla.tianocore.org/show_bug.cgi?id=1614#c16
Please do the same (in a new BZ comment) for the current version (v5),
and please repeat the same for any further versions.
Again this applies to all BZs and all posted patches.
Thanks
Laszlo
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [edk2-devel] [PATCH v5 0/9] Add new feature that evacuate temporary to permanent memory (CVE-2019-11098)
2020-07-10 5:46 ` [edk2-devel] [PATCH v5 0/9] Add new feature that evacuate temporary to permanent memory (CVE-2019-11098) Laszlo Ersek
@ 2020-07-10 6:57 ` Guomin Jiang
0 siblings, 0 replies; 24+ messages in thread
From: Guomin Jiang @ 2020-07-10 6:57 UTC (permalink / raw)
To: Laszlo Ersek, devel@edk2.groups.io
Cc: Wang, Jian J, Wu, Hao A, Bi, Dandan, Gao, Liming, De, Debkumar,
Han, Harry, West, Catharine, Dong, Eric, Ni, Ray,
Justen, Jordan L, Andrew Fish, Ard Biesheuvel, Anthony Perard,
Julien Grall, Leif Lindholm, Kumar, Rahul1, Yao, Jiewen,
Zhang, Chao B, Zhang, Qi1
I see it and will do it later.
I remind that everyone should pay attention to it as well.
Thanks.
> -----Original Message-----
> From: Laszlo Ersek <lersek@redhat.com>
> Sent: Friday, July 10, 2020 1:47 PM
> To: devel@edk2.groups.io; Jiang, Guomin <guomin.jiang@intel.com>
> Cc: Wang, Jian J <jian.j.wang@intel.com>; Wu, Hao A
> <hao.a.wu@intel.com>; Bi, Dandan <dandan.bi@intel.com>; Gao, Liming
> <liming.gao@intel.com>; De, Debkumar <debkumar.de@intel.com>; Han,
> Harry <harry.han@intel.com>; West, Catharine <catharine.west@intel.com>;
> Dong, Eric <eric.dong@intel.com>; Ni, Ray <ray.ni@intel.com>; Justen,
> Jordan L <jordan.l.justen@intel.com>; Andrew Fish <afish@apple.com>; Ard
> Biesheuvel <ard.biesheuvel@arm.com>; Anthony Perard
> <anthony.perard@citrix.com>; Julien Grall <julien@xen.org>; Leif Lindholm
> <leif@nuviainc.com>; Kumar, Rahul1 <rahul1.kumar@intel.com>; Yao,
> Jiewen <jiewen.yao@intel.com>; Zhang, Chao B <chao.b.zhang@intel.com>;
> Zhang, Qi1 <qi1.zhang@intel.com>
> Subject: Re: [edk2-devel] [PATCH v5 0/9] Add new feature that evacuate
> temporary to permanent memory (CVE-2019-11098)
>
> Guomin,
>
> On 07/09/20 03:56, Guomin Jiang wrote:
> > The TOCTOU vulnerability allow that the physical present person to replace
> the code with the normal BootGuard check and PCR0 value.
> > The issue occur when BootGuard measure IBB and access flash code after
> NEM disable.
> > the reason why we access the flash code is that we have some pointer to
> flash.
> > To avoid this vulnerability, we need to convert those pointers, the patch
> series do this work and make sure that no code will access flash address.
> >
> > v2:
> > Create gEdkiiMigratedFvInfoGuid HOB and add
> PcdMigrateTemporaryRamFirmwareVolumes to control whole feature.
> >
> > v3:
> > Remove changes which is not related with the feature and disable the
> feature in virtual platform.
> >
> > v4:
> > Disable the feature as default, Copy the Tcg2Pei behavior to TcgPei
> >
> > v5:
> > Initialize local variable Shadow and return EFI_ABORTED when
> RepublishSecPpi not installed.
>
> When you post a new version of a patch set to the list, and there is an
> associated BZ ticket, please *always* (not just for this BZ) capture the fact of
> posting the next version in a new BZ comment. Please record the version of
> the patch series being posted, and also include a link to the series blurb
> (patch 0), in the mailing list archive.
>
> I did that for you, covering the first four versions (v1 throuogh v4) of the
> series in comment 16 on TianoCore#1614:
>
> https://bugzilla.tianocore.org/show_bug.cgi?id=1614#c16
>
> Please do the same (in a new BZ comment) for the current version (v5), and
> please repeat the same for any further versions.
>
> Again this applies to all BZs and all posted patches.
>
> Thanks
> Laszlo
^ permalink raw reply [flat|nested] 24+ messages in thread