bug 985252. Build sandbox code regardless of whether --enable-content-sandbox/MOZ_CONTENT_SANDBOX is provided. Enable sandboxing of GMP plugins. Enable `SandboxBroker` to set different security policies for different process types. r=bbondy, r=cpearce, r=bent
authorTim Abraldes <tabraldes@mozilla.com>
Wed, 16 Jul 2014 16:01:34 -0700
changeset 215319 fbd06fa70b84eae689346767aed8e7ff43afb241
parent 215318 df330e73a20d72b49867a2b209b3dbd3ecc7b8d0
child 215320 b0f163fff21229dcce60562774324604ffcc054a
push id3857
push userraliiev@mozilla.com
push dateTue, 02 Sep 2014 16:39:23 +0000
treeherdermozilla-beta@5638b907b505 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbbondy, cpearce, bent
bugs985252
milestone33.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 985252. Build sandbox code regardless of whether --enable-content-sandbox/MOZ_CONTENT_SANDBOX is provided. Enable sandboxing of GMP plugins. Enable `SandboxBroker` to set different security policies for different process types. r=bbondy, r=cpearce, r=bent
browser/installer/package-manifest.in
browser/installer/windows/nsis/defines.nsi.in
browser/installer/windows/nsis/shared.nsh
content/media/gmp/GMPChild.cpp
content/media/gmp/GMPProcessParent.cpp
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
ipc/app/Makefile.in
ipc/app/MozillaRuntimeMain.cpp
ipc/app/moz.build
ipc/glue/GeckoChildProcessHost.cpp
ipc/glue/GeckoChildProcessHost.h
ipc/glue/moz.build
security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp
security/sandbox/win/src/sandboxbroker/sandboxBroker.h
toolkit/library/Makefile.in
toolkit/toolkit.mozbuild
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -741,18 +741,18 @@
 @BINPATH@/@DLL_PREFIX@softokn3@DLL_SUFFIX@
 #endif
 @BINPATH@/chrome/pippki@JAREXT@
 @BINPATH@/chrome/pippki.manifest
 @BINPATH@/components/pipboot.xpt
 @BINPATH@/components/pipnss.xpt
 @BINPATH@/components/pippki.xpt
 
-; For content sandboxing
-#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
+; For process sandboxing
+#if defined(XP_WIN)
 @BINPATH@/@DLL_PREFIX@sandboxbroker@DLL_SUFFIX@
 #endif
 
 ; for Solaris SPARC
 #ifdef SOLARIS
 bin/libfreebl_32fpu_3.so
 bin/libfreebl_32int_3.so
 bin/libfreebl_32int64_3.so
--- a/browser/installer/windows/nsis/defines.nsi.in
+++ b/browser/installer/windows/nsis/defines.nsi.in
@@ -73,20 +73,16 @@
 #ifdef MOZ_MAINTENANCE_SERVICE
 !define MOZ_MAINTENANCE_SERVICE
 #endif
 
 #ifdef MOZ_METRO
 !define MOZ_METRO
 #endif
 
-#ifdef MOZ_CONTENT_SANDBOX
-!define MOZ_CONTENT_SANDBOX
-#endif
-
 # File details shared by both the installer and uninstaller
 VIProductVersion "1.0.0.0"
 VIAddVersionKey "ProductName"     "${BrandShortName}"
 VIAddVersionKey "CompanyName"     "${CompanyName}"
 #ifdef MOZ_OFFICIAL_BRANDING
 VIAddVersionKey "LegalTrademarks" "${BrandShortName} is a Trademark of The Mozilla Foundation."
 #endif
 VIAddVersionKey "LegalCopyright"  "${CompanyName}"
--- a/browser/installer/windows/nsis/shared.nsh
+++ b/browser/installer/windows/nsis/shared.nsh
@@ -1494,19 +1494,17 @@ FunctionEnd
   ; returns after the first check.
   Push "end"
   Push "AccessibleMarshal.dll"
   Push "freebl3.dll"
   Push "nssckbi.dll"
   Push "nspr4.dll"
   Push "nssdbm3.dll"
   Push "mozsqlite3.dll"
-!ifdef MOZ_CONTENT_SANDBOX
   Push "sandboxbroker.dll"
-!endif
   Push "xpcom.dll"
   Push "crashreporter.exe"
   Push "updater.exe"
   Push "${FileMainEXE}"
 !macroend
 !define PushFilesToCheck "!insertmacro PushFilesToCheck"
 
 ; Sets this installation as the default browser by setting the registry keys
--- a/content/media/gmp/GMPChild.cpp
+++ b/content/media/gmp/GMPChild.cpp
@@ -14,16 +14,21 @@
 #include "GMPPlatform.h"
 
 #ifdef XP_WIN
 #include <stdlib.h> // for _exit()
 #else
 #include <unistd.h> // for _exit()
 #endif
 
+#if defined(XP_WIN)
+#define TARGET_SANDBOX_EXPORTS
+#include "mozilla/sandboxTarget.h"
+#endif
+
 namespace mozilla {
 namespace gmp {
 
 GMPChild::GMPChild()
   : mLib(nullptr)
   , mGetAPIFunc(nullptr)
   , mGMPMessageLoop(MessageLoop::current())
 {
@@ -34,16 +39,19 @@ GMPChild::~GMPChild()
 }
 
 bool
 GMPChild::Init(const std::string& aPluginPath,
                base::ProcessHandle aParentProcessHandle,
                MessageLoop* aIOLoop,
                IPC::Channel* aChannel)
 {
+#if defined(XP_WIN)
+  mozilla::SandboxTarget::Instance()->StartSandbox();
+#endif
   return LoadPluginLibrary(aPluginPath) &&
          Open(aChannel, aParentProcessHandle, aIOLoop);
 }
 
 bool
 GMPChild::LoadPluginLibrary(const std::string& aPluginPath)
 {
   nsDependentCString pluginPath(aPluginPath.c_str());
--- a/content/media/gmp/GMPProcessParent.cpp
+++ b/content/media/gmp/GMPProcessParent.cpp
@@ -46,16 +46,17 @@ GMPProcessParent::Launch(int32_t aTimeou
 
 void
 GMPProcessParent::Delete()
 {
   MessageLoop* currentLoop = MessageLoop::current();
   MessageLoop* ioLoop = XRE_GetIOMessageLoop();
 
   if (currentLoop == ioLoop) {
+    Join();
     delete this;
     return;
   }
 
   ioLoop->PostTask(FROM_HERE, NewRunnableMethod(this, &GMPProcessParent::Delete));
 }
 
 } // namespace gmp
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -1756,17 +1756,16 @@ ContentParent::ContentParent(mozIApplica
     // PID along with the warning.
     nsDebugImpl::SetMultiprocessMode("Parent");
 
     NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
     ChildPrivileges privs = aIsNuwaProcess
         ? base::PRIVILEGES_INHERIT
         : base::PRIVILEGES_DEFAULT;
     mSubprocess = new GeckoChildProcessHost(GeckoProcessType_Content, privs);
-    mSubprocess->SetSandboxEnabled(ShouldSandboxContentProcesses());
 
     IToplevelProtocol::SetTransport(mSubprocess->GetChannel());
 
     if (!aIsNuwaProcess) {
         // Tell the memory reporter manager that this ContentParent exists.
         nsRefPtr<nsMemoryReporterManager> mgr =
             nsMemoryReporterManager::GetOrCreate();
         if (mgr) {
@@ -3626,26 +3625,16 @@ ContentParent::ShouldContinueFromReplyTi
 {
     // The only time ContentParent sends blocking messages is for CPOWs, so
     // timeouts should only ever occur in electrolysis-enabled sessions.
     MOZ_ASSERT(BrowserTabsRemote());
     return false;
 }
 
 bool
-ContentParent::ShouldSandboxContentProcesses()
-{
-#ifdef MOZ_CONTENT_SANDBOX
-    return !PR_GetEnv("MOZ_DISABLE_CONTENT_SANDBOX");
-#else
-    return true;
-#endif
-}
-
-bool
 ContentParent::RecvRecordingDeviceEvents(const nsString& aRecordingStatus,
                                          const nsString& aPageURL,
                                          const bool& aIsAudio,
                                          const bool& aIsVideo)
 {
     nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
     if (obs) {
         // recording-device-ipc-events needs to gather more information from content process
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -269,17 +269,16 @@ public:
         const BlobConstructorParams& aParams) MOZ_OVERRIDE;
 
 protected:
     void OnChannelConnected(int32_t pid) MOZ_OVERRIDE;
     virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
     void OnNuwaForkTimeout();
 
     bool ShouldContinueFromReplyTimeout() MOZ_OVERRIDE;
-    bool ShouldSandboxContentProcesses();
 
 private:
     static nsDataHashtable<nsStringHashKey, ContentParent*> *sAppContentParents;
     static nsTArray<ContentParent*>* sNonAppContentParents;
     static nsTArray<ContentParent*>* sPrivateContent;
     static StaticAutoPtr<LinkedList<ContentParent> > sContentParents;
 
     static void JoinProcessesIOThread(const nsTArray<ContentParent*>* aProcesses,
--- a/ipc/app/Makefile.in
+++ b/ipc/app/Makefile.in
@@ -35,20 +35,18 @@ endif
 NSDISTMODE = copy
 
 include $(topsrcdir)/config/config.mk
 
 include $(topsrcdir)/config/rules.mk
 
 ifeq ($(OS_ARCH),WINNT) #{
 
-ifdef MOZ_CONTENT_SANDBOX
 LIBS += ../../security/sandbox/$(LIB_PREFIX)sandbox_s.$(LIB_SUFFIX)
 LIBS += $(NSPR_LIBS)
-endif
 
 # Note the manifest file exists in the tree, so we use the explicit filename
 # here.
 EXTRA_DEPS += plugin-container.exe.manifest
 endif #}
 
 ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT)) #{
 
--- a/ipc/app/MozillaRuntimeMain.cpp
+++ b/ipc/app/MozillaRuntimeMain.cpp
@@ -16,17 +16,17 @@
 #include <windows.h>
 // we want a wmain entry point
 // but we don't want its DLL load protection, because we'll handle it here
 #define XRE_DONT_PROTECT_DLL_LOAD
 #include "nsWindowsWMain.cpp"
 #include "nsSetDllDirectory.h"
 #endif
 
-#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
+#if defined(XP_WIN)
 #include "sandbox/chromium/base/basictypes.h"
 #include "sandbox/win/src/sandbox.h"
 #include "sandbox/win/src/sandbox_factory.h"
 #include "mozilla/sandboxTarget.h"
 #endif
 
 #ifdef MOZ_WIDGET_GONK
 # include <sys/time.h>
@@ -63,17 +63,17 @@ InitializeBinder(void *aDummy) {
     int err = setpriority(PRIO_PROCESS, 0, 0);
     MOZ_ASSERT(!err);
     LOGE_IF(err, "setpriority failed. Current process needs root permission.");
     android::ProcessState::self()->startThreadPool();
     setpriority(PRIO_PROCESS, 0, curPrio);
 }
 #endif
 
-#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
+#if defined(XP_WIN)
 static bool gIsSandboxEnabled = false;
 void StartSandboxCallback()
 {
     if (gIsSandboxEnabled) {
         sandbox::TargetServices* target_service =
             sandbox::SandboxFactory::GetTargetServices();
         target_service->LowerToken();
     }
@@ -81,17 +81,17 @@ void StartSandboxCallback()
 #endif
 
 int
 main(int argc, char* argv[])
 {
     bool isNuwa = false;
     for (int i = 1; i < argc; i++) {
         isNuwa |= strcmp(argv[i], "-nuwa") == 0;
-#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
+#if defined(XP_WIN)
         gIsSandboxEnabled |= strcmp(argv[i], "-sandbox") == 0;
 #endif
     }
 
 #ifdef MOZ_NUWA_PROCESS
     if (isNuwa) {
         PrepareNuwaProcess();
     }
@@ -124,30 +124,28 @@ main(int argc, char* argv[])
     // For plugins, this is done in PluginProcessChild::Init, as we need to
     // avoid it for unsupported plugins.  See PluginProcessChild::Init for
     // the details.
     if (proctype != GeckoProcessType_Plugin) {
         mozilla::SanitizeEnvironmentVariables();
         SetDllDirectory(L"");
     }
 
-#ifdef MOZ_CONTENT_SANDBOX
     if (gIsSandboxEnabled) {
         sandbox::TargetServices* target_service =
             sandbox::SandboxFactory::GetTargetServices();
         if (!target_service) {
             return 1;
         }
 
         sandbox::ResultCode result = target_service->Init();
         if (result != sandbox::SBOX_ALL_OK) {
            return 2;
         }
         mozilla::SandboxTarget::Instance()->SetStartSandboxCallback(StartSandboxCallback);
     }
 #endif
-#endif
 
     nsresult rv = XRE_InitChildProcess(argc, argv, proctype);
     NS_ENSURE_SUCCESS(rv, 1);
 
     return 0;
 }
--- a/ipc/app/moz.build
+++ b/ipc/app/moz.build
@@ -17,17 +17,17 @@ else:
     ]
 include('/ipc/chromium/chromium-config.mozbuild')
 
 LOCAL_INCLUDES += [
     '/toolkit/xre',
     '/xpcom/base',
 ]
 
-if CONFIG['MOZ_CONTENT_SANDBOX'] and CONFIG['OS_ARCH'] == 'WINNT':
+if CONFIG['OS_ARCH'] == 'WINNT':
     # For sandbox includes and the include dependencies those have
     LOCAL_INCLUDES += [
         '/security',
         '/security/sandbox',
         '/security/sandbox/chromium',
     ]
 
 if CONFIG['_MSC_VER']:
--- a/ipc/glue/GeckoChildProcessHost.cpp
+++ b/ipc/glue/GeckoChildProcessHost.cpp
@@ -1,20 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  */
 /* 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 "GeckoChildProcessHost.h"
 
-#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
-#include "sandboxBroker.h"
-#endif
-
 #include "base/command_line.h"
 #include "base/path_service.h"
 #include "base/string_util.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/process_watcher.h"
 #ifdef MOZ_WIDGET_COCOA
 #include "chrome/common/mach_ipc_mac.h"
 #include "base/rand_util.h"
@@ -86,17 +82,16 @@ GeckoChildProcessHost::DefaultChildPrivi
   return (kLowRightsSubprocesses ?
           base::PRIVILEGES_UNPRIVILEGED : base::PRIVILEGES_INHERIT);
 }
 
 GeckoChildProcessHost::GeckoChildProcessHost(GeckoProcessType aProcessType,
                                              ChildPrivileges aPrivileges)
   : ChildProcessHost(RENDER_PROCESS), // FIXME/cjones: we should own this enum
     mProcessType(aProcessType),
-    mSandboxEnabled(true),
     mPrivileges(aPrivileges),
     mMonitor("mozilla.ipc.GeckChildProcessHost.mMonitor"),
     mProcessState(CREATING_CHANNEL),
     mDelegate(nullptr),
     mChildProcessHandle(0)
 #if defined(MOZ_WIDGET_COCOA)
   , mChildTask(MACH_PORT_NULL)
 #endif
@@ -794,21 +789,52 @@ GeckoChildProcessHost::PerformAsyncLaunc
     }
     file = Omnijar::GetPath(Omnijar::APP);
     if (file && NS_SUCCEEDED(file->GetPath(path))) {
       cmdLine.AppendLooseValue(UTF8ToWide("-appomni"));
       cmdLine.AppendLooseValue(path.get());
     }
   }
 
-#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
-  if (mSandboxEnabled) {
-    // Tell the process that it should lower its rights after initialization.
-    cmdLine.AppendLooseValue(UTF8ToWide("-sandbox"));
-  }
+#if defined(XP_WIN)
+  bool shouldSandboxCurrentProcess = false;
+  switch (mProcessType) {
+    case GeckoProcessType_Content:
+#if defined(MOZ_CONTENT_SANDBOX)
+      if (!PR_GetEnv("MOZ_DISABLE_CONTENT_SANDBOX")) {
+        mSandboxBroker.SetSecurityLevelForContentProcess();
+        cmdLine.AppendLooseValue(UTF8ToWide("-sandbox"));
+        shouldSandboxCurrentProcess = true;
+      }
+#endif // MOZ_CONTENT_SANDBOX
+      break;
+    case GeckoProcessType_Plugin:
+      // XXX: We don't sandbox this process type yet
+      // mSandboxBroker.SetSecurityLevelForPluginProcess();
+      // cmdLine.AppendLooseValue(UTF8ToWide("-sandbox"));
+      // shouldSandboxCurrentProcess = true;
+      break;
+    case GeckoProcessType_IPDLUnitTest:
+      // XXX: We don't sandbox this process type yet
+      // mSandboxBroker.SetSecurityLevelForIPDLUnitTestProcess();
+      // cmdLine.AppendLooseValue(UTF8ToWide("-sandbox"));
+      // shouldSandboxCurrentProcess = true;
+      break;
+    case GeckoProcessType_GMPlugin:
+      if (!PR_GetEnv("MOZ_DISABLE_GMP_SANDBOX")) {
+        mSandboxBroker.SetSecurityLevelForGMPlugin();
+        cmdLine.AppendLooseValue(UTF8ToWide("-sandbox"));
+        shouldSandboxCurrentProcess = true;
+      }
+      break;
+    case GeckoProcessType_Default:
+    default:
+      MOZ_CRASH("Bad process type in GeckoChildProcessHost");
+      break;
+  };
 #endif
 
   // Add the application directory path (-appdir path)
   AddAppDirToCommandLine(cmdLine);
 
   // XXX Command line params past this point are expected to be at
   // the end of the command line string, and in a specific order.
   // See XRE_InitChildProcess in nsEmbedFunction.
@@ -822,23 +848,21 @@ GeckoChildProcessHost::PerformAsyncLaunc
 #if defined(MOZ_CRASHREPORTER)
   cmdLine.AppendLooseValue(
     UTF8ToWide(CrashReporter::GetChildNotificationPipe()));
 #endif
 
   // Process type
   cmdLine.AppendLooseValue(UTF8ToWide(childProcessType));
 
-#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
-  if (mSandboxEnabled) {
-
-    mozilla::SandboxBroker sandboxBroker;
-    sandboxBroker.LaunchApp(cmdLine.program().c_str(),
-                            cmdLine.command_line_string().c_str(),
-                            &process);
+#if defined(XP_WIN)
+  if (shouldSandboxCurrentProcess) {
+    mSandboxBroker.LaunchApp(cmdLine.program().c_str(),
+                             cmdLine.command_line_string().c_str(),
+                             &process);
   } else
 #endif
   {
     base::LaunchApp(cmdLine, false, false, &process);
   }
 
 #else
 #  error Sorry
--- a/ipc/glue/GeckoChildProcessHost.h
+++ b/ipc/glue/GeckoChildProcessHost.h
@@ -15,16 +15,20 @@
 #include "mozilla/ipc/FileDescriptor.h"
 #include "mozilla/Monitor.h"
 #include "mozilla/StaticPtr.h"
 
 #include "nsCOMPtr.h"
 #include "nsXULAppAPI.h"        // for GeckoProcessType
 #include "nsString.h"
 
+#if defined(XP_WIN)
+#include "sandboxBroker.h"
+#endif
+
 class nsIFile;
 
 namespace mozilla {
 namespace ipc {
 
 class GeckoChildProcessHost : public ChildProcessHost
 {
 protected:
@@ -126,25 +130,20 @@ public:
    * Must run on the IO thread.  Cause the OS process to exit and
    * ensure its OS resources are cleaned up.
    */
   void Join();
 
   // For bug 943174: Skip the EnsureProcessTerminated call in the destructor.
   void SetAlreadyDead();
 
-  void SetSandboxEnabled(bool aSandboxEnabled) {
-    mSandboxEnabled = aSandboxEnabled;
-  }
-
   static void CacheGreDir();
 
 protected:
   GeckoProcessType mProcessType;
-  bool mSandboxEnabled;
   ChildPrivileges mPrivileges;
   Monitor mMonitor;
   FilePath mProcessPath;
 
   // This value must be accessed while holding mMonitor.
   enum {
     // This object has been constructed, but the OS process has not
     // yet.
@@ -163,17 +162,18 @@ protected:
 
   static int32_t mChildCounter;
 
   void PrepareLaunch();
 
 #ifdef XP_WIN
   void InitWindowsGroupID();
   nsString mGroupId;
-#endif
+  SandboxBroker mSandboxBroker;
+#endif // XP_WIN
 
 #if defined(OS_POSIX)
   base::file_handle_mapping_vector mFileMap;
 #endif
 
   base::WaitableEventWatcher::Delegate* mDelegate;
 
   ProcessHandle mChildProcessHandle;
--- a/ipc/glue/moz.build
+++ b/ipc/glue/moz.build
@@ -146,14 +146,14 @@ FINAL_LIBRARY = 'xul'
 for var in ('MOZ_CHILD_PROCESS_NAME', 'MOZ_CHILD_PROCESS_BUNDLE',
             'DLL_PREFIX', 'DLL_SUFFIX'):
     DEFINES[var] = '"%s"' % CONFIG[var]
 
 LOCAL_INCLUDES += [
     '/toolkit/crashreporter',
 ]
 
-if CONFIG['MOZ_CONTENT_SANDBOX'] and CONFIG['OS_ARCH'] == 'WINNT':
+if CONFIG['OS_ARCH'] == 'WINNT':
     LOCAL_INCLUDES += [
         '/security/sandbox/win/src/sandboxbroker',
     ]
 
 FAIL_ON_WARNINGS = True
--- a/security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp
+++ b/security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp
@@ -1,88 +1,127 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 2; 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 "sandboxBroker.h"
 #include "sandbox/win/src/sandbox.h"
 #include "sandbox/win/src/sandbox_factory.h"
+#include "sandbox/win/src/security_level.h"
 
 namespace mozilla
 {
 
 sandbox::BrokerServices *SandboxBroker::sBrokerService = nullptr;
 
 SandboxBroker::SandboxBroker()
 {
+  // XXX: This is not thread-safe! Two threads could simultaneously try
+  // to set `sBrokerService`
   if (!sBrokerService) {
     sBrokerService = sandbox::SandboxFactory::GetBrokerServices();
     if (sBrokerService) {
       sandbox::ResultCode result = sBrokerService->Init();
       if (result != sandbox::SBOX_ALL_OK) {
         sBrokerService = nullptr;
       }
     }
   }
 
-  // We'll start to increase the restrictions over time.
   mPolicy = sBrokerService->CreatePolicy();
 }
 
 bool
-SandboxBroker::AllowPipe(const wchar_t *aPath)
-{
-  return mPolicy->AddRule(sandbox::TargetPolicy::SUBSYS_NAMED_PIPES,
-                          sandbox::TargetPolicy::NAMEDPIPES_ALLOW_ANY, aPath);
-}
-
-bool
 SandboxBroker::LaunchApp(const wchar_t *aPath,
-                           const wchar_t *aArguments,
-                           void **aProcessHandle)
+                         const wchar_t *aArguments,
+                         void **aProcessHandle)
 {
-  // If the broker service isn't already initialized, do it now
   if (!sBrokerService || !mPolicy) {
     return false;
   }
 
-  // Setup the sandbox policy, this is initially:
-  // Low integrity, unrestricted, in the same window station, within the
-  // same desktop, and has no job object.
-  // We'll start to increase the restrictions over time.
-  mPolicy->SetJobLevel(sandbox::JOB_NONE, 0);
-  mPolicy->SetTokenLevel(sandbox::USER_RESTRICTED_SAME_ACCESS,
-                         sandbox::USER_RESTRICTED_SAME_ACCESS);
-  mPolicy->SetDelayedIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW);
-
-  // Set an alternate Desktop within a new window station
-  mPolicy->SetAlternateDesktop(false);
-
   // Set stdout and stderr, to allow inheritance for logging.
   mPolicy->SetStdoutHandle(::GetStdHandle(STD_OUTPUT_HANDLE));
   mPolicy->SetStderrHandle(::GetStdHandle(STD_ERROR_HANDLE));
 
   // Ceate the sandboxed process
   PROCESS_INFORMATION targetInfo;
   sandbox::ResultCode result;
   result = sBrokerService->SpawnTarget(aPath, aArguments, mPolicy, &targetInfo);
 
-  // The sandboxed process is started in a suspended state, resumeit now that
-  // we'eve set things up.
+  // The sandboxed process is started in a suspended state, resume it now that
+  // we've set things up.
   ResumeThread(targetInfo.hThread);
   CloseHandle(targetInfo.hThread);
 
   // Return the process handle to the caller
   *aProcessHandle = targetInfo.hProcess;
 
   return true;
 }
 
+bool
+SandboxBroker::SetSecurityLevelForContentProcess()
+{
+  if (!mPolicy) {
+    return false;
+  }
+
+  mPolicy->SetJobLevel(sandbox::JOB_NONE, 0);
+  mPolicy->SetTokenLevel(sandbox::USER_RESTRICTED_SAME_ACCESS,
+                         sandbox::USER_RESTRICTED_SAME_ACCESS);
+  mPolicy->SetDelayedIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW);
+  mPolicy->SetAlternateDesktop(true);
+  return true;
+}
+
+bool
+SandboxBroker::SetSecurityLevelForPluginProcess()
+{
+  if (!mPolicy) {
+    return false;
+  }
+
+  mPolicy->SetJobLevel(sandbox::JOB_NONE, 0);
+  mPolicy->SetTokenLevel(sandbox::USER_UNPROTECTED,
+                         sandbox::USER_UNPROTECTED);
+  return true;
+}
+
+bool
+SandboxBroker::SetSecurityLevelForIPDLUnitTestProcess()
+{
+  if (!mPolicy) {
+    return false;
+  }
+
+  mPolicy->SetJobLevel(sandbox::JOB_NONE, 0);
+  mPolicy->SetTokenLevel(sandbox::USER_RESTRICTED_SAME_ACCESS,
+                         sandbox::USER_RESTRICTED_SAME_ACCESS);
+  return true;
+}
+
+bool
+SandboxBroker::SetSecurityLevelForGMPlugin()
+{
+  if (!mPolicy) {
+    return false;
+  }
+
+  mPolicy->SetJobLevel(sandbox::JOB_LOCKDOWN, 0);
+  mPolicy->SetTokenLevel(sandbox::USER_RESTRICTED_SAME_ACCESS,
+                         sandbox::USER_RESTRICTED_SAME_ACCESS);
+  mPolicy->SetDelayedIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW);
+  mPolicy->SetAlternateDesktop(true);
+  return true;
+}
+
+
 SandboxBroker::~SandboxBroker()
 {
   if (mPolicy) {
     mPolicy->Release();
     mPolicy = nullptr;
   }
 }
 
--- a/security/sandbox/win/src/sandboxbroker/sandboxBroker.h
+++ b/security/sandbox/win/src/sandboxbroker/sandboxBroker.h
@@ -19,21 +19,27 @@ namespace sandbox {
 }
 
 namespace mozilla {
 
 class SANDBOX_EXPORT SandboxBroker
 {
 public:
   SandboxBroker();
-  bool AllowPipe(const wchar_t *aPath);
-  bool LaunchApp(const wchar_t *aPath, const wchar_t *aArguments,
+  bool LaunchApp(const wchar_t *aPath,
+                 const wchar_t *aArguments,
                  void **aProcessHandle);
   virtual ~SandboxBroker();
 
+  // Security levels for different types of processes
+  bool SetSecurityLevelForContentProcess();
+  bool SetSecurityLevelForPluginProcess();
+  bool SetSecurityLevelForIPDLUnitTestProcess();
+  bool SetSecurityLevelForGMPlugin();
+
 private:
   static sandbox::BrokerServices *sBrokerService;
   sandbox::TargetPolicy *mPolicy;
 };
 
 } // mozilla
 
 #endif
--- a/toolkit/library/Makefile.in
+++ b/toolkit/library/Makefile.in
@@ -1,17 +1,15 @@
 # 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/.
 
-ifdef MOZ_CONTENT_SANDBOX
 ifeq ($(OS_ARCH),WINNT)
   SHARED_LIBRARY_LIBS += ../../security/sandbox/win/src/sandboxbroker/$(LIB_PREFIX)sandboxbroker.$(LIB_SUFFIX)
 endif
-endif
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
 CXXFLAGS += $(TK_CFLAGS)
 endif
 
 include $(topsrcdir)/config/rules.mk
 
 .PHONY: gtestxul
--- a/toolkit/toolkit.mozbuild
+++ b/toolkit/toolkit.mozbuild
@@ -1,17 +1,17 @@
 # vim: set filetype=python:
 # 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/.
 
 if CONFIG['LIBXUL_SDK']:
     error('toolkit.mozbuild is not compatible with --enable-libxul-sdk=')
 
-if CONFIG['MOZ_CONTENT_SANDBOX']:
+if CONFIG['MOZ_CONTENT_SANDBOX'] or (CONFIG['OS_ARCH'] == 'WINNT'):
     add_tier_dir('sandbox', 'security/sandbox')
 
 # Depends on NSS and NSPR, and must be built after sandbox or else B2G emulator
 # builds fail.
 add_tier_dir('platform', 'security/certverifier')
 
 # Depends on certverifier
 add_tier_dir('platform', 'security/apps')