Bug 1541597: Modify PEHeaders to use NumberOfRvaAndSizes as maximum DataDirectory length; r=mhowell a=pascalc
authorAaron Klotz <aklotz@mozilla.com>
Wed, 03 Apr 2019 21:56:24 +0000
changeset 526017 a502516c684a08af7f15c206cd269abc2f810255
parent 526016 aaa0388eee934cc7f6a664a4ee1c49830a26c8aa
child 526018 afec2322933263191f93d38294074197ab4dc4f3
push id2032
push userffxbld-merge
push dateMon, 13 May 2019 09:36:57 +0000
treeherdermozilla-release@455c1065dcbe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmhowell, pascalc
bugs1541597
milestone67.0
Bug 1541597: Modify PEHeaders to use NumberOfRvaAndSizes as maximum DataDirectory length; r=mhowell a=pascalc Differential Revision: https://phabricator.services.mozilla.com/D26012
mozglue/misc/NativeNt.h
--- a/mozglue/misc/NativeNt.h
+++ b/mozglue/misc/NativeNt.h
@@ -7,16 +7,18 @@
 #ifndef mozilla_NativeNt_h
 #define mozilla_NativeNt_h
 
 #include <stdint.h>
 #include <windows.h>
 #include <winnt.h>
 #include <winternl.h>
 
+#include <algorithm>
+
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/LauncherResult.h"
 
 // The declarations within this #if block are intended to be used for initial
 // process initialization ONLY. You probably don't want to be using these in
 // normal Gecko code!
 #if !defined(MOZILLA_INTERNAL_API)
@@ -398,35 +400,43 @@ class MOZ_RAII PEHeaders final {
       return;
     }
 
     mPeHeader = RVAToPtrUnchecked<PIMAGE_NT_HEADERS>(mMzHeader->e_lfanew);
     if (!mPeHeader || mPeHeader->Signature != IMAGE_NT_SIGNATURE) {
       return;
     }
 
+    if (mPeHeader->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC) {
+      return;
+    }
+
     DWORD imageSize = mPeHeader->OptionalHeader.SizeOfImage;
     // This is a coarse-grained check to ensure that the image size is
     // reasonable. It we aren't big enough to contain headers, we have a
     // problem!
     if (imageSize < sizeof(IMAGE_DOS_HEADER) + sizeof(IMAGE_NT_HEADERS)) {
       return;
     }
 
     mImageLimit = RVAToPtrUnchecked<void*>(imageSize - 1UL);
   }
 
   template <typename T>
-  T GetImageDirectoryEntry(unsigned int aDirectoryIndex) {
-    if (aDirectoryIndex >= IMAGE_NUMBEROF_DIRECTORY_ENTRIES) {
+  T GetImageDirectoryEntry(const uint32_t aDirectoryIndex) {
+    IMAGE_OPTIONAL_HEADER& optionalHeader = mPeHeader->OptionalHeader;
+
+    const uint32_t maxIndex = std::min(optionalHeader.NumberOfRvaAndSizes,
+                                       DWORD(IMAGE_NUMBEROF_DIRECTORY_ENTRIES));
+    if (aDirectoryIndex >= maxIndex) {
       return nullptr;
     }
 
     IMAGE_DATA_DIRECTORY& dirEntry =
-        mPeHeader->OptionalHeader.DataDirectory[aDirectoryIndex];
+        optionalHeader.DataDirectory[aDirectoryIndex];
     return RVAToPtr<T>(dirEntry.VirtualAddress);
   }
 
   // This private overload does not have bounds checks, because we need to be
   // able to resolve the bounds themselves.
   template <typename T, typename R>
   T RVAToPtrUnchecked(R aRva) {
     return reinterpret_cast<T>(reinterpret_cast<char*>(mMzHeader) + aRva);