Bug 1445025: Part 2 - Move blocklist definitions into separate header file and add new initialization flag; r=mhowell
☠☠ backed out by 064de066457e ☠ ☠
authorAaron Klotz <aklotz@mozilla.com>
Tue, 05 Jun 2018 15:16:13 -0600
changeset 478494 1ad82650ca1ce59d64bd44582fb134d7f4bdc44f
parent 478493 5c63001e1ce6275e20ce6eb7a4720701bd6d318a
child 478495 4dbc7fbb3361eac9add3ff78be493ef49213211b
push id1757
push userffxbld-merge
push dateFri, 24 Aug 2018 17:02:43 +0000
treeherdermozilla-release@736023aebdb1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmhowell
bugs1445025
milestone62.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1445025: Part 2 - Move blocklist definitions into separate header file and add new initialization flag; r=mhowell * This allows us to use a single blocklist definition in multiple places. * This patch also adds support for a new initialization flag that, when enabled, disables the DLL Blocking part of the mozglue blocklist but leaves the profiling and stackwalking suppression bits intact.
mozglue/build/WindowsDllBlocklist.cpp
mozglue/build/WindowsDllBlocklist.h
mozglue/build/WindowsDllBlocklistCommon.h
mozglue/build/WindowsDllBlocklistDefs.h
mozglue/build/moz.build
--- a/mozglue/build/WindowsDllBlocklist.cpp
+++ b/mozglue/build/WindowsDllBlocklist.cpp
@@ -33,256 +33,20 @@
 #include "mozilla/WindowsVersion.h"
 #include "nsWindowsHelpers.h"
 #include "WindowsDllBlocklist.h"
 #include "mozilla/AutoProfilerLabel.h"
 #include "mozilla/glue/WindowsDllServices.h"
 
 using namespace mozilla;
 
-#define ALL_VERSIONS   ((unsigned long long)-1LL)
-
-// DLLs sometimes ship without a version number, particularly early
-// releases. Blocking "version <= 0" has the effect of blocking unversioned
-// DLLs (since the call to get version info fails), but not blocking
-// any versioned instance.
-#define UNVERSIONED    ((unsigned long long)0LL)
-
-// Convert the 4 (decimal) components of a DLL version number into a
-// single unsigned long long, as needed by the blocklist
-#define MAKE_VERSION(a,b,c,d)\
-  ((a##ULL << 48) + (b##ULL << 32) + (c##ULL << 16) + d##ULL)
-
-struct DllBlockInfo {
-  // The name of the DLL -- in LOWERCASE!  It will be compared to
-  // a lowercase version of the DLL name only.
-  const char *name;
-
-  // If maxVersion is ALL_VERSIONS, we'll block all versions of this
-  // dll.  Otherwise, we'll block all versions less than or equal to
-  // the given version, as queried by GetFileVersionInfo and
-  // VS_FIXEDFILEINFO's dwFileVersionMS and dwFileVersionLS fields.
-  //
-  // Note that the version is usually 4 components, which is A.B.C.D
-  // encoded as 0x AAAA BBBB CCCC DDDD ULL (spaces added for clarity),
-  // but it's not required to be of that format.
-  //
-  // If the USE_TIMESTAMP flag is set, then we use the timestamp from
-  // the IMAGE_FILE_HEADER in lieu of a version number.
-  //
-  // If the CHILD_PROCESSES_ONLY flag is set, then the dll is blocked
-  // only when we are a child process.
-  unsigned long long maxVersion;
-
-  enum {
-    FLAGS_DEFAULT = 0,
-    BLOCK_WIN8PLUS_ONLY = 1,
-    BLOCK_WIN8_ONLY = 2,
-    USE_TIMESTAMP = 4,
-    CHILD_PROCESSES_ONLY = 8
-  } flags;
-};
-
-static const DllBlockInfo sWindowsDllBlocklist[] = {
-  // EXAMPLE:
-  // { "uxtheme.dll", ALL_VERSIONS },
-  // { "uxtheme.dll", 0x0000123400000000ULL },
-  // The DLL name must be in lowercase!
-  // The version field is a maximum, that is, we block anything that is
-  // less-than or equal to that version.
-
-  // NPFFAddon - Known malware
-  { "npffaddon.dll", ALL_VERSIONS},
-
-  // AVG 8 - Antivirus vendor AVG, old version, plugin already blocklisted
-  {"avgrsstx.dll", MAKE_VERSION(8,5,0,401)},
-
-  // calc.dll - Suspected malware
-  {"calc.dll", MAKE_VERSION(1,0,0,1)},
-
-  // hook.dll - Suspected malware
-  {"hook.dll", ALL_VERSIONS},
-
-  // GoogleDesktopNetwork3.dll - Extremely old, unversioned instances
-  // of this DLL cause crashes
-  {"googledesktopnetwork3.dll", UNVERSIONED},
-
-  // rdolib.dll - Suspected malware
-  {"rdolib.dll", MAKE_VERSION(6,0,88,4)},
-
-  // fgjk4wvb.dll - Suspected malware
-  {"fgjk4wvb.dll", MAKE_VERSION(8,8,8,8)},
-
-  // radhslib.dll - Naomi internet filter - unmaintained since 2006
-  {"radhslib.dll", UNVERSIONED},
-
-  // Music download filter for vkontakte.ru - old instances
-  // of this DLL cause crashes
-  {"vksaver.dll", MAKE_VERSION(2,2,2,0)},
-
-  // Topcrash in Firefox 4.0b1
-  {"rlxf.dll", MAKE_VERSION(1,2,323,1)},
-
-  // psicon.dll - Topcrashes in Thunderbird, and some crashes in Firefox
-  // Adobe photoshop library, now redundant in later installations
-  {"psicon.dll", ALL_VERSIONS},
-
-  // Topcrash in Firefox 4 betas (bug 618899)
-  {"accelerator.dll", MAKE_VERSION(3,2,1,6)},
-
-  // Topcrash with Roboform in Firefox 8 (bug 699134)
-  {"rf-firefox.dll", MAKE_VERSION(7,6,1,0)},
-  {"roboform.dll", MAKE_VERSION(7,6,1,0)},
-
-  // Topcrash with Babylon Toolbar on FF16+ (bug 721264)
-  {"babyfox.dll", ALL_VERSIONS},
-
-  // sprotector.dll crashes, bug 957258
-  {"sprotector.dll", ALL_VERSIONS},
-
-  // leave these two in always for tests
-  { "mozdllblockingtest.dll", ALL_VERSIONS },
-  { "mozdllblockingtest_versioned.dll", 0x0000000400000000ULL },
-
-  // Windows Media Foundation FLAC decoder and type sniffer (bug 839031).
-  { "mfflac.dll", ALL_VERSIONS },
-
-  // Older Relevant Knowledge DLLs cause us to crash (bug 904001).
-  { "rlnx.dll", MAKE_VERSION(1, 3, 334, 9) },
-  { "pmnx.dll", MAKE_VERSION(1, 3, 334, 9) },
-  { "opnx.dll", MAKE_VERSION(1, 3, 334, 9) },
-  { "prnx.dll", MAKE_VERSION(1, 3, 334, 9) },
-
-  // Older belgian ID card software causes Firefox to crash or hang on
-  // shutdown, bug 831285 and 918399.
-  { "beid35cardlayer.dll", MAKE_VERSION(3, 5, 6, 6968) },
-
-  // bug 925459, bitguard crashes
-  { "bitguard.dll", ALL_VERSIONS },
-
-  // bug 812683 - crashes in Windows library when Asus Gamer OSD is installed
-  // Software is discontinued/unsupported
-  { "atkdx11disp.dll", ALL_VERSIONS },
-
-  // Topcrash with Conduit SearchProtect, bug 944542
-  { "spvc32.dll", ALL_VERSIONS },
-
-  // Topcrash with V-bates, bug 1002748 and bug 1023239
-  { "libinject.dll", UNVERSIONED },
-  { "libinject2.dll", 0x537DDC93, DllBlockInfo::USE_TIMESTAMP },
-  { "libredir2.dll", 0x5385B7ED, DllBlockInfo::USE_TIMESTAMP },
-
-  // Crashes with RoboForm2Go written against old SDK, bug 988311/1196859
-  { "rf-firefox-22.dll", ALL_VERSIONS },
-  { "rf-firefox-40.dll", ALL_VERSIONS },
-
-  // Crashes with DesktopTemperature, bug 1046382
-  { "dtwxsvc.dll", 0x53153234, DllBlockInfo::USE_TIMESTAMP },
-
-  // Startup crashes with Lenovo Onekey Theater, bug 1123778
-  { "activedetect32.dll", UNVERSIONED },
-  { "activedetect64.dll", UNVERSIONED },
-  { "windowsapihookdll32.dll", UNVERSIONED },
-  { "windowsapihookdll64.dll", UNVERSIONED },
-
-  // Flash crashes with RealNetworks RealDownloader, bug 1132663
-  { "rndlnpshimswf.dll", ALL_VERSIONS },
-  { "rndlmainbrowserrecordplugin.dll", ALL_VERSIONS },
-
-  // Startup crashes with RealNetworks Browser Record Plugin, bug 1170141
-  { "nprpffbrowserrecordext.dll", ALL_VERSIONS },
-  { "nprndlffbrowserrecordext.dll", ALL_VERSIONS },
-
-  // Crashes with CyberLink YouCam, bug 1136968
-  { "ycwebcamerasource.ax", MAKE_VERSION(2, 0, 0, 1611) },
-
-  // Old version of WebcamMax crashes WebRTC, bug 1130061
-  { "vwcsource.ax", MAKE_VERSION(1, 5, 0, 0) },
-
-  // NetOp School, discontinued product, bug 763395
-  { "nlsp.dll", MAKE_VERSION(6, 23, 2012, 19) },
-
-  // Orbit Downloader, bug 1222819
-  { "grabdll.dll", MAKE_VERSION(2, 6, 1, 0) },
-  { "grabkernel.dll", MAKE_VERSION(1, 0, 0, 1) },
-
-  // ESET, bug 1229252
-  { "eoppmonitor.dll", ALL_VERSIONS },
-
-  // SS2OSD, bug 1262348
-  { "ss2osd.dll", ALL_VERSIONS },
-  { "ss2devprops.dll", ALL_VERSIONS },
-
-  // NHASUSSTRIXOSD.DLL, bug 1269244
-  { "nhasusstrixosd.dll", ALL_VERSIONS },
-  { "nhasusstrixdevprops.dll", ALL_VERSIONS },
-
-  // Crashes with PremierOpinion/RelevantKnowledge, bug 1277846
-  { "opls.dll", ALL_VERSIONS },
-  { "opls64.dll", ALL_VERSIONS },
-  { "pmls.dll", ALL_VERSIONS },
-  { "pmls64.dll", ALL_VERSIONS },
-  { "prls.dll", ALL_VERSIONS },
-  { "prls64.dll", ALL_VERSIONS },
-  { "rlls.dll", ALL_VERSIONS },
-  { "rlls64.dll", ALL_VERSIONS },
-
-  // Vorbis DirectShow filters, bug 1239690.
-  { "vorbis.acm", MAKE_VERSION(0, 0, 3, 6) },
-
-  // AhnLab Internet Security, bug 1311969
-  { "nzbrcom.dll", ALL_VERSIONS },
-
-  // K7TotalSecurity, bug 1339083.
-  { "k7pswsen.dll", MAKE_VERSION(15, 2, 2, 95) },
-
-  // smci*.dll - goobzo crashware (bug 1339908)
-  { "smci32.dll", ALL_VERSIONS },
-  { "smci64.dll", ALL_VERSIONS },
-
-  // Crashes with Internet Download Manager, bug 1333486
-  { "idmcchandler7.dll", ALL_VERSIONS },
-  { "idmcchandler7_64.dll", ALL_VERSIONS },
-  { "idmcchandler5.dll", ALL_VERSIONS },
-  { "idmcchandler5_64.dll", ALL_VERSIONS },
-
-  // Nahimic 2 breaks applicaton update (bug 1356637)
-  { "nahimic2devprops.dll", MAKE_VERSION(2, 5, 19, 0xffff) },
-  // Nahimic is causing crashes, bug 1233556
-  { "nahimicmsiosd.dll", UNVERSIONED },
-  // Nahimic is causing crashes, bug 1360029
-  { "nahimicvrdevprops.dll", UNVERSIONED },
-  { "nahimic2osd.dll", MAKE_VERSION(2, 5, 19, 0xffff) },
-  { "nahimicmsidevprops.dll", UNVERSIONED },
-
-  // Bug 1268470 - crashes with Kaspersky Lab on Windows 8
-  { "klsihk64.dll", MAKE_VERSION(14, 0, 456, 0xffff), DllBlockInfo::BLOCK_WIN8_ONLY },
-
-  // Bug 1407337, crashes with OpenSC < 0.16.0
-  { "onepin-opensc-pkcs11.dll", MAKE_VERSION(0, 15, 0xffff, 0xffff) },
-
-  // Avecto Privilege Guard causes crashes, bug 1385542
-  { "pghook.dll", ALL_VERSIONS },
-
-  // Old versions of G DATA BankGuard, bug 1421991
-  { "banksafe64.dll", MAKE_VERSION(1, 2, 15299, 65535) },
-
-  // Old versions of G DATA, bug 1043775
-  { "gdkbfltdll64.dll", MAKE_VERSION(1, 0, 14141, 240) },
-
-  // Dell Backup and Recovery tool causes crashes, bug 1433408
-  { "dbroverlayiconnotbackuped.dll", MAKE_VERSION(1, 8, 0, 9) },
-  { "dbroverlayiconbackuped.dll", MAKE_VERSION(1, 8, 0, 9) },
-
-  { nullptr, 0 }
-};
-
-#ifndef STATUS_DLL_NOT_FOUND
-#define STATUS_DLL_NOT_FOUND ((DWORD)0xC0000135L)
-#endif
+#define DLL_BLOCKLIST_ENTRY(name, ...) \
+  { name, __VA_ARGS__ },
+#define DLL_BLOCKLIST_CHAR_TYPE char
+#include "mozilla/WindowsDllBlocklistDefs.h"
 
 // define this for very verbose dll load debug spew
 #undef DEBUG_very_verbose
 
 static const char kBlockedDllsParameter[] = "BlockedDllList=";
 static const int kBlockedDllsParameterLen =
   sizeof(kBlockedDllsParameter) - 1;
 
@@ -499,17 +263,17 @@ public:
 private:
   DllBlockSet(const char* name, unsigned long long version)
     : mName(name)
     , mVersion(version)
     , mNext(nullptr)
   {
   }
 
-  const char* mName; // points into the sWindowsDllBlocklist string
+  const char* mName; // points into the gWindowsDllBlocklist string
   unsigned long long mVersion;
   DllBlockSet* mNext;
 
   static DllBlockSet* gFirst;
 };
 
 DllBlockSet* DllBlockSet::gFirst;
 
@@ -618,18 +382,16 @@ patched_LdrLoadDll (PWCHAR filePath, PUL
   char dllName[DLLNAME_MAX+1];
   wchar_t *dll_part;
   char *dot;
 
   int len = moduleFileName->Length / 2;
   wchar_t *fname = moduleFileName->Buffer;
   UniquePtr<wchar_t[]> full_fname;
 
-  const DllBlockInfo* info = &sWindowsDllBlocklist[0];
-
   // The filename isn't guaranteed to be null terminated, but in practice
   // it always will be; ensure that this is so, and bail if not.
   // This is done instead of the more robust approach because of bug 527122,
   // where lots of weird things were happening when we tried to make a copy.
   if (moduleFileName->MaximumLength < moduleFileName->Length+2 ||
       fname[len] != 0)
   {
 #ifdef DEBUG
@@ -678,124 +440,127 @@ patched_LdrLoadDll (PWCHAR filePath, PUL
   }
 
   dllName[len] = 0;
 
 #ifdef DEBUG_very_verbose
   printf_stderr("LdrLoadDll: dll name '%s'\n", dllName);
 #endif
 
-  // Block a suspicious binary that uses various 12-digit hex strings
-  // e.g. MovieMode.48CA2AEFA22D.dll (bug 973138)
-  dot = strchr(dllName, '.');
-  if (dot && (strchr(dot+1, '.') == dot+13)) {
-    char * end = nullptr;
-    _strtoui64(dot+1, &end, 16);
-    if (end == dot+13) {
-      return STATUS_DLL_NOT_FOUND;
-    }
-  }
-  // Block binaries where the filename is at least 16 hex digits
-  if (dot && ((dot - dllName) >= 16)) {
-    char * current = dllName;
-    while (current < dot && isxdigit(*current)) {
-      current++;
+  if (!(sInitFlags & eDllBlocklistInitFlagWasBootstrapped)) {
+    // Block a suspicious binary that uses various 12-digit hex strings
+    // e.g. MovieMode.48CA2AEFA22D.dll (bug 973138)
+    dot = strchr(dllName, '.');
+    if (dot && (strchr(dot+1, '.') == dot+13)) {
+      char * end = nullptr;
+      _strtoui64(dot+1, &end, 16);
+      if (end == dot+13) {
+        return STATUS_DLL_NOT_FOUND;
+      }
     }
-    if (current == dot) {
-      return STATUS_DLL_NOT_FOUND;
+    // Block binaries where the filename is at least 16 hex digits
+    if (dot && ((dot - dllName) >= 16)) {
+      char * current = dllName;
+      while (current < dot && isxdigit(*current)) {
+        current++;
+      }
+      if (current == dot) {
+        return STATUS_DLL_NOT_FOUND;
+      }
     }
-  }
 
-  // then compare to everything on the blocklist
-  while (info->name) {
-    if (strcmp(info->name, dllName) == 0)
-      break;
+    // then compare to everything on the blocklist
+    DECLARE_POINTER_TO_FIRST_DLL_BLOCKLIST_ENTRY(info);
+    while (info->name) {
+      if (strcmp(info->name, dllName) == 0)
+        break;
 
-    info++;
-  }
+      info++;
+    }
 
-  if (info->name) {
-    bool load_ok = false;
+    if (info->name) {
+      bool load_ok = false;
 
 #ifdef DEBUG_very_verbose
-    printf_stderr("LdrLoadDll: info->name: '%s'\n", info->name);
+      printf_stderr("LdrLoadDll: info->name: '%s'\n", info->name);
 #endif
 
-    if ((info->flags & DllBlockInfo::BLOCK_WIN8PLUS_ONLY) &&
-        !IsWin8OrLater()) {
-      goto continue_loading;
-    }
-
-    if ((info->flags & DllBlockInfo::BLOCK_WIN8_ONLY) &&
-        (!IsWin8OrLater() || IsWin8Point1OrLater())) {
-      goto continue_loading;
-    }
+      if ((info->flags & DllBlockInfo::BLOCK_WIN8PLUS_ONLY) &&
+          !IsWin8OrLater()) {
+        goto continue_loading;
+      }
 
-    if ((info->flags & DllBlockInfo::CHILD_PROCESSES_ONLY) &&
-        !(sInitFlags & eDllBlocklistInitFlagIsChildProcess)) {
-      goto continue_loading;
-    }
+      if ((info->flags & DllBlockInfo::BLOCK_WIN8_ONLY) &&
+          (!IsWin8OrLater() || IsWin8Point1OrLater())) {
+        goto continue_loading;
+      }
 
-    unsigned long long fVersion = ALL_VERSIONS;
-
-    if (info->maxVersion != ALL_VERSIONS) {
-      ReentrancySentinel sentinel(dllName);
-      if (sentinel.BailOut()) {
+      if ((info->flags & DllBlockInfo::CHILD_PROCESSES_ONLY) &&
+          !(sInitFlags & eDllBlocklistInitFlagIsChildProcess)) {
         goto continue_loading;
       }
 
-      full_fname = getFullPath(filePath, fname);
-      if (!full_fname) {
-        // uh, we couldn't find the DLL at all, so...
-        printf_stderr("LdrLoadDll: Blocking load of '%s' (SearchPathW didn't find it?)\n", dllName);
-        return STATUS_DLL_NOT_FOUND;
-      }
+      unsigned long long fVersion = ALL_VERSIONS;
 
-      if (info->flags & DllBlockInfo::USE_TIMESTAMP) {
-        fVersion = GetTimestamp(full_fname.get());
-        if (fVersion > info->maxVersion) {
-          load_ok = true;
+      if (info->maxVersion != ALL_VERSIONS) {
+        ReentrancySentinel sentinel(dllName);
+        if (sentinel.BailOut()) {
+          goto continue_loading;
         }
-      } else {
-        DWORD zero;
-        DWORD infoSize = GetFileVersionInfoSizeW(full_fname.get(), &zero);
+
+        full_fname = getFullPath(filePath, fname);
+        if (!full_fname) {
+          // uh, we couldn't find the DLL at all, so...
+          printf_stderr("LdrLoadDll: Blocking load of '%s' (SearchPathW didn't find it?)\n", dllName);
+          return STATUS_DLL_NOT_FOUND;
+        }
 
-        // If we failed to get the version information, we block.
+        if (info->flags & DllBlockInfo::USE_TIMESTAMP) {
+          fVersion = GetTimestamp(full_fname.get());
+          if (fVersion > info->maxVersion) {
+            load_ok = true;
+          }
+        } else {
+          DWORD zero;
+          DWORD infoSize = GetFileVersionInfoSizeW(full_fname.get(), &zero);
 
-        if (infoSize != 0) {
-          auto infoData = MakeUnique<unsigned char[]>(infoSize);
-          VS_FIXEDFILEINFO *vInfo;
-          UINT vInfoLen;
+          // If we failed to get the version information, we block.
 
-          if (GetFileVersionInfoW(full_fname.get(), 0, infoSize, infoData.get()) &&
-              VerQueryValueW(infoData.get(), L"\\", (LPVOID*) &vInfo, &vInfoLen))
-          {
-            fVersion =
-              ((unsigned long long)vInfo->dwFileVersionMS) << 32 |
-              ((unsigned long long)vInfo->dwFileVersionLS);
+          if (infoSize != 0) {
+            auto infoData = MakeUnique<unsigned char[]>(infoSize);
+            VS_FIXEDFILEINFO *vInfo;
+            UINT vInfoLen;
 
-            // finally do the version check, and if it's greater than our block
-            // version, keep loading
-            if (fVersion > info->maxVersion)
-              load_ok = true;
+            if (GetFileVersionInfoW(full_fname.get(), 0, infoSize, infoData.get()) &&
+                VerQueryValueW(infoData.get(), L"\\", (LPVOID*) &vInfo, &vInfoLen))
+            {
+              fVersion =
+                ((unsigned long long)vInfo->dwFileVersionMS) << 32 |
+                ((unsigned long long)vInfo->dwFileVersionLS);
+
+              // finally do the version check, and if it's greater than our block
+              // version, keep loading
+              if (fVersion > info->maxVersion)
+                load_ok = true;
+            }
           }
         }
       }
-    }
 
-    if (!load_ok) {
-      printf_stderr("LdrLoadDll: Blocking load of '%s' -- see http://www.mozilla.com/en-US/blocklist/\n", dllName);
-      DllBlockSet::Add(info->name, fVersion);
-      return STATUS_DLL_NOT_FOUND;
+      if (!load_ok) {
+        printf_stderr("LdrLoadDll: Blocking load of '%s' -- see http://www.mozilla.com/en-US/blocklist/\n", dllName);
+        DllBlockSet::Add(info->name, fVersion);
+        return STATUS_DLL_NOT_FOUND;
+      }
     }
   }
 
 continue_loading:
 #ifdef DEBUG_very_verbose
-  printf_stderr("LdrLoadDll: continuing load... ('%S')\n", moduleFileName->Buffer);
+    printf_stderr("LdrLoadDll: continuing load... ('%S')\n", moduleFileName->Buffer);
 #endif
 
   // A few DLLs such as xul.dll and nss3.dll get loaded before mozglue's
   // AutoProfilerLabel is initialized, and this is a no-op in those cases. But
   // the vast majority of DLLs do get labelled here.
   AutoProfilerLabel label("WindowsDllBlocklist::patched_LdrLoadDll", dllName,
                           __LINE__);
 
@@ -856,23 +621,31 @@ patched_BaseThreadInitThunk(BOOL aIsInit
 
   stub_BaseThreadInitThunk(aIsInitialThread, aStartAddress, aThreadParam);
 }
 
 
 static WindowsDllInterceptor NtDllIntercept;
 static WindowsDllInterceptor Kernel32Intercept;
 
+static void
+GetNativeNtBlockSetWriter();
+
 MFBT_API void
 DllBlocklist_Initialize(uint32_t aInitFlags)
 {
   if (sBlocklistInitAttempted) {
     return;
   }
   sInitFlags = aInitFlags;
+
+  if (sInitFlags & eDllBlocklistInitFlagWasBootstrapped) {
+    GetNativeNtBlockSetWriter();
+  }
+
   sBlocklistInitAttempted = true;
 #if defined(NIGHTLY_BUILD)
   gStartAddressesToBlock = new mozilla::Vector<void*, 4>;
 #endif
 
   // In order to be effective against AppInit DLLs, the blocklist must be
   // initialized before user32.dll is loaded into the process (bug 932100).
   if (GetModuleHandleA("user32.dll")) {
@@ -918,17 +691,17 @@ DllBlocklist_Initialize(uint32_t aInitFl
 
   // Bug 1361410: WRusr.dll will overwrite our hook and cause a crash.
   // Workaround: If we detect WRusr.dll, don't hook.
   if (!GetModuleHandleW(L"WRusr.dll")) {
     if(!Kernel32Intercept.AddDetour("BaseThreadInitThunk",
                                     reinterpret_cast<intptr_t>(patched_BaseThreadInitThunk),
                                     (void**) &stub_BaseThreadInitThunk)) {
 #ifdef DEBUG
-      printf_stderr("BaseThreadInitThunk hook failed\n");
+    printf_stderr("BaseThreadInitThunk hook failed\n");
 #endif
     }
   }
 
 #if defined(NIGHTLY_BUILD)
   // Populate a list of thread start addresses to block.
   HMODULE hKernel = GetModuleHandleW(L"kernel32.dll");
   if (hKernel) {
@@ -952,18 +725,18 @@ DllBlocklist_Initialize(uint32_t aInitFl
     pProc = (void*)GetProcAddress(hKernel, "LoadLibraryExW");
     if (pProc) {
       gStartAddressesToBlock->append(pProc);
     }
   }
 #endif
 }
 
-MFBT_API void
-DllBlocklist_WriteNotes(HANDLE file)
+static void
+InternalWriteNotes(HANDLE file)
 {
   DWORD nBytes;
 
   WriteFile(file, kBlockedDllsParameter, kBlockedDllsParameterLen, &nBytes, nullptr);
   DllBlockSet::Write(file);
   WriteFile(file, "\n", 1, &nBytes, nullptr);
 
   if (sBlocklistInitFailed) {
@@ -972,16 +745,36 @@ DllBlocklist_WriteNotes(HANDLE file)
   }
 
   if (sUser32BeforeBlocklist) {
     WriteFile(file, kUser32BeforeBlocklistParameter,
               kUser32BeforeBlocklistParameterLen, &nBytes, nullptr);
   }
 }
 
+using WriterFn = void (*)(HANDLE);
+static WriterFn gWriterFn = &InternalWriteNotes;
+
+static void
+GetNativeNtBlockSetWriter()
+{
+  auto nativeWriter = reinterpret_cast<WriterFn>(
+    ::GetProcAddress(::GetModuleHandleW(nullptr), "NativeNtBlockSet_Write"));
+  if (nativeWriter) {
+    gWriterFn = nativeWriter;
+  }
+}
+
+MFBT_API void
+DllBlocklist_WriteNotes(HANDLE file)
+{
+  MOZ_ASSERT(gWriterFn);
+  gWriterFn(file);
+}
+
 MFBT_API bool
 DllBlocklist_CheckStatus()
 {
   if (sBlocklistInitFailed || sUser32BeforeBlocklist)
     return false;
   return true;
 }
 
--- a/mozglue/build/WindowsDllBlocklist.h
+++ b/mozglue/build/WindowsDllBlocklist.h
@@ -12,17 +12,18 @@
 #include "mozilla/Attributes.h"
 #include "mozilla/Types.h"
 
 #define HAS_DLL_BLOCKLIST
 
 enum DllBlocklistInitFlags
 {
   eDllBlocklistInitFlagDefault = 0,
-  eDllBlocklistInitFlagIsChildProcess = 1
+  eDllBlocklistInitFlagIsChildProcess = 1,
+  eDllBlocklistInitFlagWasBootstrapped = 2
 };
 
 MFBT_API void DllBlocklist_Initialize(uint32_t aInitFlags = eDllBlocklistInitFlagDefault);
 MFBT_API void DllBlocklist_WriteNotes(HANDLE file);
 MFBT_API bool DllBlocklist_CheckStatus();
 
 // Forward declaration
 namespace mozilla {
new file mode 100644
--- /dev/null
+++ b/mozglue/build/WindowsDllBlocklistCommon.h
@@ -0,0 +1,83 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_WindowsDllBlocklistCommon_h
+#define mozilla_WindowsDllBlocklistCommon_h
+
+#include <stdint.h>
+
+namespace mozilla {
+
+template <typename CharType>
+struct DllBlockInfoT {
+  // The name of the DLL -- in LOWERCASE!  It will be compared to
+  // a lowercase version of the DLL name only.
+  const CharType* name;
+
+  // If maxVersion is ALL_VERSIONS, we'll block all versions of this
+  // dll.  Otherwise, we'll block all versions less than or equal to
+  // the given version, as queried by GetFileVersionInfo and
+  // VS_FIXEDFILEINFO's dwFileVersionMS and dwFileVersionLS fields.
+  //
+  // Note that the version is usually 4 components, which is A.B.C.D
+  // encoded as 0x AAAA BBBB CCCC DDDD ULL (spaces added for clarity),
+  // but it's not required to be of that format.
+  uint64_t maxVersion;
+
+  // If the USE_TIMESTAMP flag is set, then we use the timestamp from
+  // the IMAGE_FILE_HEADER in lieu of a version number.
+  //
+  // If the CHILD_PROCESSES_ONLY flag is set, then the dll is blocked
+  // only when we are a child process.
+  enum Flags {
+    FLAGS_DEFAULT = 0,
+    BLOCK_WIN8PLUS_ONLY = 1,
+    BLOCK_WIN8_ONLY = 2,
+    USE_TIMESTAMP = 4,
+    CHILD_PROCESSES_ONLY = 8
+  } flags;
+
+  static const uint64_t ALL_VERSIONS = (uint64_t) -1LL;
+
+  // DLLs sometimes ship without a version number, particularly early
+  // releases. Blocking "version <= 0" has the effect of blocking unversioned
+  // DLLs (since the call to get version info fails), but not blocking
+  // any versioned instance.
+  static const uint64_t UNVERSIONED = 0ULL;
+};
+
+} // namespace mozilla
+
+// Convert the 4 (decimal) components of a DLL version number into a
+// single unsigned long long, as needed by the blocklist
+static inline constexpr uint64_t
+MAKE_VERSION(uint16_t a, uint16_t b, uint16_t c, uint16_t d)
+{
+  return static_cast<uint64_t>(a) << 48 |
+         static_cast<uint64_t>(b) << 32 |
+         static_cast<uint64_t>(c) << 16 |
+         static_cast<uint64_t>(d);
+}
+
+#if !defined(DLL_BLOCKLIST_CHAR_TYPE)
+#error "You must define DLL_BLOCKLIST_CHAR_TYPE"
+#endif // !defined(DLL_BLOCKLIST_CHAR_TYPE)
+
+#define DLL_BLOCKLIST_DEFINITIONS_BEGIN \
+  using DllBlockInfo = mozilla::DllBlockInfoT<DLL_BLOCKLIST_CHAR_TYPE>; \
+  static const DllBlockInfo gWindowsDllBlocklist[] = {
+
+#define ALL_VERSIONS DllBlockInfo::ALL_VERSIONS
+#define UNVERSIONED DllBlockInfo::UNVERSIONED
+
+#define DLL_BLOCKLIST_DEFINITIONS_END \
+    {nullptr, 0} \
+  };
+
+#define DECLARE_POINTER_TO_FIRST_DLL_BLOCKLIST_ENTRY(name) \
+  const DllBlockInfo* name = &gWindowsDllBlocklist[0]
+
+#endif // mozilla_WindowsDllBlocklistCommon_h
new file mode 100644
--- /dev/null
+++ b/mozglue/build/WindowsDllBlocklistDefs.h
@@ -0,0 +1,206 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_WindowsDllBlocklistDefs_h
+#define mozilla_WindowsDllBlocklistDefs_h
+
+#include "mozilla/WindowsDllBlocklistCommon.h"
+
+DLL_BLOCKLIST_DEFINITIONS_BEGIN
+
+// EXAMPLE:
+// DLL_BLOCKLIST_ENTRY("uxtheme.dll", ALL_VERSIONS)
+// DLL_BLOCKLIST_ENTRY("uxtheme.dll", 0x0000123400000000ULL)
+// The DLL name must be in lowercase!
+// The version field is a maximum, that is, we block anything that is
+// less-than or equal to that version.
+
+// NPFFAddon - Known malware
+DLL_BLOCKLIST_ENTRY("npffaddon.dll", ALL_VERSIONS)
+
+// AVG 8 - Antivirus vendor AVG, old version, plugin already blocklisted
+DLL_BLOCKLIST_ENTRY("avgrsstx.dll", MAKE_VERSION(8,5,0,401))
+
+// calc.dll - Suspected malware
+DLL_BLOCKLIST_ENTRY("calc.dll", MAKE_VERSION(1,0,0,1))
+
+// hook.dll - Suspected malware
+DLL_BLOCKLIST_ENTRY("hook.dll", ALL_VERSIONS)
+
+// GoogleDesktopNetwork3.dll - Extremely old, unversioned instances
+// of this DLL cause crashes
+DLL_BLOCKLIST_ENTRY("googledesktopnetwork3.dll", UNVERSIONED)
+
+// rdolib.dll - Suspected malware
+DLL_BLOCKLIST_ENTRY("rdolib.dll", MAKE_VERSION(6,0,88,4))
+
+// fgjk4wvb.dll - Suspected malware
+DLL_BLOCKLIST_ENTRY("fgjk4wvb.dll", MAKE_VERSION(8,8,8,8))
+
+// radhslib.dll - Naomi internet filter - unmaintained since 2006
+DLL_BLOCKLIST_ENTRY("radhslib.dll", UNVERSIONED)
+
+// Music download filter for vkontakte.ru - old instances
+// of this DLL cause crashes
+DLL_BLOCKLIST_ENTRY("vksaver.dll", MAKE_VERSION(2,2,2,0))
+
+// Topcrash in Firefox 4.0b1
+DLL_BLOCKLIST_ENTRY("rlxf.dll", MAKE_VERSION(1,2,323,1))
+
+// psicon.dll - Topcrashes in Thunderbird, and some crashes in Firefox
+// Adobe photoshop library, now redundant in later installations
+DLL_BLOCKLIST_ENTRY("psicon.dll", ALL_VERSIONS)
+
+// Topcrash in Firefox 4 betas (bug 618899)
+DLL_BLOCKLIST_ENTRY("accelerator.dll", MAKE_VERSION(3,2,1,6))
+
+// Topcrash with Roboform in Firefox 8 (bug 699134)
+DLL_BLOCKLIST_ENTRY("rf-firefox.dll", MAKE_VERSION(7,6,1,0))
+DLL_BLOCKLIST_ENTRY("roboform.dll", MAKE_VERSION(7,6,1,0))
+
+// Topcrash with Babylon Toolbar on FF16+ (bug 721264)
+DLL_BLOCKLIST_ENTRY("babyfox.dll", ALL_VERSIONS)
+
+// sprotector.dll crashes, bug 957258
+DLL_BLOCKLIST_ENTRY("sprotector.dll", ALL_VERSIONS)
+
+// leave these two in always for tests
+DLL_BLOCKLIST_ENTRY("mozdllblockingtest.dll", ALL_VERSIONS)
+DLL_BLOCKLIST_ENTRY("mozdllblockingtest_versioned.dll", 0x0000000400000000ULL)
+
+// Windows Media Foundation FLAC decoder and type sniffer (bug 839031).
+DLL_BLOCKLIST_ENTRY("mfflac.dll", ALL_VERSIONS)
+
+// Older Relevant Knowledge DLLs cause us to crash (bug 904001).
+DLL_BLOCKLIST_ENTRY("rlnx.dll", MAKE_VERSION(1, 3, 334, 9))
+DLL_BLOCKLIST_ENTRY("pmnx.dll", MAKE_VERSION(1, 3, 334, 9))
+DLL_BLOCKLIST_ENTRY("opnx.dll", MAKE_VERSION(1, 3, 334, 9))
+DLL_BLOCKLIST_ENTRY("prnx.dll", MAKE_VERSION(1, 3, 334, 9))
+
+// Older belgian ID card software causes Firefox to crash or hang on
+// shutdown, bug 831285 and 918399.
+DLL_BLOCKLIST_ENTRY("beid35cardlayer.dll", MAKE_VERSION(3, 5, 6, 6968))
+
+// bug 925459, bitguard crashes
+DLL_BLOCKLIST_ENTRY("bitguard.dll", ALL_VERSIONS)
+
+// bug 812683 - crashes in Windows library when Asus Gamer OSD is installed
+// Software is discontinued/unsupported
+DLL_BLOCKLIST_ENTRY("atkdx11disp.dll", ALL_VERSIONS)
+
+// Topcrash with Conduit SearchProtect, bug 944542
+DLL_BLOCKLIST_ENTRY("spvc32.dll", ALL_VERSIONS)
+
+// Topcrash with V-bates, bug 1002748 and bug 1023239
+DLL_BLOCKLIST_ENTRY("libinject.dll", UNVERSIONED)
+DLL_BLOCKLIST_ENTRY("libinject2.dll", 0x537DDC93, DllBlockInfo::USE_TIMESTAMP)
+DLL_BLOCKLIST_ENTRY("libredir2.dll", 0x5385B7ED, DllBlockInfo::USE_TIMESTAMP)
+
+// Crashes with RoboForm2Go written against old SDK, bug 988311/1196859
+DLL_BLOCKLIST_ENTRY("rf-firefox-22.dll", ALL_VERSIONS)
+DLL_BLOCKLIST_ENTRY("rf-firefox-40.dll", ALL_VERSIONS)
+
+// Crashes with DesktopTemperature, bug 1046382
+DLL_BLOCKLIST_ENTRY("dtwxsvc.dll", 0x53153234, DllBlockInfo::USE_TIMESTAMP)
+
+// Startup crashes with Lenovo Onekey Theater, bug 1123778
+DLL_BLOCKLIST_ENTRY("activedetect32.dll", UNVERSIONED)
+DLL_BLOCKLIST_ENTRY("activedetect64.dll", UNVERSIONED)
+DLL_BLOCKLIST_ENTRY("windowsapihookdll32.dll", UNVERSIONED)
+DLL_BLOCKLIST_ENTRY("windowsapihookdll64.dll", UNVERSIONED)
+
+// Flash crashes with RealNetworks RealDownloader, bug 1132663
+DLL_BLOCKLIST_ENTRY("rndlnpshimswf.dll", ALL_VERSIONS)
+DLL_BLOCKLIST_ENTRY("rndlmainbrowserrecordplugin.dll", ALL_VERSIONS)
+
+// Startup crashes with RealNetworks Browser Record Plugin, bug 1170141
+DLL_BLOCKLIST_ENTRY("nprpffbrowserrecordext.dll", ALL_VERSIONS)
+DLL_BLOCKLIST_ENTRY("nprndlffbrowserrecordext.dll", ALL_VERSIONS)
+
+// Crashes with CyberLink YouCam, bug 1136968
+DLL_BLOCKLIST_ENTRY("ycwebcamerasource.ax", MAKE_VERSION(2, 0, 0, 1611))
+
+// Old version of WebcamMax crashes WebRTC, bug 1130061
+DLL_BLOCKLIST_ENTRY("vwcsource.ax", MAKE_VERSION(1, 5, 0, 0))
+
+// NetOp School, discontinued product, bug 763395
+DLL_BLOCKLIST_ENTRY("nlsp.dll", MAKE_VERSION(6, 23, 2012, 19))
+
+// Orbit Downloader, bug 1222819
+DLL_BLOCKLIST_ENTRY("grabdll.dll", MAKE_VERSION(2, 6, 1, 0))
+DLL_BLOCKLIST_ENTRY("grabkernel.dll", MAKE_VERSION(1, 0, 0, 1))
+
+// ESET, bug 1229252
+DLL_BLOCKLIST_ENTRY("eoppmonitor.dll", ALL_VERSIONS)
+
+// SS2OSD, bug 1262348
+DLL_BLOCKLIST_ENTRY("ss2osd.dll", ALL_VERSIONS)
+DLL_BLOCKLIST_ENTRY("ss2devprops.dll", ALL_VERSIONS)
+
+// NHASUSSTRIXOSD.DLL, bug 1269244
+DLL_BLOCKLIST_ENTRY("nhasusstrixosd.dll", ALL_VERSIONS)
+DLL_BLOCKLIST_ENTRY("nhasusstrixdevprops.dll", ALL_VERSIONS)
+
+// Crashes with PremierOpinion/RelevantKnowledge, bug 1277846
+DLL_BLOCKLIST_ENTRY("opls.dll", ALL_VERSIONS)
+DLL_BLOCKLIST_ENTRY("opls64.dll", ALL_VERSIONS)
+DLL_BLOCKLIST_ENTRY("pmls.dll", ALL_VERSIONS)
+DLL_BLOCKLIST_ENTRY("pmls64.dll", ALL_VERSIONS)
+DLL_BLOCKLIST_ENTRY("prls.dll", ALL_VERSIONS)
+DLL_BLOCKLIST_ENTRY("prls64.dll", ALL_VERSIONS)
+DLL_BLOCKLIST_ENTRY("rlls.dll", ALL_VERSIONS)
+DLL_BLOCKLIST_ENTRY("rlls64.dll", ALL_VERSIONS)
+
+// Vorbis DirectShow filters, bug 1239690.
+DLL_BLOCKLIST_ENTRY("vorbis.acm", MAKE_VERSION(0, 0, 3, 6))
+
+// AhnLab Internet Security, bug 1311969
+DLL_BLOCKLIST_ENTRY("nzbrcom.dll", ALL_VERSIONS)
+
+// K7TotalSecurity, bug 1339083.
+DLL_BLOCKLIST_ENTRY("k7pswsen.dll", MAKE_VERSION(15, 2, 2, 95))
+
+// smci*.dll - goobzo crashware (bug 1339908)
+DLL_BLOCKLIST_ENTRY("smci32.dll", ALL_VERSIONS)
+DLL_BLOCKLIST_ENTRY("smci64.dll", ALL_VERSIONS)
+
+// Crashes with Internet Download Manager, bug 1333486
+DLL_BLOCKLIST_ENTRY("idmcchandler7.dll", ALL_VERSIONS)
+DLL_BLOCKLIST_ENTRY("idmcchandler7_64.dll", ALL_VERSIONS)
+DLL_BLOCKLIST_ENTRY("idmcchandler5.dll", ALL_VERSIONS)
+DLL_BLOCKLIST_ENTRY("idmcchandler5_64.dll", ALL_VERSIONS)
+
+// Nahimic 2 breaks applicaton update (bug 1356637)
+DLL_BLOCKLIST_ENTRY("nahimic2devprops.dll", MAKE_VERSION(2, 5, 19, 0xffff))
+// Nahimic is causing crashes, bug 1233556
+DLL_BLOCKLIST_ENTRY("nahimicmsiosd.dll", UNVERSIONED)
+// Nahimic is causing crashes, bug 1360029
+DLL_BLOCKLIST_ENTRY("nahimicvrdevprops.dll", UNVERSIONED)
+DLL_BLOCKLIST_ENTRY("nahimic2osd.dll", MAKE_VERSION(2, 5, 19, 0xffff))
+DLL_BLOCKLIST_ENTRY("nahimicmsidevprops.dll", UNVERSIONED)
+
+// Bug 1268470 - crashes with Kaspersky Lab on Windows 8
+DLL_BLOCKLIST_ENTRY("klsihk64.dll", MAKE_VERSION(14, 0, 456, 0xffff), DllBlockInfo::BLOCK_WIN8_ONLY)
+
+// Bug 1407337, crashes with OpenSC < 0.16.0
+DLL_BLOCKLIST_ENTRY("onepin-opensc-pkcs11.dll", MAKE_VERSION(0, 15, 0xffff, 0xffff))
+
+// Avecto Privilege Guard causes crashes, bug 1385542
+DLL_BLOCKLIST_ENTRY("pghook.dll", ALL_VERSIONS)
+
+// Old versions of G DATA BankGuard, bug 1421991
+DLL_BLOCKLIST_ENTRY("banksafe64.dll", MAKE_VERSION(1, 2, 15299, 65535))
+
+// Old versions of G DATA, bug 1043775
+DLL_BLOCKLIST_ENTRY("gdkbfltdll64.dll", MAKE_VERSION(1, 0, 14141, 240))
+
+// Dell Backup and Recovery tool causes crashes, bug 1433408
+DLL_BLOCKLIST_ENTRY("dbroverlayiconnotbackuped.dll", MAKE_VERSION(1, 8, 0, 9))
+DLL_BLOCKLIST_ENTRY("dbroverlayiconbackuped.dll", MAKE_VERSION(1, 8, 0, 9))
+
+DLL_BLOCKLIST_DEFINITIONS_END
+
+#endif // mozilla_WindowsDllBlocklistDefs_h
--- a/mozglue/build/moz.build
+++ b/mozglue/build/moz.build
@@ -67,16 +67,18 @@ if CONFIG['MOZ_WIDGET_TOOLKIT']:
             'wintrust',
         ]
         DELAYLOAD_DLLS += [
             'crypt32.dll',
             'wintrust.dll',
         ]
         EXPORTS.mozilla += [
             'Authenticode.h',
+            'WindowsDllBlocklistCommon.h',
+            'WindowsDllBlocklistDefs.h',
         ]
         EXPORTS.mozilla.glue += [
             'WindowsDllServices.h',
         ]
 
     EXPORTS.mozilla += [
         'arm.h',
         'mips.h',