]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/PiSmmCore/MemoryAttributesTable.c
MdeModulePkg: Fix use-after-free error in InstallConfigurationTable()
[mirror_edk2.git] / MdeModulePkg / Core / PiSmmCore / MemoryAttributesTable.c
index 3a5a2c8743738f2fa711e88561ae3bdbe3c63b19..e3c505ef18abf9b31f1f1f1b4019225525f71076 100644 (file)
@@ -138,7 +138,7 @@ SmmMemoryAttributesTableConsistencyCheck (
     if (Address != 0) {\r
       ASSERT (Address == MemoryMap->PhysicalStart);\r
     }\r
-    Address = MemoryMap->PhysicalStart + EFI_PAGES_TO_SIZE(MemoryMap->NumberOfPages);\r
+    Address = MemoryMap->PhysicalStart + EfiPagesToSize(MemoryMap->NumberOfPages);\r
     MemoryMap = NEXT_MEMORY_DESCRIPTOR(MemoryMap, DescriptorSize);\r
   }\r
 }\r
@@ -146,10 +146,10 @@ SmmMemoryAttributesTableConsistencyCheck (
 /**\r
   Sort memory map entries based upon PhysicalStart, from low to high.\r
 \r
-  @param[in]  MemoryMap              A pointer to the buffer in which firmware places\r
-                                 the current memory map.\r
-  @param[in]  MemoryMapSize          Size, in bytes, of the MemoryMap buffer.\r
-  @param[in]  DescriptorSize         Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.\r
+  @param[in,out]  MemoryMap         A pointer to the buffer in which firmware places\r
+                                    the current memory map.\r
+  @param[in]      MemoryMapSize     Size, in bytes, of the MemoryMap buffer.\r
+  @param[in]      DescriptorSize    Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.\r
 **/\r
 STATIC\r
 VOID\r
@@ -268,15 +268,19 @@ EnforceMemoryMapAttribute (
   MemoryMapEntry = MemoryMap;\r
   MemoryMapEnd   = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) MemoryMap + MemoryMapSize);\r
   while ((UINTN)MemoryMapEntry < (UINTN)MemoryMapEnd) {\r
-    switch (MemoryMapEntry->Type) {\r
-    case EfiRuntimeServicesCode:\r
-      MemoryMapEntry->Attribute |= EFI_MEMORY_RO;\r
-      break;\r
-    case EfiRuntimeServicesData:\r
-      MemoryMapEntry->Attribute |= EFI_MEMORY_XP;\r
-      break;\r
+    if (MemoryMapEntry->Attribute != 0) {\r
+      // It is PE image, the attribute is already set.\r
+    } else {\r
+      switch (MemoryMapEntry->Type) {\r
+      case EfiRuntimeServicesCode:\r
+        MemoryMapEntry->Attribute = EFI_MEMORY_RO;\r
+        break;\r
+      case EfiRuntimeServicesData:\r
+      default:\r
+        MemoryMapEntry->Attribute |= EFI_MEMORY_XP;\r
+        break;\r
+      }\r
     }\r
-\r
     MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);\r
   }\r
 \r
@@ -358,6 +362,21 @@ SetNewRecord (
   PhysicalEnd = TempRecord.PhysicalStart + EfiPagesToSize(TempRecord.NumberOfPages);\r
   NewRecordCount = 0;\r
 \r
+  //\r
+  // Always create a new entry for non-PE image record\r
+  //\r
+  if (ImageRecord->ImageBase > TempRecord.PhysicalStart) {\r
+    NewRecord->Type = TempRecord.Type;\r
+    NewRecord->PhysicalStart = TempRecord.PhysicalStart;\r
+    NewRecord->VirtualStart  = 0;\r
+    NewRecord->NumberOfPages = EfiSizeToPages(ImageRecord->ImageBase - TempRecord.PhysicalStart);\r
+    NewRecord->Attribute     = TempRecord.Attribute;\r
+    NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);\r
+    NewRecordCount ++;\r
+    TempRecord.PhysicalStart = ImageRecord->ImageBase;\r
+    TempRecord.NumberOfPages = EfiSizeToPages(PhysicalEnd - TempRecord.PhysicalStart);\r
+  }\r
+\r
   ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList;\r
 \r
   ImageRecordCodeSectionLink = ImageRecordCodeSectionList->ForwardLink;\r
@@ -452,14 +471,10 @@ GetMaxSplitRecordCount (
     if (ImageRecord == NULL) {\r
       break;\r
     }\r
-    SplitRecordCount += (2 * ImageRecord->CodeSegmentCount + 1);\r
+    SplitRecordCount += (2 * ImageRecord->CodeSegmentCount + 2);\r
     PhysicalStart = ImageRecord->ImageBase + ImageRecord->ImageSize;\r
   } while ((ImageRecord != NULL) && (PhysicalStart < PhysicalEnd));\r
 \r
-  if (SplitRecordCount != 0) {\r
-    SplitRecordCount--;\r
-  }\r
-\r
   return SplitRecordCount;\r
 }\r
 \r
@@ -516,28 +531,16 @@ SplitRecord (
       //\r
       // No more image covered by this range, stop\r
       //\r
-      if ((PhysicalEnd > PhysicalStart) && (ImageRecord != NULL)) {\r
+      if (PhysicalEnd > PhysicalStart) {\r
         //\r
-        // If this is still address in this record, need record.\r
+        // Always create a new entry for non-PE image record\r
         //\r
-        NewRecord = PREVIOUS_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);\r
-        if (NewRecord->Type == EfiRuntimeServicesData) {\r
-          //\r
-          // Last record is DATA, just merge it.\r
-          //\r
-          NewRecord->NumberOfPages = EfiSizeToPages(PhysicalEnd - NewRecord->PhysicalStart);\r
-        } else {\r
-          //\r
-          // Last record is CODE, create a new DATA entry.\r
-          //\r
-          NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);\r
-          NewRecord->Type = EfiRuntimeServicesData;\r
-          NewRecord->PhysicalStart = TempRecord.PhysicalStart;\r
-          NewRecord->VirtualStart  = 0;\r
-          NewRecord->NumberOfPages = TempRecord.NumberOfPages;\r
-          NewRecord->Attribute     = TempRecord.Attribute | EFI_MEMORY_XP;\r
-          TotalNewRecordCount ++;\r
-        }\r
+        NewRecord->Type = TempRecord.Type;\r
+        NewRecord->PhysicalStart = TempRecord.PhysicalStart;\r
+        NewRecord->VirtualStart  = 0;\r
+        NewRecord->NumberOfPages = TempRecord.NumberOfPages;\r
+        NewRecord->Attribute     = TempRecord.Attribute;\r
+        TotalNewRecordCount ++;\r
       }\r
       break;\r
     }\r
@@ -580,6 +583,8 @@ SplitRecord (
    ==>\r
    +---------------+\r
    | Record X      |\r
+   +---------------+\r
+   | Record RtCode |\r
    +---------------+ ----\r
    | Record RtData |     |\r
    +---------------+     |\r
@@ -587,12 +592,16 @@ SplitRecord (
    +---------------+     |\r
    | Record RtData |     |\r
    +---------------+ ----\r
+   | Record RtCode |\r
+   +---------------+ ----\r
    | Record RtData |     |\r
    +---------------+     |\r
    | Record RtCode |     |-> PE/COFF2\r
    +---------------+     |\r
    | Record RtData |     |\r
    +---------------+ ----\r
+   | Record RtCode |\r
+   +---------------+\r
    | Record Y      |\r
    +---------------+\r
 \r
@@ -622,7 +631,7 @@ SplitTable (
   UINTN       TotalSplitRecordCount;\r
   UINTN       AdditionalRecordCount;\r
 \r
-  AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 1) * mImagePropertiesPrivateData.ImageRecordCount;\r
+  AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 2) * mImagePropertiesPrivateData.ImageRecordCount;\r
 \r
   TotalSplitRecordCount = 0;\r
   //\r
@@ -648,11 +657,13 @@ SplitTable (
     //\r
     // Adjust IndexNew according to real split.\r
     //\r
-    CopyMem (\r
-      ((UINT8 *)MemoryMap + (IndexNew + MaxSplitRecordCount - RealSplitRecordCount) * DescriptorSize),\r
-      ((UINT8 *)MemoryMap + IndexNew * DescriptorSize),\r
-      RealSplitRecordCount * DescriptorSize\r
-      );\r
+    if (MaxSplitRecordCount != RealSplitRecordCount) {\r
+      CopyMem (\r
+        ((UINT8 *)MemoryMap + (IndexNew + MaxSplitRecordCount - RealSplitRecordCount) * DescriptorSize),\r
+        ((UINT8 *)MemoryMap + IndexNew * DescriptorSize),\r
+        (RealSplitRecordCount + 1) * DescriptorSize\r
+        );\r
+    }\r
     IndexNew = IndexNew + MaxSplitRecordCount - RealSplitRecordCount;\r
     TotalSplitRecordCount += RealSplitRecordCount;\r
     IndexNew --;\r
@@ -744,7 +755,7 @@ SmmCoreGetMemoryMapMemoryAttributesTable (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 1) * mImagePropertiesPrivateData.ImageRecordCount;\r
+  AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 2) * mImagePropertiesPrivateData.ImageRecordCount;\r
 \r
   OldMemoryMapSize = *MemoryMapSize;\r
   Status = SmmCoreGetMemoryMap (MemoryMapSize, MemoryMap, MapKey, DescriptorSize, DescriptorVersion);\r
@@ -774,7 +785,7 @@ SmmCoreGetMemoryMapMemoryAttributesTable (
 //\r
 \r
 /**\r
-  Set MemoryProtectionAttribute accroding to PE/COFF image section alignment.\r
+  Set MemoryProtectionAttribute according to PE/COFF image section alignment.\r
 \r
   @param[in]  SectionAlignment    PE/COFF section alignment\r
 **/\r
@@ -784,7 +795,7 @@ SetMemoryAttributesTableSectionAlignment (
   IN UINT32  SectionAlignment\r
   )\r
 {\r
-  if (((SectionAlignment & (EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT - 1)) != 0) &&\r
+  if (((SectionAlignment & (RUNTIME_PAGE_ALLOCATION_GRANULARITY - 1)) != 0) &&\r
       ((mMemoryProtectionAttribute & EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA) != 0)) {\r
     DEBUG ((DEBUG_VERBOSE, "SMM SetMemoryAttributesTableSectionAlignment - Clear\n"));\r
     mMemoryProtectionAttribute &= ~((UINT64)EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA);\r
@@ -1066,7 +1077,7 @@ SmmInsertImageRecord (
   // Step 1: record whole region\r
   //\r
   ImageRecord->ImageBase = DriverEntry->ImageBuffer;\r
-  ImageRecord->ImageSize = EFI_PAGES_TO_SIZE(DriverEntry->NumberOfPage);\r
+  ImageRecord->ImageSize = EfiPagesToSize(DriverEntry->NumberOfPage);\r
 \r
   ImageAddress = (VOID *)(UINTN)DriverEntry->ImageBuffer;\r
 \r
@@ -1114,12 +1125,12 @@ SmmInsertImageRecord (
   }\r
 \r
   SetMemoryAttributesTableSectionAlignment (SectionAlignment);\r
-  if ((SectionAlignment & (EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT - 1)) != 0) {\r
-    DEBUG ((DEBUG_ERROR, "SMM !!!!!!!!  InsertImageRecord - Section Alignment(0x%x) is not %dK  !!!!!!!!\n",\r
-      SectionAlignment, EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT >> 10));\r
+  if ((SectionAlignment & (RUNTIME_PAGE_ALLOCATION_GRANULARITY - 1)) != 0) {\r
+    DEBUG ((DEBUG_WARN, "SMM !!!!!!!!  InsertImageRecord - Section Alignment(0x%x) is not %dK  !!!!!!!!\n",\r
+      SectionAlignment, RUNTIME_PAGE_ALLOCATION_GRANULARITY >> 10));\r
     PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageAddress);\r
     if (PdbPointer != NULL) {\r
-      DEBUG ((DEBUG_ERROR, "SMM !!!!!!!!  Image - %a  !!!!!!!!\n", PdbPointer));\r
+      DEBUG ((DEBUG_WARN, "SMM !!!!!!!!  Image - %a  !!!!!!!!\n", PdbPointer));\r
     }\r
     goto Finish;\r
   }\r
@@ -1214,7 +1225,7 @@ Finish:
 }\r
 \r
 /**\r
-  Find image record accroding to image base and size.\r
+  Find image record according to image base and size.\r
 \r
   @param[in]  ImageBase    Base of PE image\r
   @param[in]  ImageSize    Size of PE image\r
@@ -1270,7 +1281,7 @@ SmmRemoveImageRecord (
   DEBUG ((DEBUG_VERBOSE, "SMM RemoveImageRecord - 0x%x\n", DriverEntry));\r
   DEBUG ((DEBUG_VERBOSE, "SMM RemoveImageRecord - 0x%016lx - 0x%016lx\n", DriverEntry->ImageBuffer, DriverEntry->NumberOfPage));\r
 \r
-  ImageRecord = FindImageRecord (DriverEntry->ImageBuffer, EFI_PAGES_TO_SIZE(DriverEntry->NumberOfPage));\r
+  ImageRecord = FindImageRecord (DriverEntry->ImageBuffer, EfiPagesToSize(DriverEntry->NumberOfPage));\r
   if (ImageRecord == NULL) {\r
     DEBUG ((DEBUG_ERROR, "SMM !!!!!!!! ImageRecord not found !!!!!!!!\n"));\r
     return ;\r