Bug 1035125 Part 8: Pass sandboxing pointers through XRE_InitChildProcess instead of linking to more functions in xul. r?aklotz, r?glandium draft
authorBob Owen <bobowencode@gmail.com>
Sun, 15 May 2016 16:35:22 +0100
changeset 367185 7bf9f9ec88671786b5d299f5f7f40408d61750fc
parent 367184 02c7fc57b7e48867373576290cb872f583103711
child 367186 e8f550c440a17fe6e6d6844e3914b0ae922cc5d5
push id18159
push userbobowencode@gmail.com
push dateSun, 15 May 2016 15:37:30 +0000
reviewersaklotz, glandium
bugs1035125
milestone49.0a1
Bug 1035125 Part 8: Pass sandboxing pointers through XRE_InitChildProcess instead of linking to more functions in xul. r?aklotz, r?glandium MozReview-Commit-ID: 5AiktOArpfU
dom/media/gmp/GMPLoader.cpp
dom/media/gmp/GMPLoader.h
ipc/contentproc/plugin-container.cpp
mozglue/android/APKOpen.cpp
security/sandbox/chromium-shim/sandbox/win/loggingCallbacks.h
security/sandbox/chromium-shim/sandbox/win/sandboxLogging.h
security/sandbox/moz.build
security/sandbox/win/SandboxInitialization.cpp
security/sandbox/win/SandboxInitialization.h
security/sandbox/win/src/sandboxtarget/sandboxTarget.h
toolkit/xre/moz.build
toolkit/xre/nsEmbedFunctions.cpp
xpcom/build/XREChildData.h
xpcom/build/moz.build
xpcom/build/nsXULAppAPI.h
--- a/dom/media/gmp/GMPLoader.cpp
+++ b/dom/media/gmp/GMPLoader.cpp
@@ -2,21 +2,19 @@
  * vim: sw=4 ts=4 et :
  * 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 http://mozilla.org/MPL/2.0/. */
 
 #include "GMPLoader.h"
 #include <stdio.h>
 #include "mozilla/Attributes.h"
-#include "mozilla/UniquePtr.h"
 #include "gmp-entrypoints.h"
 #include "prlink.h"
 #include "prenv.h"
-#include "nsAutoPtr.h"
 
 #include <string>
 
 #ifdef XP_WIN
 #include "windows.h"
 #ifdef MOZ_SANDBOX
 #include <intrin.h>
 #include <assert.h>
@@ -74,18 +72,18 @@ public:
   void SetSandboxInfo(MacSandboxInfo* aSandboxInfo) override;
 #endif
 
 private:
   SandboxStarter* mSandboxStarter;
   UniquePtr<GMPAdapter> mAdapter;
 };
 
-GMPLoader* CreateGMPLoader(SandboxStarter* aStarter) {
-  return static_cast<GMPLoader*>(new GMPLoaderImpl(aStarter));
+UniquePtr<GMPLoader> CreateGMPLoader(SandboxStarter* aStarter) {
+  return MakeUnique<GMPLoaderImpl>(aStarter);
 }
 
 class PassThroughGMPAdapter : public GMPAdapter {
 public:
   ~PassThroughGMPAdapter() {
     // Ensure we're always shutdown, even if caller forgets to call GMPShutdown().
     GMPShutdown();
   }
--- a/dom/media/gmp/GMPLoader.h
+++ b/dom/media/gmp/GMPLoader.h
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef GMP_LOADER_H__
 #define GMP_LOADER_H__
 
 #include <stdint.h>
 #include "prlink.h"
 #include "gmp-entrypoints.h"
+#include "mozilla/UniquePtr.h"
 
 #if defined(XP_MACOSX) && defined(MOZ_GMP_SANDBOX)
 #include "mozilla/Sandbox.h"
 #endif
 
 namespace mozilla {
 namespace gmp {
 
@@ -93,14 +94,14 @@ public:
   // sandbox, which we don't yet know when the GMPLoader and SandboxStarter
   // objects are created.
   virtual void SetSandboxInfo(MacSandboxInfo* aSandboxInfo) = 0;
 #endif
 };
 
 // On Desktop, this function resides in plugin-container.
 // On Mobile, this function resides in XUL.
-GMPLoader* CreateGMPLoader(SandboxStarter* aStarter);
+UniquePtr<GMPLoader> CreateGMPLoader(SandboxStarter* aStarter);
 
 } // namespace gmp
 } // namespace mozilla
 
 #endif // GMP_LOADER_H__
--- a/ipc/contentproc/plugin-container.cpp
+++ b/ipc/contentproc/plugin-container.cpp
@@ -20,19 +20,18 @@
 #define XRE_DONT_PROTECT_DLL_LOAD
 #include "nsWindowsWMain.cpp"
 #include "nsSetDllDirectory.h"
 #endif
 
 #include "GMPLoader.h"
 
 #if defined(XP_WIN) && defined(MOZ_SANDBOX)
-#include "mozilla/sandboxTarget.h"
-#include "mozilla/sandboxing/loggingCallbacks.h"
-#include "sandbox/win/src/sandbox_factory.h"
+#include "mozilla/sandboxing/SandboxInitialization.h"
+#include "mozilla/sandboxing/sandboxLogging.h"
 #endif
 
 #if defined(XP_LINUX) && defined(MOZ_GMP_SANDBOX)
 #include "mozilla/Sandbox.h"
 #include "mozilla/SandboxInfo.h"
 #endif
 
 #ifdef MOZ_WIDGET_GONK
@@ -81,17 +80,17 @@ InitializeBinder(void *aDummy) {
 
 #if defined(XP_WIN) && defined(MOZ_SANDBOX)
 static bool gIsSandboxEnabled = false;
 
 class WinSandboxStarter : public mozilla::gmp::SandboxStarter {
 public:
     virtual bool Start(const char *aLibPath) override {
         if (gIsSandboxEnabled) {
-            sandbox::SandboxFactory::GetTargetServices()->LowerToken();
+            mozilla::sandboxing::LowerSandbox();
         }
         return true;
     }
 };
 #endif
 
 #if defined(XP_LINUX) && defined(MOZ_GMP_SANDBOX)
 class LinuxSandboxStarter : public mozilla::gmp::SandboxStarter {
@@ -158,31 +157,27 @@ content_process_main(int argc, char* arg
     bool isNuwa = false;
     for (int i = 1; i < argc; i++) {
         isNuwa |= strcmp(argv[i], "-nuwa") == 0;
 #if defined(XP_WIN) && defined(MOZ_SANDBOX)
         gIsSandboxEnabled |= strcmp(argv[i], "-sandbox") == 0;
 #endif
     }
 
+    XREChildData childData;
+
 #if defined(XP_WIN) && defined(MOZ_SANDBOX)
     if (gIsSandboxEnabled) {
-        sandbox::TargetServices* target_service =
-            sandbox::SandboxFactory::GetTargetServices();
-        if (!target_service) {
+        childData.sandboxTargetServices =
+            mozilla::sandboxing::GetInitializedTargetServices();
+        if (!childData.sandboxTargetServices) {
             return 1;
         }
 
-        sandbox::ResultCode result = target_service->Init();
-        if (result != sandbox::SBOX_ALL_OK) {
-           return 2;
-        }
-
-        mozilla::SandboxTarget::Instance()->SetTargetServices(target_service);
-        mozilla::sandboxing::PrepareForLogging();
+        childData.ProvideLogFunction = mozilla::sandboxing::ProvideLogFunction;
     }
 #endif
 
     XRE_SetProcessType(argv[--argc]);
 
 #ifdef MOZ_NUWA_PROCESS
     if (isNuwa) {
         PrepareNuwaProcess();
@@ -220,22 +215,21 @@ content_process_main(int argc, char* arg
     // For plugins, this is done in PluginProcessChild::Init, as we need to
     // avoid it for unsupported plugins.  See PluginProcessChild::Init for
     // the details.
     if (XRE_GetProcessType() != GeckoProcessType_Plugin) {
         mozilla::SanitizeEnvironmentVariables();
         SetDllDirectory(L"");
     }
 #endif
-    nsAutoPtr<mozilla::gmp::GMPLoader> loader;
 #if !defined(MOZ_WIDGET_ANDROID) && !defined(MOZ_WIDGET_GONK)
     // On desktop, the GMPLoader lives in plugin-container, so that its
     // code can be covered by an EME/GMP vendor's voucher.
     nsAutoPtr<mozilla::gmp::SandboxStarter> starter(MakeSandboxStarter());
     if (XRE_GetProcessType() == GeckoProcessType_GMPlugin) {
-        loader = mozilla::gmp::CreateGMPLoader(starter);
+        childData.gmpLoader = mozilla::gmp::CreateGMPLoader(starter);
     }
 #endif
-    nsresult rv = XRE_InitChildProcess(argc, argv, loader);
+    nsresult rv = XRE_InitChildProcess(argc, argv, &childData);
     NS_ENSURE_SUCCESS(rv, 1);
 
     return 0;
 }
--- a/mozglue/android/APKOpen.cpp
+++ b/mozglue/android/APKOpen.cpp
@@ -30,16 +30,17 @@
 #include "sqlite3.h"
 #include "SQLiteBridge.h"
 #include "NSSBridge.h"
 #include "ElfLoader.h"
 #include "application.ini.h"
 
 #include "mozilla/TimeStamp.h"
 #include "mozilla/UniquePtr.h"
+#include "XREChildData.h"
 
 /* Android headers don't define RUSAGE_THREAD */
 #ifndef RUSAGE_THREAD
 #define RUSAGE_THREAD 1
 #endif
 
 #ifndef RELEASE_BUILD
 /* Official builds have the debuggable flag set to false, which disables
@@ -416,11 +417,12 @@ ChildProcessInit(int argc, char* argv[])
   void (*fXRE_SetProcessType)(char*);
   xul_dlsym("XRE_SetProcessType", &fXRE_SetProcessType);
 
   mozglueresult (*fXRE_InitChildProcess)(int, char**, void*);
   xul_dlsym("XRE_InitChildProcess", &fXRE_InitChildProcess);
 
   fXRE_SetProcessType(argv[--argc]);
 
-  return fXRE_InitChildProcess(argc, argv, nullptr);
+  XREChildData childData;
+  return fXRE_InitChildProcess(argc, argv, &childData);
 }
 
--- a/security/sandbox/chromium-shim/sandbox/win/loggingCallbacks.h
+++ b/security/sandbox/chromium-shim/sandbox/win/loggingCallbacks.h
@@ -2,63 +2,30 @@
 /* vim: set ts=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 http://mozilla.org/MPL/2.0/. */
 
 #ifndef security_sandbox_loggingCallbacks_h__
 #define security_sandbox_loggingCallbacks_h__
 
-#include "mozilla/sandboxing/loggingTypes.h"
-#include "mozilla/sandboxing/sandboxLogging.h"
-
-#ifdef TARGET_SANDBOX_EXPORTS
 #include <sstream>
 #include <iostream>
 
 #include "mozilla/Preferences.h"
+#include "mozilla/sandboxing/loggingTypes.h"
 #include "nsContentUtils.h"
 
 #ifdef MOZ_STACKWALKING
 #include "mozilla/StackWalk.h"
 #endif
 
-#define TARGET_SANDBOX_EXPORT __declspec(dllexport)
-#else
-#define TARGET_SANDBOX_EXPORT __declspec(dllimport)
-#endif
-
 namespace mozilla {
 namespace sandboxing {
 
-// We need to use a callback to work around the fact that sandbox_s lib is
-// linked into plugin-container.exe directly and also via xul.dll via
-// sandboxbroker.dll. This causes problems with holding the state required to
-// implement sandbox logging.
-// So, we provide a callback from plugin-container.exe that the code in xul.dll
-// can call to make sure we hit the right version of the code.
-void TARGET_SANDBOX_EXPORT
-SetProvideLogFunctionCb(ProvideLogFunctionCb aProvideLogFunctionCb);
-
-// Provide a call back so a pointer to a logging function can be passed later.
-static void
-PrepareForLogging()
-{
-  SetProvideLogFunctionCb(ProvideLogFunction);
-}
-
-#ifdef TARGET_SANDBOX_EXPORTS
-static ProvideLogFunctionCb sProvideLogFunctionCb = nullptr;
-
-void
-SetProvideLogFunctionCb(ProvideLogFunctionCb aProvideLogFunctionCb)
-{
-  sProvideLogFunctionCb = aProvideLogFunctionCb;
-}
-
 #ifdef MOZ_STACKWALKING
 static uint32_t sStackTraceDepth = 0;
 
 // NS_WalkStackCallback to write a formatted stack frame to an ostringstream.
 static void
 StackFrameToOStringStream(uint32_t aFrameNumber, void* aPC, void* aSP,
                           void* aClosure)
 {
@@ -105,33 +72,33 @@ Log(const char* aMessageType,
 
   if (nsContentUtils::IsInitialized()) {
     nsContentUtils::LogMessageToConsole(msg.c_str());
   }
 }
 
 // Initialize sandbox logging if required.
 static void
-InitLoggingIfRequired()
+InitLoggingIfRequired(ProvideLogFunctionCb aProvideLogFunctionCb)
 {
-  if (!sProvideLogFunctionCb) {
+  if (!aProvideLogFunctionCb) {
     return;
   }
 
   if (Preferences::GetBool("security.sandbox.windows.log") ||
       PR_GetEnv("MOZ_WIN_SANDBOX_LOGGING")) {
-    sProvideLogFunctionCb(Log);
+    aProvideLogFunctionCb(Log);
 
 #if defined(MOZ_CONTENT_SANDBOX) && defined(MOZ_STACKWALKING)
     // We can only log the stack trace on process types where we know that the
     // sandbox won't prevent it.
     if (XRE_IsContentProcess()) {
       Preferences::AddUintVarCache(&sStackTraceDepth,
         "security.sandbox.windows.log.stackTraceDepth");
     }
 #endif
   }
 }
-#endif
+
 } // sandboxing
 } // mozilla
 
-#endif // security_sandbox_loggingCallbacks_h__
+#endif // security_sandbox_loggingCallbacks_h__
\ No newline at end of file
--- a/security/sandbox/chromium-shim/sandbox/win/sandboxLogging.h
+++ b/security/sandbox/chromium-shim/sandbox/win/sandboxLogging.h
@@ -8,32 +8,26 @@
  * Set of helper methods to implement logging for Windows sandbox.
  */
 
 #ifndef security_sandbox_sandboxLogging_h__
 #define security_sandbox_sandboxLogging_h__
 
 #include "loggingTypes.h"
 
-#ifdef SANDBOX_EXPORTS
-#define SANDBOX_EXPORT __declspec(dllexport)
-#else
-#define SANDBOX_EXPORT __declspec(dllimport)
-#endif
-
 namespace sandbox {
 class TargetPolicy;
 }
 
 namespace mozilla {
 namespace sandboxing {
 
 // This is used to pass a LogCallback to the sandboxing code, as the logging
 // requires code to which we cannot link directly.
-void SANDBOX_EXPORT ProvideLogFunction(LogFunction aLogFunction);
+void ProvideLogFunction(LogFunction aLogFunction);
 
 // Set up dummy interceptions via the broker, so we can log calls.
 void ApplyLoggingPolicy(sandbox::TargetPolicy& aPolicy);
 
 // Log a "BLOCKED" msg to the browser console and, if DEBUG build, stderr.
 // If the logging of a stack trace is enabled then the default aFramesToSkip
 // will start from our caller's caller, which should normally be the function
 // that triggered the interception.
--- a/security/sandbox/moz.build
+++ b/security/sandbox/moz.build
@@ -23,16 +23,17 @@ elif CONFIG['OS_ARCH'] == 'WINNT':
     if (CONFIG['CPU_ARCH'] == 'x86' and CONFIG['_MSC_VER'] and not
             CONFIG['CLANG_CL']):
         DIRS += ['win/wow_helper']
 
     EXPORTS.mozilla.sandboxing += [
         'chromium-shim/sandbox/win/loggingCallbacks.h',
         'chromium-shim/sandbox/win/loggingTypes.h',
         'chromium-shim/sandbox/win/sandboxLogging.h',
+        'win/SandboxInitialization.h',
     ]
 
     SOURCES += [
         'chromium-shim/base/logging.cpp',
         'chromium-shim/sandbox/win/sandboxLogging.cpp',
         'chromium/base/at_exit.cc',
         'chromium/base/base_switches.cc',
         'chromium/base/callback_internal.cc',
@@ -123,16 +124,17 @@ elif CONFIG['OS_ARCH'] == 'WINNT':
         'chromium/sandbox/win/src/sync_interception.cc',
         'chromium/sandbox/win/src/sync_policy.cc',
         'chromium/sandbox/win/src/target_interceptions.cc',
         'chromium/sandbox/win/src/target_process.cc',
         'chromium/sandbox/win/src/target_services.cc',
         'chromium/sandbox/win/src/win2k_threadpool.cc',
         'chromium/sandbox/win/src/win_utils.cc',
         'chromium/sandbox/win/src/window.cc',
+        'win/SandboxInitialization.cpp',
     ]
 
     if CONFIG['CPU_ARCH'] == 'x86_64':
         SOURCES += [
             'chromium/sandbox/win/src/interceptors_64.cc',
             'chromium/sandbox/win/src/resolver_64.cc',
             'chromium/sandbox/win/src/service_resolver_64.cc',
             'chromium/sandbox/win/src/Wow64_64.cc',
new file mode 100644
--- /dev/null
+++ b/security/sandbox/win/SandboxInitialization.cpp
@@ -0,0 +1,46 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=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 http://mozilla.org/MPL/2.0/. */
+
+#include "SandboxInitialization.h"
+
+#include "sandbox/win/src/sandbox_factory.h"
+
+namespace mozilla {
+namespace sandboxing {
+
+static sandbox::TargetServices*
+InitializeTargetServices()
+{
+  sandbox::TargetServices* targetServices =
+    sandbox::SandboxFactory::GetTargetServices();
+  if (!targetServices) {
+    return nullptr;
+  }
+
+  if (targetServices->Init() != sandbox::SBOX_ALL_OK) {
+    return nullptr;
+  }
+
+  return targetServices;
+}
+
+sandbox::TargetServices*
+GetInitializedTargetServices()
+{
+  static sandbox::TargetServices* sInitializedTargetServices =
+    InitializeTargetServices();
+
+  return sInitializedTargetServices;
+}
+
+void
+LowerSandbox()
+{
+  GetInitializedTargetServices()->LowerToken();
+}
+
+} // sandboxing
+} // mozilla
new file mode 100644
--- /dev/null
+++ b/security/sandbox/win/SandboxInitialization.h
@@ -0,0 +1,35 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=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 http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_sandboxing_SandboxInitialization_h
+#define mozilla_sandboxing_SandboxInitialization_h
+
+namespace sandbox {
+class TargetServices;
+}
+
+namespace mozilla {
+// Note the Chromium code just uses a bare sandbox namespace, which makes using
+// sandbox for our namespace painful.
+namespace sandboxing {
+
+/**
+ * Initializes (if required) and returns the Chromium sandbox TargetServices.
+ *
+ * @return the TargetServices or null if the creation or initialization failed.
+ */
+sandbox::TargetServices* GetInitializedTargetServices();
+
+/**
+ * Lowers the permissions on the process sandbox.
+ * Provided because the GMP sandbox needs to be lowered from the executable.
+ */
+void LowerSandbox();
+
+} // sandboxing
+} // mozilla
+
+#endif // mozilla_sandboxing_SandboxInitialization_h
--- a/security/sandbox/win/src/sandboxtarget/sandboxTarget.h
+++ b/security/sandbox/win/src/sandboxtarget/sandboxTarget.h
@@ -7,27 +7,20 @@
 #ifndef __SECURITY_SANDBOX_SANDBOXTARGET_H__
 #define __SECURITY_SANDBOX_SANDBOXTARGET_H__
 
 #include <windows.h>
 
 #include "mozilla/Assertions.h"
 #include "base/MissingBasicTypes.h"
 #include "sandbox/win/src/sandbox.h"
-#include "sandbox/win/src/target_services.h"
 
-#ifdef TARGET_SANDBOX_EXPORTS
-#define TARGET_SANDBOX_EXPORT __declspec(dllexport)
-#else
-#define TARGET_SANDBOX_EXPORT __declspec(dllimport)
-#endif
 namespace mozilla {
 
-
-class TARGET_SANDBOX_EXPORT SandboxTarget
+class SandboxTarget
 {
 public:
   /**
    * Obtains a pointer to the singleton instance
    */
   static SandboxTarget* Instance();
 
   /**
--- a/toolkit/xre/moz.build
+++ b/toolkit/xre/moz.build
@@ -154,16 +154,22 @@ LOCAL_INCLUDES += [
     '/config',
     '/dom/base',
     '/dom/ipc',
     '/testing/gtest/mozilla',
     '/toolkit/crashreporter',
     '/xpcom/build',
 ]
 
+if CONFIG['MOZ_SANDBOX'] and CONFIG['OS_ARCH'] == 'WINNT':
+    LOCAL_INCLUDES += [
+        '/security/sandbox/chromium',
+        '/security/sandbox/chromium-shim',
+    ]
+
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
     LOCAL_INCLUDES += [
         '/widget',
         '/widget/cocoa',
     ]
 
 if CONFIG['MOZ_ENABLE_XREMOTE']:
     LOCAL_INCLUDES += [
--- a/toolkit/xre/nsEmbedFunctions.cpp
+++ b/toolkit/xre/nsEmbedFunctions.cpp
@@ -74,17 +74,17 @@
 #include "GMPProcessChild.h"
 #include "GMPLoader.h"
 
 #include "GeckoProfiler.h"
 
  #include "base/histogram.h"
 
 #if defined(MOZ_SANDBOX) && defined(XP_WIN)
-#define TARGET_SANDBOX_EXPORTS
+#include "mozilla/sandboxTarget.h"
 #include "mozilla/sandboxing/loggingCallbacks.h"
 #endif
 
 #ifdef MOZ_IPDL_TESTS
 #include "mozilla/_ipdltest/IPDLUnitTests.h"
 #include "mozilla/_ipdltest/IPDLUnitTestProcessChild.h"
 
 using mozilla::_ipdltest::IPDLUnitTestProcessChild;
@@ -292,40 +292,41 @@ SetTaskbarGroupId(const nsString& aId)
     if (hDLL)
         ::FreeLibrary(hDLL);
 }
 #endif
 
 nsresult
 XRE_InitChildProcess(int aArgc,
                      char* aArgv[],
-                     GMPLoader* aGMPLoader)
+                     const XREChildData* aChildData)
 {
   NS_ENSURE_ARG_MIN(aArgc, 2);
   NS_ENSURE_ARG_POINTER(aArgv);
   NS_ENSURE_ARG_POINTER(aArgv[0]);
+  MOZ_ASSERT(aChildData);
 
 #ifdef HAS_DLL_BLOCKLIST
   DllBlocklist_Initialize();
 #endif
 
   // This is needed by Telemetry to initialize histogram collection.
   UniquePtr<base::StatisticsRecorder> statisticsRecorder =
     MakeUnique<base::StatisticsRecorder>();
 
 #if !defined(MOZ_WIDGET_ANDROID) && !defined(MOZ_WIDGET_GONK)
   // On non-Fennec Gecko, the GMPLoader code resides in plugin-container,
   // and we must forward it through to the GMP code here.
-  GMPProcessChild::SetGMPLoader(aGMPLoader);
+  GMPProcessChild::SetGMPLoader(aChildData->gmpLoader.get());
 #else
   // On Fennec, the GMPLoader's code resides inside XUL (because for the time
   // being GMPLoader relies upon NSPR, which we can't use in plugin-container
   // on Android), so we create it here inside XUL and pass it to the GMP code.
-  nsAutoPtr<GMPLoader> loader(CreateGMPLoader(nullptr));
-  GMPProcessChild::SetGMPLoader(loader);
+  UniquePtr<GMPLoader> loader = CreateGMPLoader(nullptr);
+  GMPProcessChild::SetGMPLoader(loader.get());
 #endif
 
 #if defined(XP_WIN)
   // From the --attach-console support in nsNativeAppSupportWin.cpp, but
   // here we are a content child process, so we always attempt to attach
   // to the parent's (ie, the browser's) console.
   // Try to attach console to the parent process.
   // It will succeed when the parent process is a command line,
@@ -340,16 +341,22 @@ XRE_InitChildProcess(int aArgc,
     // Merge stderr into CONOUT$ since there isn't any `CONERR$`.
     // http://msdn.microsoft.com/en-us/library/windows/desktop/ms683231%28v=vs.85%29.aspx
     if (_fileno(stderr) == -1 ||
         _get_osfhandle(fileno(stderr)) == -1)
         freopen("CONOUT$", "w", stderr);
     if (_fileno(stdin) == -1 || _get_osfhandle(fileno(stdin)) == -1)
         freopen("CONIN$", "r", stdin);
   }
+
+#if defined(MOZ_SANDBOX)
+  if (aChildData->sandboxTargetServices) {
+    SandboxTarget::Instance()->SetTargetServices(aChildData->sandboxTargetServices);
+  }
+#endif
 #endif
 
   // NB: This must be called before profiler_init
   NS_LogInit();
 
   mozilla::LogModule::Init();
 
   char aLocal;
@@ -623,17 +630,17 @@ XRE_InitChildProcess(int aArgc,
       // chrome process is killed in cases where the user shuts the system
       // down or logs off.
       ::SetProcessShutdownParameters(0x280 - 1, SHUTDOWN_NORETRY);
 #endif
 
 #if defined(MOZ_SANDBOX) && defined(XP_WIN)
       // We need to do this after the process has been initialised, as
       // InitLoggingIfRequired may need access to prefs.
-      mozilla::sandboxing::InitLoggingIfRequired();
+      mozilla::sandboxing::InitLoggingIfRequired(aChildData->ProvideLogFunction);
 #endif
 
       OverrideDefaultLocaleIfNeeded();
 
       // Run the UI event loop on the main thread.
       uiMessageLoop.MessageLoop::Run();
 
       // Allow ProcessChild to clean up after itself before going out of
new file mode 100644
--- /dev/null
+++ b/xpcom/build/XREChildData.h
@@ -0,0 +1,51 @@
+/* -*- 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 http://mozilla.org/MPL/2.0/. */
+
+#ifndef XREChildData_h
+#define XREChildData_h
+
+#include "mozilla/UniquePtr.h"
+
+#if defined(XP_WIN) && defined(MOZ_SANDBOX)
+#include "mozilla/sandboxing/loggingTypes.h"
+
+namespace sandbox {
+class TargetServices;
+}
+#endif
+
+namespace mozilla {
+namespace gmp {
+class GMPLoader;
+}
+}
+
+/**
+ * Data needed to start a child process.
+ */
+struct XREChildData
+{
+#if !defined(MOZ_WIDGET_ANDROID) && !defined(MOZ_WIDGET_GONK)
+  /**
+   * Used to load the GMP binary.
+   */
+  mozilla::UniquePtr<mozilla::gmp::GMPLoader> gmpLoader;
+#endif
+
+#if defined(XP_WIN) && defined(MOZ_SANDBOX)
+  /**
+   * Chromium sandbox TargetServices.
+   */
+  sandbox::TargetServices* sandboxTargetServices = nullptr;
+
+  /**
+   * Function to provide a logging function to the chromium sandbox code.
+   */
+  mozilla::sandboxing::ProvideLogFunctionCb ProvideLogFunction = nullptr;
+#endif
+};
+
+#endif // XREChildData_h
--- a/xpcom/build/moz.build
+++ b/xpcom/build/moz.build
@@ -5,16 +5,17 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 EXPORTS += [
     'nsXPCOM.h',
     'nsXPCOMCID.h',
     'nsXPCOMCIDInternal.h',
     'nsXREAppData.h',
     'nsXULAppAPI.h',
+    'XREChildData.h',
     'xrecore.h',
 ]
 
 EXPORTS.mozilla += [
     'FileLocation.h',
     'IOInterposer.h',
     'LateWriteChecks.h',
     'Omnijar.h',
--- a/xpcom/build/nsXULAppAPI.h
+++ b/xpcom/build/nsXULAppAPI.h
@@ -14,16 +14,17 @@
 #include "mozilla/Logging.h"
 #include "nsXREAppData.h"
 #include "js/TypeDecls.h"
 
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/Vector.h"
 #include "mozilla/TimeStamp.h"
+#include "XREChildData.h"
 
 /**
  * A directory service key which provides the platform-correct "application
  * data" directory as follows, where $name and $vendor are as defined above and
  * $vendor is optional:
  *
  * Windows:
  *   HOME = Documents and Settings\$USER\Application Data
@@ -406,17 +407,17 @@ namespace mozilla {
 namespace gmp {
 class GMPLoader;
 } // namespace gmp
 } // namespace mozilla
 
 XRE_API(nsresult,
         XRE_InitChildProcess, (int aArgc,
                                char* aArgv[],
-                               mozilla::gmp::GMPLoader* aGMPLoader))
+                               const XREChildData* aChildData))
 
 XRE_API(GeckoProcessType,
         XRE_GetProcessType, ())
 
 XRE_API(bool,
         XRE_IsParentProcess, ())
 
 XRE_API(bool,