Bug 1358223 - Part 1 - On Windows and macOS hardcode the minimum content sandbox level at 1. draft
authorAlex Gaynor <agaynor@mozilla.com>
Fri, 12 May 2017 17:04:42 -0400
changeset 587257 dec3d657f5afec6192a09da9e8b4855123ce97ce
parent 587256 94906c37940c6b1c371dc7c22ed2098face96d8b
child 587258 39b29adcf17531edace6af46ff5c09980ec18e96
push id61668
push userbmo:agaynor@mozilla.com
push dateWed, 31 May 2017 19:53:14 +0000
bugs1358223
milestone55.0a1
Bug 1358223 - Part 1 - On Windows and macOS hardcode the minimum content sandbox level at 1. If the "security.sandbox.content.level" preference is set to a value less than 1, all consumers will automatically treat it as if it were level 1. On Linux and Nightly builds, setting the sandbox level to 0 is still allowed, for now. MozReview-Commit-ID: 9QNTCkdbTfm
browser/app/profile/firefox.js
browser/installer/package-manifest.in
dom/ipc/ContentChild.cpp
dom/ipc/ContentParent.cpp
dom/ipc/ContentProcess.cpp
ipc/glue/GeckoChildProcessHost.cpp
security/sandbox/common/SandboxSettings.cpp
security/sandbox/common/SandboxSettings.h
security/sandbox/common/moz.build
security/sandbox/common/mozISandboxSettings.idl
security/sandbox/linux/broker/SandboxBrokerPolicyFactory.cpp
security/sandbox/moz.build
security/sandbox/test/browser_content_sandbox_fs.js
security/sandbox/test/browser_content_sandbox_syscalls.js
toolkit/components/telemetry/docs/data/environment.rst
toolkit/locales/en-US/chrome/global/aboutSupport.properties
toolkit/modules/Troubleshoot.jsm
toolkit/modules/tests/browser/browser_Troubleshoot.js
toolkit/xre/nsAppRunner.cpp
toolkit/xre/nsEmbedFunctions.cpp
toolkit/xre/nsXREDirProvider.cpp
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1038,17 +1038,17 @@ pref("security.sandbox.windows.log.stack
 // SetSecurityLevelForGPUProcess() in
 // security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp
 pref("security.sandbox.gpu.level", 0);
 #endif
 
 #if defined(XP_MACOSX) && defined(MOZ_SANDBOX) && defined(MOZ_CONTENT_SANDBOX)
 // This pref is discussed in bug 1083344, the naming is inspired from its
 // Windows counterpart, but on Mac it's an integer which means:
-// 0 -> "no sandbox"
+// 0 -> "no sandbox" (nightly only)
 // 1 -> "preliminary content sandboxing enabled: write access to
 //       home directory is prevented"
 // 2 -> "preliminary content sandboxing enabled with profile protection:
 //       write access to home directory is prevented, read and write access
 //       to ~/Library and profile directories are prevented (excluding
 //       $PROFILE/{extensions,weave})"
 // This setting is read when the content process is started. On Mac the content
 // process is killed when all windows are closed, so a change will take effect
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -741,19 +741,19 @@
 @RESPATH@/chrome/pippki.manifest
 @RESPATH@/components/pipnss.xpt
 @RESPATH@/components/pippki.xpt
 
 ; For process sandboxing
 #if defined(MOZ_SANDBOX)
 #if defined(XP_LINUX)
 @BINPATH@/@DLL_PREFIX@mozsandbox@DLL_SUFFIX@
+#endif
 @RESPATH@/components/sandbox.xpt
 #endif
-#endif
 
 ; for Solaris SPARC
 #ifdef SOLARIS
 bin/libfreebl_32fpu_3.so
 bin/libfreebl_32int_3.so
 bin/libfreebl_32int64_3.so
 #endif
 
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -73,16 +73,17 @@
 #include "imgLoader.h"
 #include "GMPServiceChild.h"
 
 #ifdef MOZ_GECKO_PROFILER
 #include "ChildProfilerController.h"
 #endif
 
 #if defined(MOZ_CONTENT_SANDBOX)
+#include "mozilla/SandboxSettings.h"
 #if defined(XP_WIN)
 #define TARGET_SANDBOX_EXPORTS
 #include "mozilla/sandboxTarget.h"
 #elif defined(XP_LINUX)
 #include "mozilla/Sandbox.h"
 #include "mozilla/SandboxInfo.h"
 
 // Remove this include with Bug 1104619
@@ -1337,17 +1338,17 @@ GetDirectoryPath(const char *aPath) {
   }
   return directoryPath;
 }
 #endif // DEBUG
 
 static bool
 StartMacOSContentSandbox()
 {
-  int sandboxLevel = Preferences::GetInt("security.sandbox.content.level");
+  int sandboxLevel = GetEffectiveContentSandboxLevel();
   if (sandboxLevel < 1) {
     return false;
   }
 
   nsAutoCString appPath, appBinaryPath, appDir;
   if (!GetAppPaths(appPath, appBinaryPath, appDir)) {
     MOZ_CRASH("Error resolving child process path");
   }
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -224,21 +224,24 @@
 #include "mozilla/RemoteSpellCheckEngineParent.h"
 
 #include "Crypto.h"
 
 #ifdef MOZ_WEBSPEECH
 #include "mozilla/dom/SpeechSynthesisParent.h"
 #endif
 
-#if defined(MOZ_CONTENT_SANDBOX) && defined(XP_LINUX)
+#if defined(MOZ_CONTENT_SANDBOX)
+#include "mozilla/SandboxSettings.h"
+#if defined(XP_LINUX)
 #include "mozilla/SandboxInfo.h"
 #include "mozilla/SandboxBroker.h"
 #include "mozilla/SandboxBrokerPolicyFactory.h"
 #endif
+#endif
 
 #ifdef MOZ_TOOLKIT_SEARCH
 #include "nsIBrowserSearchService.h"
 #endif
 
 #ifdef XP_WIN
 #include "mozilla/widget/AudioSession.h"
 #endif
@@ -2334,17 +2337,17 @@ ContentParent::InitInternal(ProcessPrior
   bool shouldSandbox = true;
   MaybeFileDesc brokerFd = void_t();
 #ifdef XP_LINUX
   // XXX: Checking the pref here makes it possible to enable/disable sandboxing
   // during an active session. Currently the pref is only used for testing
   // purpose. If the decision is made to permanently rely on the pref, this
   // should be changed so that it is required to restart firefox for the change
   // of value to take effect.
-  shouldSandbox = (Preferences::GetInt("security.sandbox.content.level") > 0) &&
+  shouldSandbox = (GetEffectiveContentSandboxLevel() > 0) &&
     !PR_GetEnv("MOZ_DISABLE_CONTENT_SANDBOX");
 
   if (shouldSandbox) {
     MOZ_ASSERT(!mSandboxBroker);
     UniquePtr<SandboxBroker::Policy> policy =
       sSandboxBrokerPolicyFactory->GetContentPolicy(Pid());
     if (policy) {
       brokerFd = FileDescriptor();
--- a/dom/ipc/ContentProcess.cpp
+++ b/dom/ipc/ContentProcess.cpp
@@ -10,33 +10,34 @@
 #include "ContentPrefs.h"
 
 #if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
 #include <stdlib.h>
 #endif
 
 #if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
 #include "mozilla/Preferences.h"
+#include "mozilla/SandboxSettings.h"
 #include "nsAppDirectoryServiceDefs.h"
 #include "nsDirectoryService.h"
 #include "nsDirectoryServiceDefs.h"
 #endif
 
 using mozilla::ipc::IOThreadChild;
 
 namespace mozilla {
 namespace dom {
 
 #if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
 static bool
 IsSandboxTempDirRequired()
 {
   // On Windows, a sandbox-writable temp directory is only used
   // when sandbox pref level >= 1.
-  return Preferences::GetInt("security.sandbox.content.level") >= 1;
+  return GetEffectiveContentSandboxLevel() >= 1;
 }
 
 static void
 SetTmpEnvironmentVariable(nsIFile* aValue)
 {
   // Save the TMP environment variable so that is is picked up by GetTempPath().
   // Note that we specifically write to the TMP variable, as that is the first
   // variable that is checked by GetTempPath() to determine its output.
@@ -52,17 +53,17 @@ SetTmpEnvironmentVariable(nsIFile* aValu
 }
 #endif
 
 #if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
 static bool
 IsSandboxTempDirRequired()
 {
   // On OSX, use the sandbox-writable temp when the pref level >= 1.
-  return (Preferences::GetInt("security.sandbox.content.level") >= 1);
+  return (GetEffectiveContentSandboxLevel() >= 1);
 }
 
 static void
 SetTmpEnvironmentVariable(nsIFile* aValue)
 {
   nsAutoCString fullTmpPath;
   nsresult rv = aValue->GetNativePath(fullTmpPath);
   if (NS_WARN_IF(NS_FAILED(rv))) {
--- a/ipc/glue/GeckoChildProcessHost.cpp
+++ b/ipc/glue/GeckoChildProcessHost.cpp
@@ -18,19 +18,22 @@
 #include "SharedMemoryBasic.h"
 #endif
 
 #include "MainThreadUtils.h"
 #include "mozilla/Sprintf.h"
 #include "prenv.h"
 #include "nsXPCOMPrivate.h"
 
-#if defined(MOZ_CONTENT_SANDBOX) && defined(XP_MACOSX)
+#if defined(MOZ_CONTENT_SANDBOX)
+#include "mozilla/SandboxSettings.h"
+#if defined(XP_MACOSX)
 #include "nsAppDirectoryServiceDefs.h"
 #endif
+#endif
 
 #include "nsExceptionHandler.h"
 
 #include "nsDirectoryServiceDefs.h"
 #include "nsIFile.h"
 #include "nsPrintfCString.h"
 
 #include "mozilla/ClearOnShutdown.h"
@@ -306,17 +309,17 @@ GeckoChildProcessHost::PrepareLaunch()
 #ifdef XP_WIN
   if (mProcessType == GeckoProcessType_Plugin) {
     InitWindowsGroupID();
   }
 
 #if defined(MOZ_CONTENT_SANDBOX)
   // We need to get the pref here as the process is launched off main thread.
   if (mProcessType == GeckoProcessType_Content) {
-    mSandboxLevel = Preferences::GetInt("security.sandbox.content.level");
+    mSandboxLevel = GetEffectiveContentSandboxLevel();
     mEnableSandboxLogging =
       Preferences::GetBool("security.sandbox.logging.enabled");
   }
 #endif
 
 #if defined(MOZ_SANDBOX)
   // For other process types we can't rely on them being launched on main
   // thread and they may not have access to prefs in the child process, so allow
new file mode 100644
--- /dev/null
+++ b/security/sandbox/common/SandboxSettings.cpp
@@ -0,0 +1,68 @@
+/* -*- 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/. */
+
+#include "mozISandboxSettings.h"
+
+#include "mozilla/ModuleUtils.h"
+#include "mozilla/Preferences.h"
+
+namespace mozilla {
+
+int GetEffectiveContentSandboxLevel() {
+  int level = Preferences::GetInt("security.sandbox.content.level");
+// On Windows and macOS, enforce a minimum content sandbox level of 1 (except on
+// Nightly, where it can be set to 0).
+#if !defined(NIGHTLY_BUILD) && (defined(XP_WIN) || defined(XP_MACOSX))
+  if (level < 1) {
+    level = 1;
+  }
+#endif
+  return level;
+}
+
+class SandboxSettings final : public mozISandboxSettings
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_MOZISANDBOXSETTINGS
+
+  SandboxSettings() { }
+
+private:
+  ~SandboxSettings() { }
+};
+
+NS_IMPL_ISUPPORTS(SandboxSettings, mozISandboxSettings)
+
+NS_IMETHODIMP SandboxSettings::GetEffectiveContentSandboxLevel(int32_t *aRetVal)
+{
+  *aRetVal = mozilla::GetEffectiveContentSandboxLevel();
+  return NS_OK;
+}
+
+NS_GENERIC_FACTORY_CONSTRUCTOR(SandboxSettings)
+
+NS_DEFINE_NAMED_CID(MOZ_SANDBOX_SETTINGS_CID);
+
+static const mozilla::Module::CIDEntry kSandboxSettingsCIDs[] = {
+  { &kMOZ_SANDBOX_SETTINGS_CID, false, nullptr, SandboxSettingsConstructor },
+  { nullptr }
+};
+
+static const mozilla::Module::ContractIDEntry kSandboxSettingsContracts[] = {
+  { MOZ_SANDBOX_SETTINGS_CONTRACTID, &kMOZ_SANDBOX_SETTINGS_CID },
+  { nullptr }
+};
+
+static const mozilla::Module kSandboxSettingsModule = {
+  mozilla::Module::kVersion,
+  kSandboxSettingsCIDs,
+  kSandboxSettingsContracts
+};
+
+NSMODULE_DEFN(SandboxSettingsModule) = &kSandboxSettingsModule;
+
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/security/sandbox/common/SandboxSettings.h
@@ -0,0 +1,17 @@
+/* -*- Mode: C++; tab-width: 2; 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/. */
+
+#ifndef mozilla_SandboxSettings_h
+#define mozilla_SandboxSettings_h
+
+namespace mozilla {
+
+// Return the current sandbox level. This is the
+// "security.sandbox.content.level" preference, but rounded up to the current
+// minimum allowed level.
+int GetEffectiveContentSandboxLevel();
+
+}
+#endif // mozilla_SandboxPolicies_h
new file mode 100644
--- /dev/null
+++ b/security/sandbox/common/moz.build
@@ -0,0 +1,20 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# 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/.
+
+with Files('**'):
+    BUG_COMPONENT = ('Core', 'Security: Process Sandboxing')
+
+UNIFIED_SOURCES += ['SandboxSettings.cpp']
+
+XPIDL_SOURCES += [
+    'mozISandboxSettings.idl',
+]
+
+XPIDL_MODULE = 'sandbox'
+
+FINAL_LIBRARY = 'xul'
+
+EXPORTS.mozilla += ['SandboxSettings.h']
new file mode 100644
--- /dev/null
+++ b/security/sandbox/common/mozISandboxSettings.idl
@@ -0,0 +1,25 @@
+/* -*- Mode: IDL; 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/. */
+
+#include "nsISupports.idl"
+
+/* Used to expose information about the configuration of the sanbox.
+ */
+[scriptable, builtinclass, uuid(5516303d-9007-45a0-94b9-940ef134a6e2)]
+interface mozISandboxSettings : nsISupports
+{
+  readonly attribute long effectiveContentSandboxLevel;
+};
+
+%{ C++
+
+#define MOZ_SANDBOX_SETTINGS_CID \
+{0x5516303d, 0x9007, 0x45a0, { 0x94, 0xb9, 0x94, 0x0e, 0xf1, 0x34, 0xa6, 0xe2}}
+
+#define MOZ_SANDBOX_SETTINGS_CONTRACTID \
+    "@mozilla.org/sandbox/sandbox-settings;1"
+
+%}
--- a/security/sandbox/linux/broker/SandboxBrokerPolicyFactory.cpp
+++ b/security/sandbox/linux/broker/SandboxBrokerPolicyFactory.cpp
@@ -5,16 +5,17 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "SandboxBrokerPolicyFactory.h"
 #include "SandboxInfo.h"
 #include "SandboxLogging.h"
 
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/SandboxSettings.h"
 #include "nsPrintfCString.h"
 #include "nsString.h"
 #include "nsThreadUtils.h"
 #include "nsXULAppAPI.h"
 #include "SpecialSystemDirectory.h"
 
 #ifdef ANDROID
 #include "cutils/properties.h"
@@ -157,17 +158,17 @@ SandboxBrokerPolicyFactory::SandboxBroke
 UniquePtr<SandboxBroker::Policy>
 SandboxBrokerPolicyFactory::GetContentPolicy(int aPid)
 {
   // Policy entries that vary per-process (currently the only reason
   // that can happen is because they contain the pid) are added here.
 
   MOZ_ASSERT(NS_IsMainThread());
   // File broker usage is controlled through a pref.
-  if (Preferences::GetInt("security.sandbox.content.level") <= 1) {
+  if (GetEffectiveContentSandboxLevel() <= 1) {
     return nullptr;
   }
 
   MOZ_ASSERT(mCommonContentPolicy);
 #if defined(MOZ_WIDGET_GONK)
   // Allow overriding "unsupported"ness with a pref, for testing.
   if (!IsSystemSupported()) {
     return nullptr;
--- a/security/sandbox/moz.build
+++ b/security/sandbox/moz.build
@@ -4,16 +4,18 @@
 # 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/.
 
 BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
 
 with Files('**'):
     BUG_COMPONENT = ('Core', 'Security: Process Sandboxing')
 
+DIRS += ['common']
+
 if CONFIG['OS_ARCH'] == 'Linux':
     DIRS += ['linux']
 elif CONFIG['OS_ARCH'] == 'Darwin':
     DIRS += ['mac']
 elif CONFIG['OS_ARCH'] == 'WINNT':
     Library('sandbox_s')
     FORCE_STATIC_LIB = True
 
--- a/security/sandbox/test/browser_content_sandbox_fs.js
+++ b/security/sandbox/test/browser_content_sandbox_fs.js
@@ -169,20 +169,16 @@ add_task(function* () {
 
   ok(prefExists, "pref security.sandbox.content.level exists");
   if (!prefExists) {
     return;
   }
 
   info(`security.sandbox.content.level=${level}`);
   ok(level > 0, "content sandbox is enabled.");
-  if (level == 0) {
-    info("content sandbox is not enabled, exiting");
-    return;
-  }
 
   let isFileIOSandboxed = isContentFileIOSandboxed(level);
 
   // Content sandbox enabled, but level doesn't include file I/O sandboxing.
   ok(isFileIOSandboxed, "content file I/O sandboxing is enabled.");
   if (!isFileIOSandboxed) {
     info("content sandbox level too low for file I/O tests, exiting\n");
     return;
--- a/security/sandbox/test/browser_content_sandbox_syscalls.js
+++ b/security/sandbox/test/browser_content_sandbox_syscalls.js
@@ -145,20 +145,16 @@ add_task(function* () {
 
   ok(prefExists, "pref security.sandbox.content.level exists");
   if (!prefExists) {
     return;
   }
 
   info(`security.sandbox.content.level=${level}`);
   ok(level > 0, "content sandbox is enabled.");
-  if (level == 0) {
-    info("content sandbox is not enabled, exiting");
-    return;
-  }
 
   let areSyscallsSandboxed = areContentSyscallsSandboxed(level);
 
   // Content sandbox enabled, but level doesn't include syscall sandboxing.
   ok(areSyscallsSandboxed, "content syscall sandboxing is enabled.");
   if (!areSyscallsSandboxed) {
     info("content sandbox level too low for syscall tests, exiting\n");
     return;
--- a/toolkit/components/telemetry/docs/data/environment.rst
+++ b/toolkit/components/telemetry/docs/data/environment.rst
@@ -328,17 +328,17 @@ The following is a partial list of colle
 - ``browser.search.suggest.enabled``: The "master switch" for search suggestions everywhere in Firefox (search bar, urlbar, etc.). Defaults to true.
 
 - ``browser.urlbar.suggest.searches``: True if search suggestions are enabled in the urlbar. Defaults to false.
 
 - ``browser.urlbar.userMadeSearchSuggestionsChoice``: True if the user has clicked Yes or No in the urlbar's opt-in notification. Defaults to false.
 
 - ``browser.zoom.full`` (deprecated): True if zoom is enabled for both text and images, that is if "Zoom Text Only" is not enabled. Defaults to true. This preference was collected in Firefox 50 to 52 (`Bug 979323 <https://bugzilla.mozilla.org/show_bug.cgi?id=979323>`_).
 
-- ``security.sandbox.content.level``: The meanings of the values are OS dependent, but 0 means not sandboxed for all OS. Details of the meanings can be found in the `Firefox prefs file <https://hg.mozilla.org/mozilla-central/file/tip/browser/app/profile/firefox.js>`_.
+- ``security.sandbox.content.level``: The meanings of the values are OS dependent. Details of the meanings can be found in the `Firefox prefs file <https://hg.mozilla.org/mozilla-central/file/tip/browser/app/profile/firefox.js>`_.
 
 attribution
 ~~~~~~~~~~~
 
 This object contains the attribution data for the product installation.
 
 Attribution data is used to link installations of Firefox with the source that the user arrived at the Firefox download page from. It would indicate, for instance, when a user executed a web search for Firefox and arrived at the download page from there, directly navigated to the site, clicked on a link from a particular social media campaign, etc.
 
--- a/toolkit/locales/en-US/chrome/global/aboutSupport.properties
+++ b/toolkit/locales/en-US/chrome/global/aboutSupport.properties
@@ -106,16 +106,17 @@ loadedLibVersions = Version in use
 
 hasSeccompBPF = Seccomp-BPF (System Call Filtering)
 hasSeccompTSync = Seccomp Thread Synchronization
 hasUserNamespaces = User Namespaces
 hasPrivilegedUserNamespaces = User Namespaces for privileged processes
 canSandboxContent = Content Process Sandboxing
 canSandboxMedia = Media Plugin Sandboxing
 contentSandboxLevel = Content Process Sandbox Level
+effectiveContentSandboxLevel = Effective Content Process Sandbox Level
 sandboxProcType.content = content
 sandboxProcType.mediaPlugin = media plugin
 
 # LOCALIZATION NOTE %1$S and %2$S will be replaced with the number of remote and the total number
 # of windows, respectively, while %3$S will be replaced with one of the status strings below,
 # which contains a description of the multi-process preference and status.
 # Note: multiProcessStatus.3 doesn't exist because status=3 was deprecated.
 multiProcessWindows = %1$S/%2$S (%3$S)
--- a/toolkit/modules/Troubleshoot.jsm
+++ b/toolkit/modules/Troubleshoot.jsm
@@ -617,15 +617,19 @@ if (AppConstants.MOZ_SANDBOX) {
           args.push(report.getArg(i));
         }
         syscalls.push({ index, msecAgo, pid, tid, procType, syscall, args });
       }
       data.syscallLog = syscalls;
     }
 
     if (AppConstants.MOZ_CONTENT_SANDBOX) {
+      let sandboxSettings = Cc["@mozilla.org/sandbox/sandbox-settings;1"].
+                            getService(Ci.mozISandboxSettings);
       data.contentSandboxLevel =
         Services.prefs.getIntPref("security.sandbox.content.level");
+      data.effectiveContentSandboxLevel =
+        sandboxSettings.effectiveContentSandboxLevel;
     }
 
     done(data);
   }
 }
--- a/toolkit/modules/tests/browser/browser_Troubleshoot.js
+++ b/toolkit/modules/tests/browser/browser_Troubleshoot.js
@@ -515,16 +515,20 @@ const SNAPSHOT_SCHEMA = {
         canSandboxMedia: {
           required: false,
           type: "boolean"
         },
         contentSandboxLevel: {
           required: AppConstants.MOZ_CONTENT_SANDBOX,
           type: "number"
         },
+        effectiveContentSandboxLevel: {
+          required: AppConstants.MOZ_CONTENT_SANDBOX,
+          type: "number"
+        },
 	syscallLog: {
 	  required: AppConstants.platform == "linux",
 	  type: "array",
 	  items: {
 	    type: "object",
 	    properties: {
 	      index: {
 		required: true,
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -105,19 +105,22 @@
 #include "mozilla/mscom/MainThreadRuntime.h"
 #include "mozilla/widget/AudioSession.h"
 
 #ifndef PROCESS_DEP_ENABLE
 #define PROCESS_DEP_ENABLE 0x1
 #endif
 #endif
 
-#if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
+#if defined(MOZ_CONTENT_SANDBOX)
+#include "mozilla/SandboxSettings.h"
+#if (defined(XP_WIN) || defined(XP_MACOSX))
 #include "nsIUUIDGenerator.h"
 #endif
+#endif
 
 #ifdef ACCESSIBILITY
 #include "nsAccessibilityService.h"
 #if defined(XP_WIN)
 #include "mozilla/a11y/Compatibility.h"
 #endif
 #endif
 
@@ -4188,17 +4191,17 @@ XREMain::XRE_mainStartup(bool* aExitFlag
   return 0;
 }
 
 #if defined(MOZ_CRASHREPORTER)
 #if defined(MOZ_CONTENT_SANDBOX) && !defined(MOZ_WIDGET_GONK)
 void AddSandboxAnnotations()
 {
   // Include the sandbox content level, regardless of platform
-  int level = Preferences::GetInt("security.sandbox.content.level");
+  int level = GetEffectiveContentSandboxLevel();
 
   nsAutoCString levelString;
   levelString.AppendInt(level);
 
   CrashReporter::AnnotateCrashReport(
     NS_LITERAL_CSTRING("ContentSandboxLevel"), levelString);
 
   // Include whether or not this instance is capable of content sandboxing
--- a/toolkit/xre/nsEmbedFunctions.cpp
+++ b/toolkit/xre/nsEmbedFunctions.cpp
@@ -82,19 +82,22 @@
 
 #include "mozilla/Telemetry.h"
 
 #if defined(MOZ_SANDBOX) && defined(XP_WIN)
 #include "mozilla/sandboxTarget.h"
 #include "mozilla/sandboxing/loggingCallbacks.h"
 #endif
 
-#if defined(MOZ_CONTENT_SANDBOX) && !defined(MOZ_WIDGET_GONK)
+#if defined(MOZ_CONTENT_SANDBOX)
+#include "mozilla/SandboxSettings.h"
+#if !defined(MOZ_WIDGET_GONK)
 #include "mozilla/Preferences.h"
 #endif
+#endif
 
 #if defined(XP_LINUX) && defined(MOZ_GMP_SANDBOX)
 #include "mozilla/Sandbox.h"
 #include "mozilla/SandboxInfo.h"
 #endif
 
 #if defined(XP_LINUX)
 #include <sys/prctl.h>
@@ -306,17 +309,17 @@ SetTaskbarGroupId(const nsString& aId)
 #endif
 
 #if defined(MOZ_CRASHREPORTER)
 #if defined(MOZ_CONTENT_SANDBOX) && !defined(MOZ_WIDGET_GONK)
 void
 AddContentSandboxLevelAnnotation()
 {
   if (XRE_GetProcessType() == GeckoProcessType_Content) {
-    int level = Preferences::GetInt("security.sandbox.content.level");
+    int level = GetEffectiveContentSandboxLevel();
     nsAutoCString levelString;
     levelString.AppendInt(level);
     CrashReporter::AnnotateCrashReport(
       NS_LITERAL_CSTRING("ContentSandboxLevel"), levelString);
   }
 }
 #endif /* MOZ_CONTENT_SANDBOX && !MOZ_WIDGET_GONK */
 #endif /* MOZ_CRASHREPORTER */
--- a/toolkit/xre/nsXREDirProvider.cpp
+++ b/toolkit/xre/nsXREDirProvider.cpp
@@ -58,20 +58,23 @@
 #endif
 #ifdef XP_UNIX
 #include <ctype.h>
 #endif
 #ifdef XP_IOS
 #include "UIKitDirProvider.h"
 #endif
 
-#if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
+#if defined(MOZ_CONTENT_SANDBOX)
+#include "mozilla/SandboxSettings.h"
+#if (defined(XP_WIN) || defined(XP_MACOSX))
 #include "nsIUUIDGenerator.h"
 #include "mozilla/Unused.h"
 #endif
+#endif
 
 #if defined(XP_MACOSX)
 #define APP_REGISTRY_NAME "Application Registry"
 #elif defined(XP_WIN)
 #define APP_REGISTRY_NAME "registry.dat"
 #else
 #define APP_REGISTRY_NAME "appreg"
 #endif
@@ -681,24 +684,17 @@ nsXREDirProvider::LoadContentProcessTemp
     return NS_GetSpecialDirectory(NS_OS_TEMP_DIR,
                                   getter_AddRefs(mContentTempDir));
   }
 }
 
 static bool
 IsContentSandboxDisabled()
 {
-  if (!BrowserTabsRemoteAutostart()) {
-    return false;
-  }
-#if defined(XP_WIN) || defined(XP_MACOSX)
-  const bool isSandboxDisabled =
-    Preferences::GetInt("security.sandbox.content.level") < 1;
-#endif
-  return isSandboxDisabled;
+  return !BrowserTabsRemoteAutostart() || (GetEffectiveContentSandboxLevel() < 1);
 }
 
 //
 // If a content process sandbox temp dir is to be used, returns an nsIFile
 // for the directory. Returns null if the content sandbox is disabled or
 // an error occurs.
 //
 static already_AddRefed<nsIFile>
@@ -1656,17 +1652,17 @@ nsXREDirProvider::AppendSysUserExtension
 nsresult
 nsXREDirProvider::AppendProfilePath(nsIFile* aFile,
                                     const nsACString* aProfileName,
                                     const nsACString* aAppName,
                                     const nsACString* aVendorName,
                                     bool aLocal)
 {
   NS_ASSERTION(aFile, "Null pointer!");
-  
+
   if (!gAppData) {
     return NS_ERROR_FAILURE;
   }
 
   nsAutoCString profile;
   nsAutoCString appName;
   nsAutoCString vendor;
   if (aProfileName && !aProfileName->IsEmpty()) {