]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/DxeIplPeim/DxeLoad.c
Add logic to validate variable before use it.
[mirror_edk2.git] / MdeModulePkg / Core / DxeIplPeim / DxeLoad.c
index 3c9ed7c23545a194389374f613d1fefdb88a90d0..dea627e16282afc88bb9c5bb61c6c3d7468c4346 100644 (file)
@@ -2,8 +2,8 @@
   Last PEIM.\r
   Responsibility of this module is to load the DXE Core from a Firmware Volume.\r
 \r
-Copyright (c) 2006 - 2009, Intel Corporation. <BR>\r
-All rights reserved. This program and the accompanying materials\r
+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
 http://opensource.org/licenses/bsd-license.php\r
@@ -124,6 +124,53 @@ PeimInitializeDxeIpl (
   return Status;\r
 }\r
 \r
+/**\r
+   Validate variable data for the MemoryTypeInformation. \r
+\r
+   @param MemoryData       Variable data.\r
+   @param MemoryDataSize   Variable data length.\r
+\r
+   @return TRUE            The variable data is valid.\r
+   @return FALSE           The variable data is invalid.\r
+\r
+**/\r
+BOOLEAN\r
+ValidateMemoryTypeInfoVariable (\r
+  IN EFI_MEMORY_TYPE_INFORMATION      *MemoryData,\r
+  IN UINTN                            MemoryDataSize\r
+  )\r
+{\r
+  UINTN                       Count;\r
+  UINTN                       Index;\r
+\r
+  // Check the input parameter.\r
+  if (MemoryData == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  // Get Count\r
+  Count = MemoryDataSize / sizeof (*MemoryData);\r
+\r
+  // Check Size\r
+  if (Count * sizeof(*MemoryData) != MemoryDataSize) {\r
+    return FALSE;\r
+  }\r
+\r
+  // Check last entry type filed.\r
+  if (MemoryData[Count - 1].Type != EfiMaxMemoryType) {\r
+    return FALSE;\r
+  }\r
+\r
+  // Check the type filed.\r
+  for (Index = 0; Index < Count - 1; Index++) {\r
+    if (MemoryData[Index].Type >= EfiMaxMemoryType) {\r
+      return FALSE;\r
+    }\r
+  }\r
+\r
+  return TRUE;\r
+}\r
+\r
 /**\r
    Main entry point to last PEIM. \r
 \r
@@ -158,7 +205,7 @@ DxeLoadCore (
   UINTN                                     Instance;\r
   UINT32                                    AuthenticationState;\r
   UINTN                                     DataSize;\r
-  EFI_PEI_S3_RESUME_PPI                     *S3Resume;\r
+  EFI_PEI_S3_RESUME2_PPI                    *S3Resume;\r
   EFI_PEI_RECOVERY_MODULE_PPI               *PeiRecovery;\r
   EFI_MEMORY_TYPE_INFORMATION               MemoryData[EfiMaxMemoryType + 1];\r
 \r
@@ -169,14 +216,14 @@ DxeLoadCore (
 \r
   if (BootMode == BOOT_ON_S3_RESUME) {\r
     Status = PeiServicesLocatePpi (\r
-               &gEfiPeiS3ResumePpiGuid,\r
+               &gEfiPeiS3Resume2PpiGuid,\r
                0,\r
                NULL,\r
                (VOID **) &S3Resume\r
                );\r
     ASSERT_EFI_ERROR (Status);\r
     \r
-    Status = S3Resume->S3RestoreConfig (PeiServices);\r
+    Status = S3Resume->S3RestoreConfig2 (S3Resume);\r
     ASSERT_EFI_ERROR (Status);\r
   } else if (BootMode == BOOT_IN_RECOVERY_MODE) {\r
     Status = PeiServicesLocatePpi (\r
@@ -214,7 +261,7 @@ DxeLoadCore (
                          &DataSize,\r
                          &MemoryData\r
                          );\r
-    if (!EFI_ERROR (Status)) {\r
+    if (!EFI_ERROR (Status) && ValidateMemoryTypeInfoVariable(MemoryData, DataSize)) {\r
       //\r
       // Build the GUID'd HOB for DXE\r
       //\r
@@ -271,7 +318,7 @@ DxeLoadCore (
   //\r
   // Report Status Code EFI_SW_PEI_PC_HANDOFF_TO_NEXT\r
   //\r
-  REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PcdGet32 (PcdStatusCodeValuePeiHandoffToDxe));\r
+  REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_CORE | EFI_SW_PEI_CORE_PC_HANDOFF_TO_NEXT));\r
 \r
   DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Loading DXE CORE at 0x%11p EntryPoint=0x%11p\n", (VOID *)(UINTN)DxeCoreAddress, FUNCTION_ENTRY_POINT (DxeCoreEntryPoint)));\r
 \r
@@ -318,6 +365,9 @@ DxeIplFindDxeCore (
     // If some error occurs here, then we cannot find any firmware\r
     // volume that may contain DxeCore.\r
     //\r
+    if (EFI_ERROR (Status)) {\r
+      REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_CORE_EC_DXE_CORRUPT));\r
+    }\r
     ASSERT_EFI_ERROR (Status);\r
     \r
     //\r
@@ -510,23 +560,34 @@ Decompress (
   EFI_STATUS                      Status;\r
   UINT8                           *DstBuffer;\r
   UINT8                           *ScratchBuffer;\r
-  UINT                          DstBufferSize;\r
+  UINT32                          DstBufferSize;\r
   UINT32                          ScratchBufferSize;\r
-  EFI_COMMON_SECTION_HEADER       *Section;\r
-  UINTN                           SectionLength;\r
+  VOID                            *CompressionSource;\r
+  UINT32                          CompressionSourceSize;\r
+  UINT32                          UncompressedLength;\r
+  UINT8                           CompressionType;\r
 \r
   if (CompressionSection->CommonHeader.Type != EFI_SECTION_COMPRESSION) {\r
     ASSERT (FALSE);\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  Section = (EFI_COMMON_SECTION_HEADER *) CompressionSection;\r
-  SectionLength = *(UINT32 *) (Section->Size) & 0x00ffffff;\r
+  if (IS_SECTION2 (CompressionSection)) {\r
+    CompressionSource = (VOID *) ((UINT8 *) CompressionSection + sizeof (EFI_COMPRESSION_SECTION2));\r
+    CompressionSourceSize = (UINT32) (SECTION2_SIZE (CompressionSection) - sizeof (EFI_COMPRESSION_SECTION2));\r
+    UncompressedLength = ((EFI_COMPRESSION_SECTION2 *) CompressionSection)->UncompressedLength;\r
+    CompressionType = ((EFI_COMPRESSION_SECTION2 *) CompressionSection)->CompressionType;\r
+  } else {\r
+    CompressionSource = (VOID *) ((UINT8 *) CompressionSection + sizeof (EFI_COMPRESSION_SECTION));\r
+    CompressionSourceSize = (UINT32) (SECTION_SIZE (CompressionSection) - sizeof (EFI_COMPRESSION_SECTION));\r
+    UncompressedLength = CompressionSection->UncompressedLength;\r
+    CompressionType = CompressionSection->CompressionType;\r
+  }\r
   \r
   //\r
   // This is a compression set, expand it\r
   //\r
-  switch (CompressionSection->CompressionType) {\r
+  switch (CompressionType) {\r
   case EFI_STANDARD_COMPRESSION:\r
     if (FeaturePcdGet(PcdDxeIplSupportUefiDecompress)) {\r
       //\r
@@ -534,9 +595,9 @@ Decompress (
       // For compressed data, decompress them to destination buffer.\r
       //\r
       Status = UefiDecompressGetInfo (\r
-                 (UINT8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),\r
-                 (UINT32) SectionLength - sizeof (EFI_COMPRESSION_SECTION),\r
-                 (UINT32 *) &DstBufferSize,\r
+                 CompressionSource,\r
+                 CompressionSourceSize,\r
+                 &DstBufferSize,\r
                  &ScratchBufferSize\r
                  );\r
       if (EFI_ERROR (Status)) {\r
@@ -569,7 +630,7 @@ Decompress (
       // Call decompress function\r
       //\r
       Status = UefiDecompress (\r
-                  (CHAR8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),\r
+                  CompressionSource,\r
                   DstBuffer,\r
                   ScratchBuffer\r
                   );\r
@@ -594,7 +655,7 @@ Decompress (
     //\r
     // Allocate destination buffer\r
     //\r
-    DstBufferSize = CompressionSection->UncompressedLength;\r
+    DstBufferSize = UncompressedLength;\r
     DstBuffer     = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize) + 1);\r
     if (DstBuffer == NULL) {\r
       return EFI_OUT_OF_RESOURCES;\r
@@ -607,7 +668,7 @@ Decompress (
     //\r
     // stream is not actually compressed, just encapsulated.  So just copy it.\r
     //\r
-    CopyMem (DstBuffer, CompressionSection + 1, DstBufferSize);\r
+    CopyMem (DstBuffer, CompressionSource, DstBufferSize);\r
     break;\r
 \r
   default:\r
@@ -647,13 +708,14 @@ UpdateStackHob (
   while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) {\r
     if (CompareGuid (&gEfiHobMemoryAllocStackGuid, &(Hob.MemoryAllocationStack->AllocDescriptor.Name))) {\r
       //\r
-      // Build a new memory allocation HOB with old stack info with EfiConventionalMemory type\r
-      // to be reclaimed by DXE core.\r
+      // Build a new memory allocation HOB with old stack info with EfiBootServicesData type. Need to \r
+      // avoid this region be reclaimed by DXE core as the IDT built in SEC might be on stack, and some \r
+      // PEIMs may also keep key information on stack\r
       //\r
       BuildMemoryAllocationHob (\r
         Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress,\r
         Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength,\r
-        EfiConventionalMemory\r
+        EfiBootServicesData\r
         );\r
       //\r
       // Update the BSP Stack Hob to reflect the new stack info.\r