tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

SandboxSettings.cpp (9996B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
      5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "mozilla/SandboxSettings.h"
      8 #include "mozISandboxSettings.h"
      9 #include "nsServiceManagerUtils.h"
     10 #include "nsAppRunner.h"
     11 
     12 #include "mozilla/Components.h"
     13 #include "mozilla/Preferences.h"
     14 #include "mozilla/StaticPrefs_media.h"
     15 #include "mozilla/StaticPrefs_network.h"
     16 #include "mozilla/StaticPrefs_security.h"
     17 #include "mozilla/StaticPrefs_webgl.h"
     18 
     19 #include "prenv.h"
     20 
     21 #ifdef XP_WIN
     22 #  include "mozilla/gfx/gfxVars.h"
     23 #  include "nsExceptionHandler.h"
     24 #  include "PDMFactory.h"
     25 #endif  // XP_WIN
     26 
     27 using namespace mozilla;
     28 
     29 namespace mozilla {
     30 
     31 const char* ContentWin32kLockdownStateToString(
     32    nsIXULRuntime::ContentWin32kLockdownState aValue) {
     33  switch (aValue) {
     34    case nsIXULRuntime::ContentWin32kLockdownState::LockdownEnabled:
     35      return "Win32k Lockdown enabled";
     36 
     37    case nsIXULRuntime::ContentWin32kLockdownState::MissingWebRender:
     38      return "Win32k Lockdown disabled -- Missing WebRender";
     39 
     40    case nsIXULRuntime::ContentWin32kLockdownState::OperatingSystemNotSupported:
     41      return "Win32k Lockdown disabled -- Operating system not supported";
     42 
     43    case nsIXULRuntime::ContentWin32kLockdownState::PrefNotSet:
     44      return "Win32k Lockdown disabled -- Preference not set";
     45 
     46    case nsIXULRuntime::ContentWin32kLockdownState::MissingRemoteWebGL:
     47      return "Win32k Lockdown disabled -- Missing Remote WebGL";
     48 
     49    case nsIXULRuntime::ContentWin32kLockdownState::MissingNonNativeTheming:
     50      return "Win32k Lockdown disabled -- Missing Non-Native Theming";
     51 
     52    case nsIXULRuntime::ContentWin32kLockdownState::DecodersArentRemote:
     53      return "Win32k Lockdown disabled -- Not all media decoders are remoted "
     54             "to Utility Process";
     55 
     56    case nsIXULRuntime::ContentWin32kLockdownState::DisabledByEnvVar:
     57      return "Win32k Lockdown disabled -- MOZ_ENABLE_WIN32K is set";
     58 
     59    case nsIXULRuntime::ContentWin32kLockdownState::DisabledByE10S:
     60      return "Win32k Lockdown disabled -- E10S is disabled";
     61 
     62    case nsIXULRuntime::ContentWin32kLockdownState::DisabledByUserPref:
     63      return "Win32k Lockdown disabled -- manually set "
     64             "security.sandbox.content.win32k-disable to false";
     65 
     66    case nsIXULRuntime::ContentWin32kLockdownState::EnabledByUserPref:
     67      return "Win32k Lockdown enabled -- manually set "
     68             "security.sandbox.content.win32k-disable to true";
     69 
     70    case nsIXULRuntime::ContentWin32kLockdownState::DisabledByControlGroup:
     71      return "Win32k Lockdown disabled -- user in Control Group";
     72 
     73    case nsIXULRuntime::ContentWin32kLockdownState::EnabledByTreatmentGroup:
     74      return "Win32k Lockdown enabled -- user in Treatment Group";
     75 
     76    case nsIXULRuntime::ContentWin32kLockdownState::DisabledByDefault:
     77      return "Win32k Lockdown disabled -- default value is false";
     78 
     79    case nsIXULRuntime::ContentWin32kLockdownState::EnabledByDefault:
     80      return "Win32k Lockdown enabled -- default value is true";
     81 
     82    case nsIXULRuntime::ContentWin32kLockdownState::
     83        IncompatibleMitigationPolicy:
     84      return "Win32k Lockdown disabled -- Incompatible Windows Exploit "
     85             "Protection policies enabled";
     86  }
     87 
     88  MOZ_CRASH("Should never reach here");
     89 }
     90 
     91 bool GetContentWin32kLockdownEnabled() {
     92  auto state = GetContentWin32kLockdownState();
     93  return state ==
     94             nsIXULRuntime::ContentWin32kLockdownState::EnabledByUserPref ||
     95         state == nsIXULRuntime::ContentWin32kLockdownState::
     96                      EnabledByTreatmentGroup ||
     97         state == nsIXULRuntime::ContentWin32kLockdownState::EnabledByDefault;
     98 }
     99 
    100 nsIXULRuntime::ContentWin32kLockdownState GetContentWin32kLockdownState() {
    101 #ifdef XP_WIN
    102 
    103  static auto getLockdownState = [] {
    104    auto state = GetWin32kLockdownState();
    105 
    106    CrashReporter::RecordAnnotationCString(
    107        CrashReporter::Annotation::ContentSandboxWin32kState,
    108        ContentWin32kLockdownStateToString(state));
    109 
    110    return state;
    111  };
    112 
    113  static nsIXULRuntime::ContentWin32kLockdownState result = getLockdownState();
    114  return result;
    115 
    116 #else  // XP_WIN
    117 
    118  return nsIXULRuntime::ContentWin32kLockdownState::OperatingSystemNotSupported;
    119 
    120 #endif  // XP_WIN
    121 }
    122 
    123 #if defined(XP_WIN)
    124 static bool IsWebglOutOfProcessEnabled() {
    125  if (StaticPrefs::webgl_out_of_process_force()) {
    126    return true;
    127  }
    128 
    129  // We have to check initialization state for gfxVars, because of early use in
    130  // child processes. In rare cases this could lead to the incorrect sandbox
    131  // level being reported, but not the incorrect one being set.
    132  if (gfx::gfxVars::IsInitialized() && !gfx::gfxVars::AllowWebglOop()) {
    133    return false;
    134  }
    135 
    136  return StaticPrefs::webgl_out_of_process();
    137 }
    138 #endif
    139 
    140 int GetEffectiveContentSandboxLevel() {
    141  if (PR_GetEnv("MOZ_DISABLE_CONTENT_SANDBOX")) {
    142    return 0;
    143  }
    144  int level = StaticPrefs::security_sandbox_content_level_DoNotUseDirectly();
    145 #if !defined(NIGHTLY_BUILD) && defined(XP_MACOSX)
    146  // On non-Nightly macOS, enforce a minimum sandbox level of 1.
    147  static const int minimumLevel = 1;
    148 #elif defined(XP_WIN)
    149  // On Windows, enforce a minimum sandbox level of 6.
    150  static const int minimumLevel = 6;
    151 #else
    152  static const int minimumLevel = 0;
    153 #endif
    154  if (level < minimumLevel) {
    155    level = minimumLevel;
    156  }
    157 #ifdef XP_LINUX
    158  // Level 1 was a configuration with default-deny seccomp-bpf but
    159  // which allowed direct filesystem access; that required additional
    160  // code for the syscall filter which was untested and tended to
    161  // bit-rot.  It was trivially escapable and was no longer being used
    162  // even for debugging, so it has been removed.
    163  //
    164  // If the content sandbox is enabled, enforce a minimum level of 2.
    165  static constexpr int kMinSupportedLevel = 2;
    166 
    167  if (level > 0 && level <= kMinSupportedLevel) {
    168    level = kMinSupportedLevel;
    169  }
    170  // Level 4 and up will break direct access to audio.
    171  if (level > 3 && !StaticPrefs::media_cubeb_sandbox()) {
    172    level = 3;
    173  }
    174  // Turn off ioctl lockdown in safe mode, until it's gotten more testing.
    175  if (level > 5 && gSafeMode) {
    176    level = 5;
    177  }
    178 #endif
    179 #if defined(XP_WIN)
    180  // Sandbox level 8, which uses a USER_RESTRICTED access token level, breaks if
    181  // prefs moving processing out of the content process are not the default.
    182  if (level >= 8 &&
    183      (!IsWebglOutOfProcessEnabled() ||
    184       !PDMFactory::AllDecodersAreRemote()
    185 #  if defined(MOZ_WEBRTC) && !defined(MOZ_THUNDERBIRD)
    186       // These are only relevant if webrtc is present. Thunderbird currently
    187       // compiles with webrtc, but doesn't use it.
    188       || !StaticPrefs::network_process_enabled() ||
    189       !Preferences::GetBool("media.peerconnection.mtransport_process")
    190 #  endif
    191           )) {
    192    level = 7;
    193  }
    194 #endif
    195 
    196  return level;
    197 }
    198 
    199 bool IsContentSandboxEnabled() { return GetEffectiveContentSandboxLevel() > 0; }
    200 
    201 bool IsGPUSandboxEnabled() {
    202  return Preferences::GetInt("security.sandbox.gpu.level") > 0;
    203 }
    204 
    205 int GetEffectiveSocketProcessSandboxLevel() {
    206  if (PR_GetEnv("MOZ_DISABLE_SOCKET_PROCESS_SANDBOX")) {
    207    return 0;
    208  }
    209 
    210  int level =
    211      StaticPrefs::security_sandbox_socket_process_level_DoNotUseDirectly();
    212 
    213 #ifdef XP_LINUX
    214  // Turn off ioctl lockdown in safe mode, until it's gotten more testing.
    215  if (level > 1 && gSafeMode) {
    216    level = 1;
    217  }
    218 #endif
    219 
    220  return level;
    221 }
    222 
    223 int GetEffectiveGpuSandboxLevel() {
    224  return StaticPrefs::security_sandbox_gpu_level();
    225 }
    226 
    227 #if defined(MOZ_PROFILE_GENERATE)
    228 // It should only be allowed on instrumented builds, never on production
    229 // builds.
    230 #  if defined(XP_WIN)
    231 bool GetLlvmProfileDir(std::wstring& parentPath) {
    232  bool rv = false;
    233  if (const wchar_t* llvmProfileFileEnv = _wgetenv(L"LLVM_PROFILE_FILE")) {
    234    std::wstring llvmProfileDir(llvmProfileFileEnv);
    235    const size_t found = llvmProfileDir.find_last_of(L"/\\");
    236    if (found != std::string::npos) {
    237      parentPath = llvmProfileDir.substr(0, found);
    238      parentPath.append(L"\\*");
    239      rv = true;
    240    }
    241  }
    242  return rv;
    243 }
    244 #  else   // defined(XP_WIN)
    245 bool GetLlvmProfileDir(std::string& parentPath) {
    246  bool rv = false;
    247  if (const char* llvmProfileFileEnv = getenv("LLVM_PROFILE_FILE")) {
    248    std::string llvmProfileDir(llvmProfileFileEnv);
    249    const size_t found = llvmProfileDir.find_last_of("/\\");
    250    if (found != std::string::npos) {
    251      parentPath = llvmProfileDir.substr(0, found);
    252      rv = true;
    253    }
    254  }
    255  return rv;
    256 }
    257 #  endif  // defined(XP_WIN)
    258 #endif    // defined(MOZ_PROFILE_GENERATE
    259 
    260 #if defined(XP_MACOSX)
    261 int ClampFlashSandboxLevel(const int aLevel) {
    262  const int minLevel = 0;
    263  const int maxLevel = 3;
    264 
    265  if (aLevel < minLevel) {
    266    return minLevel;
    267  }
    268 
    269  if (aLevel > maxLevel) {
    270    return maxLevel;
    271  }
    272  return aLevel;
    273 }
    274 #endif
    275 
    276 class SandboxSettings final : public mozISandboxSettings {
    277 public:
    278  NS_DECL_ISUPPORTS
    279  NS_DECL_MOZISANDBOXSETTINGS
    280 
    281  SandboxSettings() = default;
    282 
    283 private:
    284  ~SandboxSettings() = default;
    285 };
    286 
    287 NS_IMPL_ISUPPORTS(SandboxSettings, mozISandboxSettings)
    288 
    289 NS_IMETHODIMP SandboxSettings::GetEffectiveContentSandboxLevel(
    290    int32_t* aRetVal) {
    291  *aRetVal = mozilla::GetEffectiveContentSandboxLevel();
    292  return NS_OK;
    293 }
    294 
    295 NS_IMETHODIMP SandboxSettings::GetContentWin32kLockdownState(int32_t* aRetVal) {
    296  *aRetVal = static_cast<int32_t>(mozilla::GetContentWin32kLockdownState());
    297  return NS_OK;
    298 }
    299 
    300 NS_IMETHODIMP
    301 SandboxSettings::GetContentWin32kLockdownStateString(nsAString& aString) {
    302  nsIXULRuntime::ContentWin32kLockdownState lockdownState =
    303      mozilla::GetContentWin32kLockdownState();
    304  aString = NS_ConvertASCIItoUTF16(
    305      mozilla::ContentWin32kLockdownStateToString(lockdownState));
    306  return NS_OK;
    307 }
    308 
    309 }  // namespace mozilla
    310 
    311 NS_IMPL_COMPONENT_FACTORY(mozISandboxSettings) {
    312  return MakeAndAddRef<SandboxSettings>().downcast<nsISupports>();
    313 }