]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdePkg/Library/BasePeCoffLib/BasePeCoff.c
Add check for Zero Relocation section.
[mirror_edk2.git] / MdePkg / Library / BasePeCoffLib / BasePeCoff.c
index 60f04703190b147d85266218c92b991355f56358..d029cc7f47eb4b560675f368c41a81af03623d21 100644 (file)
@@ -457,7 +457,7 @@ PeCoffLoaderGetImageInfo (
   Converts an image address to the loaded address.\r
 \r
   @param  ImageContext  The context of the image being loaded.\r
-  @param  Address       The address to be converted to the loaded address.\r
+  @param  Address       The relative virtual address to be converted to the loaded address.\r
 \r
   @return The converted address or NULL if the address can not be converted.\r
 \r
@@ -469,8 +469,7 @@ PeCoffLoaderImageAddress (
   )\r
 {\r
   //\r
-  // @bug Check to make sure ImageSize is correct for the relocated image.\r
-  //      it may only work for the file we start with and not the relocated image\r
+  // Make sure that Address and ImageSize is correct for the loaded image.\r
   //\r
   if (Address >= ImageContext->ImageSize) {\r
     ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_ADDRESS;\r
@@ -586,17 +585,20 @@ PeCoffLoaderRelocateImage (
     // the optional header to verify a desired directory entry is there.\r
     //\r
 \r
-    if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {\r
+    if ((NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) && (RelocDir->Size > 0)) {\r
       RelocBase = PeCoffLoaderImageAddress (ImageContext, RelocDir->VirtualAddress);\r
       RelocBaseEnd = PeCoffLoaderImageAddress (\r
                       ImageContext,\r
                       RelocDir->VirtualAddress + RelocDir->Size - 1\r
                       );\r
+      if (RelocBase == NULL || RelocBaseEnd == NULL) {\r
+        return RETURN_LOAD_ERROR;\r
+      }\r
     } else {\r
       //\r
       // Set base and end to bypass processing below.\r
       //\r
-      RelocBase = RelocBaseEnd = 0;\r
+      RelocBase = RelocBaseEnd = NULL;\r
     }\r
   } else {\r
     Hdr.Te             = (EFI_TE_IMAGE_HEADER *)(UINTN)(ImageContext->ImageAddress);\r
@@ -607,13 +609,20 @@ PeCoffLoaderRelocateImage (
     // Find the relocation block\r
     //\r
     RelocDir = &Hdr.Te->DataDirectory[0];\r
-    RelocBase = (EFI_IMAGE_BASE_RELOCATION *)(UINTN)(\r
-                                    ImageContext->ImageAddress +\r
-                                    RelocDir->VirtualAddress +\r
-                                    sizeof(EFI_TE_IMAGE_HEADER) -\r
-                                    Hdr.Te->StrippedSize\r
-                                    );\r
-    RelocBaseEnd = (EFI_IMAGE_BASE_RELOCATION *) ((UINTN) RelocBase + (UINTN) RelocDir->Size - 1);\r
+    if (RelocDir->Size > 0) {\r
+      RelocBase = (EFI_IMAGE_BASE_RELOCATION *)(UINTN)(\r
+                                      ImageContext->ImageAddress +\r
+                                      RelocDir->VirtualAddress +\r
+                                      sizeof(EFI_TE_IMAGE_HEADER) -\r
+                                      Hdr.Te->StrippedSize\r
+                                      );\r
+      RelocBaseEnd = (EFI_IMAGE_BASE_RELOCATION *) ((UINTN) RelocBase + (UINTN) RelocDir->Size - 1);\r
+    } else {\r
+      //\r
+      // Set base and end to bypass processing below.\r
+      //\r
+      RelocBase = RelocBaseEnd = NULL;    \r
+    }\r
   }\r
 \r
   //\r
@@ -624,22 +633,28 @@ PeCoffLoaderRelocateImage (
 \r
     Reloc     = (UINT16 *) ((CHAR8 *) RelocBase + sizeof (EFI_IMAGE_BASE_RELOCATION));\r
     RelocEnd  = (UINT16 *) ((CHAR8 *) RelocBase + RelocBase->SizeOfBlock);\r
+    \r
+    //\r
+    // Make sure RelocEnd is in the Image range.\r
+    //\r
+    if ((CHAR8 *) RelocEnd < (CHAR8 *)((UINTN) ImageContext->ImageAddress) ||\r
+        (CHAR8 *) RelocEnd > (CHAR8 *)((UINTN)ImageContext->ImageAddress + (UINTN)ImageContext->ImageSize)) {\r
+      ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;\r
+      return RETURN_LOAD_ERROR;\r
+    }\r
+\r
     if (!(ImageContext->IsTeImage)) {\r
       FixupBase = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress);\r
+      if (FixupBase == NULL) {\r
+        return RETURN_LOAD_ERROR;\r
+      }\r
     } else {\r
       FixupBase = (CHAR8 *)(UINTN)(ImageContext->ImageAddress +\r
                     RelocBase->VirtualAddress +\r
                     sizeof(EFI_TE_IMAGE_HEADER) -\r
                     Hdr.Te->StrippedSize\r
                     );\r
-    }\r
-\r
-    if ((CHAR8 *) RelocEnd < (CHAR8 *) ((UINTN) ImageContext->ImageAddress) ||\r
-        (CHAR8 *) RelocEnd > (CHAR8 *)((UINTN)ImageContext->ImageAddress +\r
-          (UINTN)ImageContext->ImageSize)) {\r
-      ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;\r
-      return RETURN_LOAD_ERROR;\r
-    }\r
+    }    \r
 \r
     //\r
     // Run this relocation record\r
@@ -887,7 +902,6 @@ PeCoffLoaderLoadImage (
   //\r
   Section = FirstSection;\r
   for (Index = 0, MaxEnd = NULL; Index < NumberOfSections; Index++) {\r
-\r
     //\r
     // Compute sections address\r
     //\r
@@ -896,14 +910,7 @@ PeCoffLoaderLoadImage (
             ImageContext,\r
             Section->VirtualAddress + Section->Misc.VirtualSize - 1\r
             );\r
-    if (ImageContext->IsTeImage) {\r
-      Base = (CHAR8 *)((UINTN) Base + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN)Hdr.Te->StrippedSize);\r
-      End  = (CHAR8 *)((UINTN) End +  sizeof (EFI_TE_IMAGE_HEADER) - (UINTN)Hdr.Te->StrippedSize);\r
-    }\r
 \r
-    if (End > MaxEnd) {\r
-      MaxEnd = End;\r
-    }\r
     //\r
     // If the base start or end address resolved to 0, then fail.\r
     //\r
@@ -912,6 +919,15 @@ PeCoffLoaderLoadImage (
       return RETURN_LOAD_ERROR;\r
     }\r
 \r
+    if (ImageContext->IsTeImage) {\r
+      Base = (CHAR8 *)((UINTN) Base + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN)Hdr.Te->StrippedSize);\r
+      End  = (CHAR8 *)((UINTN) End +  sizeof (EFI_TE_IMAGE_HEADER) - (UINTN)Hdr.Te->StrippedSize);\r
+    }\r
+\r
+    if (End > MaxEnd) {\r
+      MaxEnd = End;\r
+    }\r
+\r
     //\r
     // Read the section\r
     //\r
@@ -1129,9 +1145,11 @@ PeCoffLoaderLoadImage (
   Reapply fixups on a fixed up PE32/PE32+ image to allow virutal calling at EFI\r
   runtime. \r
   \r
-  PE_COFF_LOADER_IMAGE_CONTEXT.FixupData stores information needed to reapply\r
-  the fixups with a virtual mapping.\r
-\r
+  This function reapplies relocation fixups to the PE/COFF image specified by ImageBase \r
+  and ImageSize so the image will execute correctly when the PE/COFF image is mapped \r
+  to the address specified by VirtualImageBase.  RelocationData must be identical \r
+  to the FiuxupData buffer from the PE_COFF_LOADER_IMAGE_CONTEXT structure \r
+  after this PE/COFF image was relocated with PeCoffLoaderRelocateImage().\r
 \r
   @param  ImageBase          Base address of a PE/COFF image that has been loaded \r
                              and relocated into system memory.\r