]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdePkg/Library/BasePeCoffLib/BasePeCoff.c
MdePkg BaseStackCheckLib: Correct style of file header
[mirror_edk2.git] / MdePkg / Library / BasePeCoffLib / BasePeCoff.c
index d9e8809e5512c78d401458c89b3c5292c29077ab..8d1daba4bbe5cc5a2361ff2d3b08b1f7ad8cd160 100644 (file)
@@ -15,7 +15,7 @@
   PeCoffLoaderGetPeHeader() routine will do basic check for PE/COFF header.\r
   PeCoffLoaderGetImageInfo() routine will do basic check for whole PE/COFF image.\r
 \r
-  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>\r
   Portions copyright (c) 2008 - 2009, Apple Inc. 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
@@ -703,12 +703,10 @@ PeCoffLoaderGetImageInfo (
       //\r
       DebugDirectoryEntryFileOffset = 0;\r
 \r
-      SectionHeaderOffset = (UINTN)(\r
-                               ImageContext->PeCoffHeaderOffset +\r
-                               sizeof (UINT32) +\r
-                               sizeof (EFI_IMAGE_FILE_HEADER) +\r
-                               Hdr.Pe32->FileHeader.SizeOfOptionalHeader\r
-                               );\r
+      SectionHeaderOffset = ImageContext->PeCoffHeaderOffset +\r
+                            sizeof (UINT32) +\r
+                            sizeof (EFI_IMAGE_FILE_HEADER) +\r
+                            Hdr.Pe32->FileHeader.SizeOfOptionalHeader;\r
 \r
       for (Index = 0; Index < Hdr.Pe32->FileHeader.NumberOfSections; Index++) {\r
         //\r
@@ -941,6 +939,7 @@ PeCoffLoaderRelocateImage (
   EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION   Hdr;\r
   EFI_IMAGE_DATA_DIRECTORY              *RelocDir;\r
   UINT64                                Adjust;\r
+  EFI_IMAGE_BASE_RELOCATION             *RelocBaseOrg;\r
   EFI_IMAGE_BASE_RELOCATION             *RelocBase;\r
   EFI_IMAGE_BASE_RELOCATION             *RelocBaseEnd;\r
   UINT16                                *Reloc;\r
@@ -1041,7 +1040,8 @@ PeCoffLoaderRelocateImage (
                                                                             RelocDir->VirtualAddress + RelocDir->Size - 1,\r
                                                                             TeStrippedOffset\r
                                                                             );\r
-    if (RelocBase == NULL || RelocBaseEnd == NULL) {\r
+    if (RelocBase == NULL || RelocBaseEnd == NULL || RelocBaseEnd < RelocBase) {\r
+      ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;\r
       return RETURN_LOAD_ERROR;\r
     }\r
   } else {\r
@@ -1050,6 +1050,7 @@ PeCoffLoaderRelocateImage (
     //\r
     RelocBase = RelocBaseEnd = NULL;    \r
   }\r
+  RelocBaseOrg = RelocBase;\r
 \r
   //\r
   // If Adjust is not zero, then apply fix ups to the image\r
@@ -1065,14 +1066,23 @@ PeCoffLoaderRelocateImage (
       //\r
       // Add check for RelocBase->SizeOfBlock field.\r
       //\r
-      if ((RelocBase->SizeOfBlock == 0) || (RelocBase->SizeOfBlock > RelocDir->Size)) {\r
+      if (RelocBase->SizeOfBlock == 0) {\r
+        ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;\r
+        return RETURN_LOAD_ERROR;\r
+      }\r
+      if ((UINTN)RelocBase > MAX_ADDRESS - RelocBase->SizeOfBlock) {\r
         ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;\r
         return RETURN_LOAD_ERROR;\r
       }\r
 \r
       RelocEnd  = (UINT16 *) ((CHAR8 *) RelocBase + RelocBase->SizeOfBlock);\r
+      if ((UINTN)RelocEnd > (UINTN)RelocBaseOrg + RelocDir->Size) {\r
+        ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;\r
+        return RETURN_LOAD_ERROR;\r
+      }\r
       FixupBase = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress, TeStrippedOffset);\r
       if (FixupBase == NULL) {\r
+        ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;\r
         return RETURN_LOAD_ERROR;\r
       }  \r
 \r
@@ -1080,8 +1090,11 @@ PeCoffLoaderRelocateImage (
       // Run this relocation record\r
       //\r
       while (Reloc < RelocEnd) {\r
-\r
-        Fixup = FixupBase + (*Reloc & 0xFFF);\r
+        Fixup = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress + (*Reloc & 0xFFF), TeStrippedOffset);\r
+        if (Fixup == NULL) {\r
+          ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;\r
+          return RETURN_LOAD_ERROR;\r
+        }\r
         switch ((*Reloc) >> 12) {\r
         case EFI_IMAGE_REL_BASED_ABSOLUTE:\r
           break;\r
@@ -1148,6 +1161,7 @@ PeCoffLoaderRelocateImage (
       //\r
       RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd;\r
     }\r
+    ASSERT ((UINTN)FixupData <= (UINTN)ImageContext->FixupData + ImageContext->FixupDataSize);\r
 \r
     //\r
     // Adjust the EntryPoint to match the linked-to address\r
@@ -1444,14 +1458,17 @@ PeCoffLoaderLoadImage (
       DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];\r
     }\r
 \r
+    //\r
+    // Must use UINT64 here, because there might a case that 32bit loader to load 64bit image.\r
+    //\r
     if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {\r
-      ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN);\r
+      ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINT64);\r
     } else {\r
       ImageContext->FixupDataSize = 0;\r
     }\r
   } else {\r
     DirectoryEntry              = &Hdr.Te->DataDirectory[0];\r
-    ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN);\r
+    ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINT64);\r
   }\r
   //\r
   // Consumer must allocate a buffer for the relocation fixup log.\r