]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/Pei/Image/Image.c
MdeModulePkg/PeiCore: Enable T-RAM evacuation in PeiCore (CVE-2019-11098)
[mirror_edk2.git] / MdeModulePkg / Core / Pei / Image / Image.c
index e3ee3699337fb57d04f229b002dd6cf08ce11c1e..1d15774527474474a7c0b6972bef5639990066e7 100644 (file)
@@ -328,8 +328,11 @@ LoadAndRelocatePeCoffImage (
   //\r
   // When Image has no reloc section, it can't be relocated into memory.\r
   //\r
-  if (ImageContext.RelocationsStripped && (Private->PeiMemoryInstalled) && ((!IsPeiModule) ||\r
-      (!IsS3Boot && (PcdGetBool (PcdShadowPeimOnBoot) || IsRegisterForShadow)) || (IsS3Boot && PcdGetBool (PcdShadowPeimOnS3Boot)))) {\r
+  if (ImageContext.RelocationsStripped && (Private->PeiMemoryInstalled) &&\r
+      ((!IsPeiModule) || PcdGetBool (PcdMigrateTemporaryRamFirmwareVolumes) ||\r
+       (!IsS3Boot && (PcdGetBool (PcdShadowPeimOnBoot) || IsRegisterForShadow)) ||\r
+       (IsS3Boot && PcdGetBool (PcdShadowPeimOnS3Boot)))\r
+     ) {\r
     DEBUG ((EFI_D_INFO|EFI_D_LOAD, "The image at 0x%08x without reloc section can't be loaded into memory\n", (UINTN) Pe32Data));\r
   }\r
 \r
@@ -343,8 +346,11 @@ LoadAndRelocatePeCoffImage (
   // On normal boot, PcdShadowPeimOnBoot decides whether load PEIM or PeiCore into memory.\r
   // On S3 boot, PcdShadowPeimOnS3Boot decides whether load PEIM or PeiCore into memory.\r
   //\r
-  if ((!ImageContext.RelocationsStripped) && (Private->PeiMemoryInstalled) && ((!IsPeiModule) ||\r
-      (!IsS3Boot && (PcdGetBool (PcdShadowPeimOnBoot) || IsRegisterForShadow)) || (IsS3Boot && PcdGetBool (PcdShadowPeimOnS3Boot)))) {\r
+  if ((!ImageContext.RelocationsStripped) && (Private->PeiMemoryInstalled) &&\r
+      ((!IsPeiModule) || PcdGetBool (PcdMigrateTemporaryRamFirmwareVolumes) ||\r
+       (!IsS3Boot && (PcdGetBool (PcdShadowPeimOnBoot) || IsRegisterForShadow)) ||\r
+       (IsS3Boot && PcdGetBool (PcdShadowPeimOnS3Boot)))\r
+     ) {\r
     //\r
     // Allocate more buffer to avoid buffer overflow.\r
     //\r
@@ -444,6 +450,122 @@ LoadAndRelocatePeCoffImage (
   return ReturnStatus;\r
 }\r
 \r
+/**\r
+  Loads and relocates a PE/COFF image in place.\r
+\r
+  @param Pe32Data         The base address of the PE/COFF file that is to be loaded and relocated\r
+  @param ImageAddress     The base address of the relocated PE/COFF image\r
+\r
+  @retval EFI_SUCCESS     The file was loaded and relocated.\r
+  @retval Others          The file not be loaded and error occurred.\r
+\r
+**/\r
+EFI_STATUS\r
+LoadAndRelocatePeCoffImageInPlace (\r
+  IN  VOID    *Pe32Data,\r
+  IN  VOID    *ImageAddress\r
+  )\r
+{\r
+  EFI_STATUS                      Status;\r
+  PE_COFF_LOADER_IMAGE_CONTEXT    ImageContext;\r
+\r
+  ZeroMem (&ImageContext, sizeof (ImageContext));\r
+  ImageContext.Handle = Pe32Data;\r
+  ImageContext.ImageRead = PeiImageRead;\r
+\r
+  Status = PeCoffLoaderGetImageInfo (&ImageContext);\r
+  if (EFI_ERROR (Status)) {\r
+    ASSERT_EFI_ERROR (Status);\r
+    return Status;\r
+  }\r
+\r
+  ImageContext.ImageAddress   = (PHYSICAL_ADDRESS)(UINTN) ImageAddress;\r
+\r
+  //\r
+  // Load the image in place\r
+  //\r
+  Status = PeCoffLoaderLoadImage (&ImageContext);\r
+  if (EFI_ERROR (Status)) {\r
+    ASSERT_EFI_ERROR (Status);\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Relocate the image in place\r
+  //\r
+  Status = PeCoffLoaderRelocateImage (&ImageContext);\r
+  if (EFI_ERROR (Status)) {\r
+    ASSERT_EFI_ERROR (Status);\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Flush the instruction cache so the image data is written before we execute it\r
+  //\r
+  if (ImageContext.ImageAddress != (EFI_PHYSICAL_ADDRESS)(UINTN) Pe32Data) {\r
+    InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Find the PE32 Data for an FFS file.\r
+\r
+  @param FileHandle       Pointer to the FFS file header of the image.\r
+  @param Pe32Data         Pointer to a (VOID *) PE32 Data pointer.\r
+\r
+  @retval EFI_SUCCESS      Image is successfully loaded.\r
+  @retval EFI_NOT_FOUND    Fail to locate PE32 Data.\r
+\r
+**/\r
+EFI_STATUS\r
+PeiGetPe32Data (\r
+  IN     EFI_PEI_FILE_HANDLE  FileHandle,\r
+  OUT    VOID                 **Pe32Data\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  EFI_SECTION_TYPE            SearchType1;\r
+  EFI_SECTION_TYPE            SearchType2;\r
+  UINT32                      AuthenticationState;\r
+\r
+  *Pe32Data = NULL;\r
+\r
+  if (FeaturePcdGet (PcdPeiCoreImageLoaderSearchTeSectionFirst)) {\r
+    SearchType1 = EFI_SECTION_TE;\r
+    SearchType2 = EFI_SECTION_PE32;\r
+  } else {\r
+    SearchType1 = EFI_SECTION_PE32;\r
+    SearchType2 = EFI_SECTION_TE;\r
+  }\r
+\r
+  //\r
+  // Try to find a first exe section (if PcdPeiCoreImageLoaderSearchTeSectionFirst\r
+  // is true, TE will be searched first).\r
+  //\r
+  Status = PeiServicesFfsFindSectionData3 (\r
+             SearchType1,\r
+             0,\r
+             FileHandle,\r
+             Pe32Data,\r
+             &AuthenticationState\r
+             );\r
+  //\r
+  // If we didn't find a first exe section, try to find the second exe section.\r
+  //\r
+  if (EFI_ERROR (Status)) {\r
+    Status = PeiServicesFfsFindSectionData3 (\r
+               SearchType2,\r
+               0,\r
+               FileHandle,\r
+               Pe32Data,\r
+               &AuthenticationState\r
+               );\r
+  }\r
+  return Status;\r
+}\r
+\r
 /**\r
   Loads a PEIM into memory for subsequent execution. If there are compressed\r
   images or images that need to be relocated into memory for performance reasons,\r