]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Support load 64 bit image from 32 bit core.
authorEric Dong <eric.dong@intel.com>
Tue, 25 Mar 2014 05:04:21 +0000 (05:04 +0000)
committerydong10 <ydong10@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 25 Mar 2014 05:04:21 +0000 (05:04 +0000)
Add more enhancement to check invalid PE format.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Jiewen, Yao <jiewen.yao@intel.com>
Reviewed-by: Liming, Gao <liming.gao@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15387 6f19259b-4bc3-4df7-8a09-765794883524

MdePkg/Library/BasePeCoffLib/BasePeCoff.c

index d9e8809e5512c78d401458c89b3c5292c29077ab..33cad23a014e03998b9a0fcc53d7aca7560daf21 100644 (file)
@@ -941,6 +941,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 +1042,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 +1052,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 +1068,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 +1092,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 +1163,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 +1460,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