]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdePkg/Library/BasePeCoffLib/BasePeCoff.c
Enhance the check for debug data before get the PdbPointer.
[mirror_edk2.git] / MdePkg / Library / BasePeCoffLib / BasePeCoff.c
index 014eb22dc812db0935f41283e7c36c4570f1ca3e..27b130d42ecae25ee63555d393c9458b309be5e9 100644 (file)
@@ -104,6 +104,9 @@ PeCoffLoaderGetPeHeader (
                            );\r
   if (RETURN_ERROR (Status) || (Size != ReadSize)) {\r
     ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+    if (Size != ReadSize) {\r
+      Status = RETURN_UNSUPPORTED;\r
+    }\r
     return Status;\r
   }\r
 \r
@@ -132,6 +135,9 @@ PeCoffLoaderGetPeHeader (
                            );\r
   if (RETURN_ERROR (Status) || (Size != ReadSize)) {\r
     ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+    if (Size != ReadSize) {\r
+      Status = RETURN_UNSUPPORTED;\r
+    }\r
     return Status;\r
   }\r
 \r
@@ -161,6 +167,7 @@ PeCoffLoaderGetPeHeader (
       // 1. Check FileHeader.SizeOfOptionalHeader filed.\r
       //\r
       if (EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES < Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes) {\r
+        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
         return RETURN_UNSUPPORTED;\r
       }\r
 \r
@@ -171,6 +178,7 @@ PeCoffLoaderGetPeHeader (
       //\r
       if (EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1 < Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes) {\r
         if (Hdr.Pe32->OptionalHeader.SizeOfHeaders < (UINT32)((UINT8 *)(&Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]) - (UINT8 *) &Hdr)) {\r
+          ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
           return RETURN_UNSUPPORTED;\r
         }\r
       }\r
@@ -187,6 +195,10 @@ PeCoffLoaderGetPeHeader (
                                &BufferData\r
                                );\r
       if (RETURN_ERROR (Status) || (Size != ReadSize)) {\r
+        ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+        if (Size != ReadSize) {\r
+          Status = RETURN_UNSUPPORTED;\r
+        }\r
         return Status;\r
       }\r
 \r
@@ -202,7 +214,8 @@ PeCoffLoaderGetPeHeader (
           //\r
           if ((UINT32) (~0) - Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress <\r
               Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size) {\r
-            return RETURN_INVALID_PARAMETER;\r
+            ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
+            return RETURN_UNSUPPORTED;\r
           }\r
 \r
           //\r
@@ -218,6 +231,10 @@ PeCoffLoaderGetPeHeader (
                                    &BufferData\r
                                    );\r
           if (RETURN_ERROR (Status) || (Size != ReadSize)) {\r
+            ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+            if (Size != ReadSize) {\r
+              Status = RETURN_UNSUPPORTED;\r
+            }\r
             return Status;\r
           }\r
         }\r
@@ -236,6 +253,7 @@ PeCoffLoaderGetPeHeader (
       // 1. Check FileHeader.SizeOfOptionalHeader filed.\r
       //\r
       if (EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES < Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes) {\r
+        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
         return RETURN_UNSUPPORTED;\r
       }\r
 \r
@@ -246,6 +264,7 @@ PeCoffLoaderGetPeHeader (
       //\r
       if (EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1 < Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes) {\r
         if (Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders < (UINT32)((UINT8 *)(&Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]) - (UINT8 *) &Hdr)) {\r
+          ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
           return RETURN_UNSUPPORTED;\r
         }\r
       }\r
@@ -262,6 +281,10 @@ PeCoffLoaderGetPeHeader (
                                &BufferData\r
                                );\r
       if (RETURN_ERROR (Status) || (Size != ReadSize)) {\r
+        ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+        if (Size != ReadSize) {\r
+          Status = RETURN_UNSUPPORTED;\r
+        }\r
         return Status;\r
       }\r
 \r
@@ -277,7 +300,8 @@ PeCoffLoaderGetPeHeader (
           //\r
           if ((UINT32) (~0) - Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress <\r
               Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size) {\r
-            return RETURN_INVALID_PARAMETER;\r
+            ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
+            return RETURN_UNSUPPORTED;\r
           }\r
 \r
           //\r
@@ -293,6 +317,10 @@ PeCoffLoaderGetPeHeader (
                                    &BufferData\r
                                    );\r
           if (RETURN_ERROR (Status) || (Size != ReadSize)) {\r
+            ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+            if (Size != ReadSize) {\r
+              Status = RETURN_UNSUPPORTED;\r
+            }\r
             return Status;\r
           }\r
         }\r
@@ -348,6 +376,10 @@ PeCoffLoaderGetPeHeader (
                              &SectionHeader\r
                              );\r
     if (RETURN_ERROR (Status) || (Size != ReadSize)) {\r
+      ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+      if (Size != ReadSize) {\r
+        Status = RETURN_UNSUPPORTED;\r
+      }\r
       return Status;\r
     }\r
 \r
@@ -356,7 +388,8 @@ PeCoffLoaderGetPeHeader (
       // Check the member data to avoid overflow.\r
       //\r
       if ((UINT32) (~0) - SectionHeader.PointerToRawData < SectionHeader.SizeOfRawData) {\r
-        return RETURN_INVALID_PARAMETER;\r
+        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
+        return RETURN_UNSUPPORTED;\r
       }\r
 \r
       //\r
@@ -372,6 +405,10 @@ PeCoffLoaderGetPeHeader (
                                &BufferData\r
                                );\r
       if (RETURN_ERROR (Status) || (Size != ReadSize)) {\r
+        ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+        if (Size != ReadSize) {\r
+          Status = RETURN_UNSUPPORTED;\r
+        }\r
         return Status;\r
       }\r
     }\r
@@ -507,7 +544,8 @@ PeCoffLoaderGetImageInfo (
   // This case is not a valid TE image. \r
   //\r
   if ((ImageContext->IsTeImage) && (Hdr.Te->DataDirectory[0].Size != 0) && (Hdr.Te->DataDirectory[0].VirtualAddress == 0)) {\r
-    return RETURN_INVALID_PARAMETER;\r
+    ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
+    return RETURN_UNSUPPORTED;\r
   }\r
 \r
   if (!(ImageContext->IsTeImage)) {\r
@@ -557,6 +595,9 @@ PeCoffLoaderGetImageInfo (
                                  );\r
         if (RETURN_ERROR (Status) || (Size != ReadSize)) {\r
           ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+          if (Size != ReadSize) {\r
+            Status = RETURN_UNSUPPORTED;\r
+          }\r
           return Status;\r
         }\r
 \r
@@ -585,8 +626,17 @@ PeCoffLoaderGetImageInfo (
                                    );\r
           if (RETURN_ERROR (Status) || (Size != ReadSize)) {\r
             ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+            if (Size != ReadSize) {\r
+              Status = RETURN_UNSUPPORTED;\r
+            }\r
             return Status;\r
           }\r
+\r
+          //\r
+          // From PeCoff spec, when DebugEntry.RVA == 0 means this debug info will not load into memory.\r
+          // Here we will always load EFI_IMAGE_DEBUG_TYPE_CODEVIEW type debug info. so need adjust the\r
+          // ImageContext->ImageSize when DebugEntry.RVA == 0.\r
+          //\r
           if (DebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {\r
             ImageContext->DebugDirectoryEntryRva = (UINT32) (DebugDirectoryEntryRva + Index);\r
             if (DebugEntry.RVA == 0 && DebugEntry.FileOffset != 0) {\r
@@ -620,6 +670,9 @@ PeCoffLoaderGetImageInfo (
                                );\r
       if (RETURN_ERROR (Status) || (Size != ReadSize)) {\r
         ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+        if (Size != ReadSize) {\r
+          Status = RETURN_UNSUPPORTED;\r
+        }\r
         return Status;\r
       }\r
 \r
@@ -674,6 +727,9 @@ PeCoffLoaderGetImageInfo (
                                  );\r
         if (RETURN_ERROR (Status) || (Size != ReadSize)) {\r
           ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+          if (Size != ReadSize) {\r
+            Status = RETURN_UNSUPPORTED;\r
+          }\r
           return Status;\r
         }\r
 \r
@@ -1044,7 +1100,6 @@ PeCoffLoaderLoadImage (
   UINTN                                 Index;\r
   CHAR8                                 *Base;\r
   CHAR8                                 *End;\r
-  CHAR8                                 *MaxEnd;\r
   EFI_IMAGE_DATA_DIRECTORY              *DirectoryEntry;\r
   EFI_IMAGE_DEBUG_DIRECTORY_ENTRY       *DebugEntry;\r
   UINTN                                 Size;\r
@@ -1170,7 +1225,7 @@ PeCoffLoaderLoadImage (
   // Load each section of the image\r
   //\r
   Section = FirstSection;\r
-  for (Index = 0, MaxEnd = NULL; Index < NumberOfSections; Index++) {\r
+  for (Index = 0; Index < NumberOfSections; Index++) {\r
     //\r
     // Read the section\r
     //\r
@@ -1201,10 +1256,6 @@ PeCoffLoaderLoadImage (
       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 (Section->SizeOfRawData > 0) {\r
       if (!(ImageContext->IsTeImage)) {\r
         Status = ImageContext->ImageRead (\r
@@ -1392,14 +1443,26 @@ PeCoffLoaderLoadImage (
 \r
         switch (*(UINT32 *) ImageContext->CodeView) {\r
         case CODEVIEW_SIGNATURE_NB10:\r
+          if (DebugEntry->SizeOfData < sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY)) {\r
+            ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
+            return RETURN_UNSUPPORTED;\r
+          }\r
           ImageContext->PdbPointer = (CHAR8 *)ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);\r
           break;\r
 \r
         case CODEVIEW_SIGNATURE_RSDS:\r
+          if (DebugEntry->SizeOfData < sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY)) {\r
+            ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
+            return RETURN_UNSUPPORTED;\r
+          }\r
           ImageContext->PdbPointer = (CHAR8 *)ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);\r
           break;\r
 \r
         case CODEVIEW_SIGNATURE_MTOC:\r
+          if (DebugEntry->SizeOfData < sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY)) {\r
+            ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
+            return RETURN_UNSUPPORTED;\r
+          }\r
           ImageContext->PdbPointer = (CHAR8 *)ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY);\r
           break;\r
 \r
@@ -1435,6 +1498,12 @@ PeCoffLoaderLoadImage (
 \r
         for (Index = 0; Index < ResourceDirectory->NumberOfNamedEntries; Index++) {\r
           if (ResourceDirectoryEntry->u1.s.NameIsString) {\r
+            //\r
+            // Check the ResourceDirectoryEntry->u1.s.NameOffset before use it.\r
+            //\r
+            if (ResourceDirectoryEntry->u1.s.NameOffset >= DirectoryEntry->Size) {\r
+              continue;\r
+            }\r
             ResourceDirectoryString = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *) (Base + ResourceDirectoryEntry->u1.s.NameOffset);\r
             String = &ResourceDirectoryString->String[0];\r
 \r
@@ -1610,6 +1679,15 @@ PeCoffLoaderRelocateImageForRuntime (
   //\r
   FixupData = RelocationData;\r
   while (RelocBase < RelocBaseEnd) {\r
+    //\r
+    // Add check for RelocBase->SizeOfBlock field.\r
+    //\r
+    if ((RelocBase->SizeOfBlock == 0) || (RelocBase->SizeOfBlock > RelocDir->Size)) {\r
+      //\r
+      // Data invalid, cannot continue to relocate the image, just return.\r
+      //\r
+      return;\r
+    }\r
 \r
     Reloc     = (UINT16 *) ((UINT8 *) RelocBase + sizeof (EFI_IMAGE_BASE_RELOCATION));\r
     RelocEnd  = (UINT16 *) ((UINT8 *) RelocBase + RelocBase->SizeOfBlock);\r
@@ -1703,6 +1781,8 @@ PeCoffLoaderRelocateImageForRuntime (
   PE/COFF image starting at byte offset FileOffset into the buffer specified by Buffer.  \r
   The size of the buffer actually read is returned in ReadSize.\r
   \r
+  The caller must make sure the FileOffset and ReadSize within the file scope.\r
+\r
   If FileHandle is NULL, then ASSERT().\r
   If ReadSize is NULL, then ASSERT().\r
   If Buffer is NULL, then ASSERT().\r