Bug 1467736: Add support for DllBlocklist_Shutdown;r?aklotz draft
authorCarl Corcoran <ccorcoran@mozilla.com>
Thu, 19 Jul 2018 21:27:29 +0200
changeset 820724 d180a9d66d6fa83f5c1fe3f79158ad1546f7e4b7
parent 819215 547144f5596c1a146b208d68d93950a6313080ca
push id116909
push userbmo:ccorcoran@mozilla.com
push dateFri, 20 Jul 2018 08:54:07 +0000
reviewersaklotz
bugs1467736
milestone63.0a1
Bug 1467736: Add support for DllBlocklist_Shutdown;r?aklotz MozReview-Commit-ID: 9FCEeInmopX
browser/app/nsBrowserApp.cpp
ipc/app/MozillaRuntimeMain.cpp
js/xpconnect/shell/xpcshell.cpp
mozglue/build/WindowsDllBlocklist.cpp
mozglue/build/WindowsDllBlocklist.h
toolkit/crashreporter/nsExceptionHandler.cpp
--- a/browser/app/nsBrowserApp.cpp
+++ b/browser/app/nsBrowserApp.cpp
@@ -281,16 +281,20 @@ int main(int argc, char* argv[], char* e
 
     nsresult rv = InitXPCOMGlue();
     if (NS_FAILED(rv)) {
       return 255;
     }
 
     int result = content_process_main(gBootstrap.get(), argc, argv);
 
+#ifdef HAS_DLL_BLOCKLIST
+  DllBlocklist_Shutdown();
+#endif
+
     // InitXPCOMGlue calls NS_LogInit, so we need to balance it here.
     gBootstrap->NS_LogTerm();
 
     return result;
   }
 #endif
 
 #ifdef HAS_DLL_BLOCKLIST
@@ -307,16 +311,20 @@ int main(int argc, char* argv[], char* e
 #ifdef MOZ_BROWSER_CAN_BE_CONTENTPROC
   gBootstrap->XRE_EnableSameExecutableForContentProc();
 #endif
 
   int result = do_main(argc, argv, envp);
 
   gBootstrap->NS_LogTerm();
 
+#ifdef HAS_DLL_BLOCKLIST
+  DllBlocklist_Shutdown();
+#endif
+
 #ifdef XP_MACOSX
   // Allow writes again. While we would like to catch writes from static
   // destructors to allow early exits to use _exit, we know that there is
   // at least one such write that we don't control (see bug 826029). For
   // now we enable writes again and early exits will have to use exit instead
   // of _exit.
   gBootstrap->XRE_StopLateWriteChecks();
 #endif
--- a/ipc/app/MozillaRuntimeMain.cpp
+++ b/ipc/app/MozillaRuntimeMain.cpp
@@ -17,10 +17,14 @@ main(int argc, char *argv[])
 #ifdef HAS_DLL_BLOCKLIST
   DllBlocklist_Initialize(eDllBlocklistInitFlagIsChildProcess);
 #endif
 
   Bootstrap::UniquePtr bootstrap = GetBootstrap();
   if (!bootstrap) {
     return 2;
   }
-  return content_process_main(bootstrap.get(), argc, argv);
+  int ret = content_process_main(bootstrap.get(), argc, argv);
+#ifdef HAS_DLL_BLOCKLIST
+  DllBlocklist_Shutdown();
+#endif
+  return ret;
 }
--- a/js/xpconnect/shell/xpcshell.cpp
+++ b/js/xpconnect/shell/xpcshell.cpp
@@ -61,14 +61,18 @@ main(int argc, char** argv, char** envp)
 
     mozilla::Bootstrap::UniquePtr bootstrap = mozilla::GetBootstrap();
     if (!bootstrap) {
         return 2;
     }
 
     int result = bootstrap->XRE_XPCShellMain(argc, argv, envp, &shellData);
 
+#ifdef HAS_DLL_BLOCKLIST
+  DllBlocklist_Shutdown();
+#endif
+
 #ifdef XP_MACOSX
     FinishAutoreleasePool();
 #endif
 
     return result;
 }
--- a/mozglue/build/WindowsDllBlocklist.cpp
+++ b/mozglue/build/WindowsDllBlocklist.cpp
@@ -774,16 +774,23 @@ DllBlocklist_Initialize(uint32_t aInitFl
     pProc = (void*)GetProcAddress(hKernel, "LoadLibraryExW");
     if (pProc) {
       gStartAddressesToBlock->append(pProc);
     }
   }
 #endif
 }
 
+#ifdef DEBUG
+MFBT_API void
+DllBlocklist_DebugShutdown()
+{
+}
+#endif // DEBUG
+
 static void
 InternalWriteNotes(HANDLE file)
 {
   DWORD nBytes;
 
   WriteFile(file, kBlockedDllsParameter, kBlockedDllsParameterLen, &nBytes, nullptr);
   DllBlockSet::Write(file);
   WriteFile(file, "\n", 1, &nBytes, nullptr);
--- a/mozglue/build/WindowsDllBlocklist.h
+++ b/mozglue/build/WindowsDllBlocklist.h
@@ -23,16 +23,31 @@ enum DllBlocklistInitFlags
   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();
 
+// This export intends to clean up after DllBlocklist_Initialize().
+// It's disabled in release builds for performance and to limit callers' ability
+// to interfere with dll blocking.
+#ifdef DEBUG
+MFBT_API void DllBlocklist_DebugShutdown();
+#endif // DEBUG
+
+MOZ_ALWAYS_INLINE_EVEN_DEBUG void
+DllBlocklist_Shutdown()
+{
+#ifdef DEBUG
+  DllBlocklist_DebugShutdown();
+#endif // DEBUG
+}
+
 #ifdef ENABLE_TESTS
 typedef void (*DllLoadHookType)(bool aDllLoaded, NTSTATUS aNtStatus,
                                 HANDLE aDllBase, PUNICODE_STRING aDllName);
 MFBT_API void DllBlocklist_SetDllLoadHook(DllLoadHookType aHook);
 typedef void (*CreateThreadHookType)(bool aWasAllowed, void *aStartAddress);
 MFBT_API void DllBlocklist_SetCreateThreadHook(CreateThreadHookType aHook);
 #endif // ENABLE_TESTS
 
--- a/toolkit/crashreporter/nsExceptionHandler.cpp
+++ b/toolkit/crashreporter/nsExceptionHandler.cpp
@@ -1335,16 +1335,19 @@ FreeBreakpadVM()
  *
  * Also calls FreeBreakpadVM if appropriate.
  */
 static bool FPEFilter(void* context, EXCEPTION_POINTERS* exinfo,
                       MDRawAssertionInfo* assertion)
 {
   if (!exinfo) {
     mozilla::IOInterposer::Disable();
+#ifdef HAS_DLL_BLOCKLIST
+    DllBlocklist_Shutdown();
+#endif
     FreeBreakpadVM();
     return true;
   }
 
   PEXCEPTION_RECORD e = (PEXCEPTION_RECORD)exinfo->ExceptionRecord;
   switch (e->ExceptionCode) {
     case STATUS_FLOAT_DENORMAL_OPERAND:
     case STATUS_FLOAT_DIVIDE_BY_ZERO:
@@ -1353,16 +1356,19 @@ static bool FPEFilter(void* context, EXC
     case STATUS_FLOAT_OVERFLOW:
     case STATUS_FLOAT_STACK_CHECK:
     case STATUS_FLOAT_UNDERFLOW:
     case STATUS_FLOAT_MULTIPLE_FAULTS:
     case STATUS_FLOAT_MULTIPLE_TRAPS:
       return false; // Don't write minidump, continue exception search
   }
   mozilla::IOInterposer::Disable();
+#ifdef HAS_DLL_BLOCKLIST
+    DllBlocklist_Shutdown();
+#endif
   FreeBreakpadVM();
   return true;
 }
 
 static bool
 ChildFPEFilter(void* context, EXCEPTION_POINTERS* exinfo,
                MDRawAssertionInfo* assertion)
 {
@@ -1421,16 +1427,19 @@ static bool ShouldReport()
 
   return true;
 }
 
 static bool
 Filter(void* context)
 {
   mozilla::IOInterposer::Disable();
+#ifdef HAS_DLL_BLOCKLIST
+    DllBlocklist_Shutdown();
+#endif
   return true;
 }
 
 static bool
 ChildFilter(void* context)
 {
   bool result = Filter(context);
   if (result) {
@@ -3782,16 +3791,20 @@ GetChildThread(ProcessHandle childPid, T
 }
 #endif
 
 bool TakeMinidump(nsIFile** aResult, bool aMoveToPending)
 {
   if (!GetEnabled())
     return false;
 
+#ifdef HAS_DLL_BLOCKLIST
+  DllBlocklist_Shutdown();
+#endif
+
   AutoIOInterposerDisable disableIOInterposition;
 
   xpstring dump_path;
 #ifndef XP_LINUX
   dump_path = gExceptionHandler->dump_path();
 #else
   dump_path = gExceptionHandler->minidump_descriptor().directory();
 #endif
@@ -3903,16 +3916,19 @@ CreateMinidumpsAndPair(ProcessHandle aTa
                        nsIFile** aMainDumpOut,
                        std::function<void(bool)>&& aCallback,
                        bool aAsync)
 {
   if (!GetEnabled()) {
     aCallback(false);
     return;
   }
+#ifdef HAS_DLL_BLOCKLIST
+  DllBlocklist_Shutdown();
+#endif
 
   AutoIOInterposerDisable disableIOInterposition;
 
   xpstring dump_path;
 #ifndef XP_LINUX
   dump_path = gExceptionHandler->dump_path();
 #else
   dump_path = gExceptionHandler->minidump_descriptor().directory();