Bug 1035125 Part 8: Pass sandboxing pointers through XRE_InitChildProcess instead of linking to more functions in xul. r=aklotz,glandium
authorBob Owen <bobowencode@gmail.com>
Sun, 15 May 2016 16:35:22 +0100
changeset 336617 da96cd1bf70c748bc59219677262530639a5e32b
parent 336616 477b991bf6fa7b4511768649c9bf37c7275d30d9
child 336618 a416c55e664816080084ad68453a5c212f1d00a0
push id6249
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 13:59:36 +0000
treeherdermozilla-beta@bad9d4f5bf7e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersaklotz, glandium
bugs1035125
milestone49.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 1035125 Part 8: Pass sandboxing pointers through XRE_InitChildProcess instead of linking to more functions in xul. r=aklotz,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,