]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Enhance the check for some fields in the PE image before use it.
authorydong10 <ydong10@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 28 Nov 2012 02:49:49 +0000 (02:49 +0000)
committerydong10 <ydong10@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 28 Nov 2012 02:49:49 +0000 (02:49 +0000)
Signed-off-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Jiewen Yao<jiewen.yao@intel.com>
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13972 6f19259b-4bc3-4df7-8a09-765794883524

MdePkg/Library/BasePeCoffLib/BasePeCoff.c

index f82ed76ee6ced88313d487e49ca9026178c81a19..6f056e519ef6739be54fa816670932c454fc713b 100644 (file)
@@ -87,6 +87,7 @@ PeCoffLoaderGetPeHeader (
   UINT16                Magic;\r
   UINT32                SectionHeaderOffset;\r
   UINT32                Index;\r
+  UINT32                HeaderWithoutDataDir;\r
   CHAR8                 BufferData;\r
   UINTN                 NumberOfSections;\r
   EFI_IMAGE_SECTION_HEADER  SectionHeader;\r
@@ -164,7 +165,7 @@ PeCoffLoaderGetPeHeader (
 \r
     if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
       //\r
-      // 1. Check FileHeader.SizeOfOptionalHeader filed.\r
+      // 1. Check OptionalHeader.NumberOfRvaAndSizes filed.\r
       //\r
       if (EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES < Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes) {\r
         ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
@@ -172,19 +173,36 @@ PeCoffLoaderGetPeHeader (
       }\r
 \r
       //\r
-      // 2. Check the OptionalHeader.SizeOfHeaders field.\r
-      // This field will be use like the following mode, so just compare the result.\r
-      // The DataDirectory array begin with 1, not 0, so here use < to compare not <=.\r
+      // 2. Check the FileHeader.SizeOfOptionalHeader field.\r
+      // OptionalHeader.NumberOfRvaAndSizes is not bigger than 16, so \r
+      // OptionalHeader.NumberOfRvaAndSizes * sizeof (EFI_IMAGE_DATA_DIRECTORY) will not overflow.\r
       //\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
+      HeaderWithoutDataDir = sizeof (EFI_IMAGE_OPTIONAL_HEADER32) - sizeof (EFI_IMAGE_DATA_DIRECTORY) * EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES;\r
+      if (((UINT32)Hdr.Pe32->FileHeader.SizeOfOptionalHeader - HeaderWithoutDataDir) !=\r
+          Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes * sizeof (EFI_IMAGE_DATA_DIRECTORY)) {\r
+        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
+        return RETURN_UNSUPPORTED;\r
       }\r
 \r
+      SectionHeaderOffset = ImageContext->PeCoffHeaderOffset + sizeof (UINT32) + sizeof (EFI_IMAGE_FILE_HEADER) + Hdr.Pe32->FileHeader.SizeOfOptionalHeader;\r
       //\r
-      // 2.2 Read last byte of Hdr.Pe32.OptionalHeader.SizeOfHeaders from the file.\r
+      // 3. Check the FileHeader.NumberOfSections field.\r
+      //\r
+      if ((Hdr.Pe32->OptionalHeader.SizeOfImage - SectionHeaderOffset) / EFI_IMAGE_SIZEOF_SECTION_HEADER <= Hdr.Pe32->FileHeader.NumberOfSections) {\r
+        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
+        return RETURN_UNSUPPORTED;\r
+      }\r
+\r
+      //\r
+      // 4. Check the OptionalHeader.SizeOfHeaders field.\r
+      //\r
+      if ((Hdr.Pe32->OptionalHeader.SizeOfHeaders - SectionHeaderOffset) / EFI_IMAGE_SIZEOF_SECTION_HEADER < (UINT32)Hdr.Pe32->FileHeader.NumberOfSections) {\r
+        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
+        return RETURN_UNSUPPORTED;\r
+      }\r
+\r
+      //\r
+      // 4.2 Read last byte of Hdr.Pe32.OptionalHeader.SizeOfHeaders from the file.\r
       //\r
       Size = 1;\r
       ReadSize = Size;\r
@@ -250,27 +268,43 @@ PeCoffLoaderGetPeHeader (
 \r
     } else if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
       //\r
-      // 1. Check FileHeader.SizeOfOptionalHeader filed.\r
+      // 1. Check FileHeader.NumberOfRvaAndSizes 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
+      // 2. Check the FileHeader.SizeOfOptionalHeader field.\r
+      // OptionalHeader.NumberOfRvaAndSizes is not bigger than 16, so \r
+      // OptionalHeader.NumberOfRvaAndSizes * sizeof (EFI_IMAGE_DATA_DIRECTORY) will not overflow.\r
+      //\r
+      HeaderWithoutDataDir = sizeof (EFI_IMAGE_OPTIONAL_HEADER64) - sizeof (EFI_IMAGE_DATA_DIRECTORY) * EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES;\r
+      if (((UINT32)Hdr.Pe32Plus->FileHeader.SizeOfOptionalHeader - HeaderWithoutDataDir) !=\r
+          Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes * sizeof (EFI_IMAGE_DATA_DIRECTORY)) {\r
+        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
+        return RETURN_UNSUPPORTED;\r
+      }\r
 \r
+      SectionHeaderOffset = ImageContext->PeCoffHeaderOffset + sizeof (UINT32) + sizeof (EFI_IMAGE_FILE_HEADER) + Hdr.Pe32Plus->FileHeader.SizeOfOptionalHeader;\r
       //\r
-      // 2. Check the OptionalHeader.SizeOfHeaders field.\r
-      // This field will be use like the following mode, so just compare the result.\r
-      // The DataDirectory array begin with 1, not 0, so here use < to compare not <=.\r
+      // 3. Check the FileHeader.NumberOfSections field.\r
       //\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
+      if ((Hdr.Pe32Plus->OptionalHeader.SizeOfImage - SectionHeaderOffset) / EFI_IMAGE_SIZEOF_SECTION_HEADER <= Hdr.Pe32Plus->FileHeader.NumberOfSections) {\r
+        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
+        return RETURN_UNSUPPORTED;\r
+      }\r
+\r
+      //\r
+      // 4. Check the OptionalHeader.SizeOfHeaders field.\r
+      //\r
+      if ((Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders - SectionHeaderOffset) / EFI_IMAGE_SIZEOF_SECTION_HEADER < (UINT32)Hdr.Pe32Plus->FileHeader.NumberOfSections) {\r
+        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
+        return RETURN_UNSUPPORTED;\r
       }\r
 \r
       //\r
-      // 2.2 Read last byte of Hdr.Pe32Plus.OptionalHeader.SizeOfHeaders from the file.\r
+      // 4.2 Read last byte of Hdr.Pe32Plus.OptionalHeader.SizeOfHeaders from the file.\r
       //\r
       Size = 1;\r
       ReadSize = Size;\r
@@ -384,6 +418,15 @@ PeCoffLoaderGetPeHeader (
     }\r
 \r
     if (SectionHeader.SizeOfRawData > 0) {\r
+      //\r
+      // Section data should bigger than the Pe header.\r
+      //\r
+      if (SectionHeader.VirtualAddress < ImageContext->SizeOfHeaders || \r
+          SectionHeader.PointerToRawData < ImageContext->SizeOfHeaders) {\r
+        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
+        return RETURN_UNSUPPORTED;\r
+      }\r
+\r
       //\r
       // Check the member data to avoid overflow.\r
       //\r