]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/PiSmmCore/Dispatcher.c
MdeModulePkg: Fix use-after-free error in InstallConfigurationTable()
[mirror_edk2.git] / MdeModulePkg / Core / PiSmmCore / Dispatcher.c
index 87f4617c41a81ad8915b3b1362b83b67fc7bc587..f32bbbd1b4b3da6abaadb2c504ef963039ce330e 100644 (file)
@@ -28,7 +28,7 @@
   Depex - Dependency Expresion.\r
 \r
   Copyright (c) 2014, Hewlett-Packard Development Company, L.P.\r
-  Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.<BR>\r
   This program and the accompanying materials are licensed and made available \r
   under the terms and conditions of the BSD License which accompanies this \r
   distribution.  The full text of the license may be found at        \r
@@ -183,8 +183,8 @@ CheckAndMarkFixLoadingMemoryUsageBitMap (
    //\r
    // Test if the memory is avalaible or not.\r
    // \r
-   BaseOffsetPageNumber = (UINTN)EFI_SIZE_TO_PAGES((UINT32)(ImageBase - SmmCodeBase));\r
-   TopOffsetPageNumber  = (UINTN)EFI_SIZE_TO_PAGES((UINT32)(ImageBase + ImageSize - SmmCodeBase));\r
+   BaseOffsetPageNumber = EFI_SIZE_TO_PAGES((UINT32)(ImageBase - SmmCodeBase));\r
+   TopOffsetPageNumber  = EFI_SIZE_TO_PAGES((UINT32)(ImageBase + ImageSize - SmmCodeBase));\r
    for (Index = BaseOffsetPageNumber; Index < TopOffsetPageNumber; Index ++) {\r
      if ((mSmmCodeMemoryRangeUsageBitMap[Index / 64] & LShiftU64(1, (Index % 64))) != 0) {\r
        //\r
@@ -234,12 +234,10 @@ GetPeCoffImageFixLoadingAssignedAddress(
   // Get PeHeader pointer\r
   //\r
   ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((CHAR8* )ImageContext->Handle + ImageContext->PeCoffHeaderOffset);\r
-  SectionHeaderOffset = (UINTN)(\r
-                                 ImageContext->PeCoffHeaderOffset +\r
-                                 sizeof (UINT32) +\r
-                                 sizeof (EFI_IMAGE_FILE_HEADER) +\r
-                                 ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader\r
-                                 );\r
+  SectionHeaderOffset = ImageContext->PeCoffHeaderOffset +\r
+                        sizeof (UINT32) +\r
+                        sizeof (EFI_IMAGE_FILE_HEADER) +\r
+                        ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader;\r
   NumberOfSections = ImgHdr->Pe32.FileHeader.NumberOfSections;\r
 \r
   //\r
@@ -520,7 +518,7 @@ SmmLoadImage (
   // Align buffer on section boundary\r
   //\r
   ImageContext.ImageAddress += ImageContext.SectionAlignment - 1;\r
-  ImageContext.ImageAddress &= ~((EFI_PHYSICAL_ADDRESS)(ImageContext.SectionAlignment - 1));\r
+  ImageContext.ImageAddress &= ~((EFI_PHYSICAL_ADDRESS)ImageContext.SectionAlignment - 1);\r
 \r
   //\r
   // Load the image to our new buffer\r
@@ -580,6 +578,11 @@ SmmLoadImage (
   DriverEntry->LoadedImage->SystemTable   = gST;\r
   DriverEntry->LoadedImage->DeviceHandle  = DeviceHandle;\r
 \r
+  DriverEntry->SmmLoadedImage.Revision     = EFI_LOADED_IMAGE_PROTOCOL_REVISION;\r
+  DriverEntry->SmmLoadedImage.ParentHandle = gSmmCorePrivate->SmmIplImageHandle;\r
+  DriverEntry->SmmLoadedImage.SystemTable  = gST;\r
+  DriverEntry->SmmLoadedImage.DeviceHandle = DeviceHandle;\r
+\r
   //\r
   // Make an EfiBootServicesData buffer copy of FilePath\r
   //\r
@@ -593,11 +596,30 @@ SmmLoadImage (
   }\r
   CopyMem (DriverEntry->LoadedImage->FilePath, FilePath, GetDevicePathSize (FilePath));\r
 \r
-  DriverEntry->LoadedImage->ImageBase     = (VOID *)(UINTN)DriverEntry->ImageBuffer;\r
+  DriverEntry->LoadedImage->ImageBase     = (VOID *)(UINTN) ImageContext.ImageAddress;\r
   DriverEntry->LoadedImage->ImageSize     = ImageContext.ImageSize;\r
   DriverEntry->LoadedImage->ImageCodeType = EfiRuntimeServicesCode;\r
   DriverEntry->LoadedImage->ImageDataType = EfiRuntimeServicesData;\r
 \r
+  //\r
+  // Make a buffer copy of FilePath\r
+  //\r
+  Status = SmmAllocatePool (EfiRuntimeServicesData, GetDevicePathSize(FilePath), (VOID **)&DriverEntry->SmmLoadedImage.FilePath);\r
+  if (EFI_ERROR (Status)) {\r
+    if (Buffer != NULL) {\r
+      gBS->FreePool (Buffer);\r
+    }\r
+    gBS->FreePool (DriverEntry->LoadedImage->FilePath);\r
+    SmmFreePages (DstBuffer, PageCount);\r
+    return Status;\r
+  }\r
+  CopyMem (DriverEntry->SmmLoadedImage.FilePath, FilePath, GetDevicePathSize(FilePath));\r
+\r
+  DriverEntry->SmmLoadedImage.ImageBase = (VOID *)(UINTN) ImageContext.ImageAddress;\r
+  DriverEntry->SmmLoadedImage.ImageSize = ImageContext.ImageSize;\r
+  DriverEntry->SmmLoadedImage.ImageCodeType = EfiRuntimeServicesCode;\r
+  DriverEntry->SmmLoadedImage.ImageDataType = EfiRuntimeServicesData;\r
+\r
   //\r
   // Create a new image handle in the UEFI handle database for the SMM Driver\r
   //\r
@@ -608,6 +630,17 @@ SmmLoadImage (
                   NULL\r
                   );\r
 \r
+  //\r
+  // Create a new image handle in the SMM handle database for the SMM Driver\r
+  //\r
+  DriverEntry->SmmImageHandle = NULL;\r
+  Status = SmmInstallProtocolInterface (\r
+             &DriverEntry->SmmImageHandle,\r
+             &gEfiLoadedImageProtocolGuid,\r
+             EFI_NATIVE_INTERFACE,\r
+             &DriverEntry->SmmLoadedImage\r
+             );\r
+\r
   PERF_START (DriverEntry->ImageHandle, "LoadImage:", NULL, Tick);\r
   PERF_END (DriverEntry->ImageHandle, "LoadImage:", NULL, 0);\r
 \r
@@ -896,6 +929,16 @@ SmmDispatcher (
           }\r
           gBS->FreePool (DriverEntry->LoadedImage);\r
         }\r
+        Status = SmmUninstallProtocolInterface (\r
+                   DriverEntry->SmmImageHandle,\r
+                   &gEfiLoadedImageProtocolGuid,\r
+                   &DriverEntry->SmmLoadedImage\r
+                   );\r
+        if (!EFI_ERROR(Status)) {\r
+          if (DriverEntry->SmmLoadedImage.FilePath != NULL) {\r
+            SmmFreePool (DriverEntry->SmmLoadedImage.FilePath);\r
+          }\r
+        }\r
       }\r
 \r
       REPORT_STATUS_CODE_WITH_EXTENDED_DATA (\r
@@ -1327,6 +1370,27 @@ SmmDriverDispatchHandler (
 \r
               mSmmCoreLoadedImage->DeviceHandle = FvHandle;\r
             }\r
+            if (mSmmCoreDriverEntry->SmmLoadedImage.FilePath == NULL) {\r
+              //\r
+              // Maybe one special FV contains only one SMM_CORE module, so its device path must\r
+              // be initialized completely.\r
+              //\r
+              EfiInitializeFwVolDevicepathNode (&mFvDevicePath.File, &NameGuid);\r
+              SetDevicePathEndNode (&mFvDevicePath.End);\r
+\r
+              //\r
+              // Make a buffer copy FilePath\r
+              //\r
+              Status = SmmAllocatePool (\r
+                         EfiRuntimeServicesData,\r
+                         GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath),\r
+                         (VOID **)&mSmmCoreDriverEntry->SmmLoadedImage.FilePath\r
+                         );\r
+              ASSERT_EFI_ERROR (Status);\r
+              CopyMem (mSmmCoreDriverEntry->SmmLoadedImage.FilePath, &mFvDevicePath, GetDevicePathSize((EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath));\r
+\r
+              mSmmCoreDriverEntry->SmmLoadedImage.DeviceHandle = FvHandle;\r
+            }\r
           } else {\r
             SmmAddToDriverList (Fv, FvHandle, &NameGuid);\r
           }\r