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 }