diff --git a/security/sandbox/common/SandboxSettings.cpp b/security/sandbox/common/SandboxSettings.cpp index 808c616df9d5..5409883ad80f 100644 --- a/security/sandbox/common/SandboxSettings.cpp +++ b/security/sandbox/common/SandboxSettings.cpp @@ -17,7 +17,7 @@ #ifdef XP_WIN # include "mozilla/gfx/gfxVars.h" # include "mozilla/WindowsVersion.h" - +# include "nsExceptionHandler.h" #endif // XP_WIN using namespace mozilla; @@ -46,28 +46,37 @@ const char* ContentWin32kLockdownStateToString( ContentWin32kLockdownState GetContentWin32kLockdownState() { #ifdef XP_WIN static ContentWin32kLockdownState result = [] { - if (!IsWin8OrLater()) { - return ContentWin32kLockdownState::OperatingSystemNotSupported; - } + ContentWin32kLockdownState state = [] { + if (!IsWin8OrLater()) { + return ContentWin32kLockdownState::OperatingSystemNotSupported; + } - // Win32k Lockdown requires WebRender, but WR is not currently guaranteed - // on all computers. It can also fail to initialize and fallback to - // non-WR render path. - // - // We don't want a situation where "Win32k Lockdown + No WR" occurs - // without the user explicitly requesting unsupported behavior. - if (!gfx::gfxVars::UseWebRender()) { - return ContentWin32kLockdownState::MissingWebRender; - } + // Win32k Lockdown requires WebRender, but WR is not currently guaranteed + // on all computers. It can also fail to initialize and fallback to + // non-WR render path. + // + // We don't want a situation where "Win32k Lockdown + No WR" occurs + // without the user explicitly requesting unsupported behavior. + if (!gfx::gfxVars::UseWebRender()) { + return ContentWin32kLockdownState::MissingWebRender; + } - // It's important that this goes last, as we'd like to know in - // telemetry and crash reporting if the only thing holding the user - // back from Win32k Lockdown is the-lack-of-asking-for-it - if (!StaticPrefs::security_sandbox_content_win32k_disable()) { - return ContentWin32kLockdownState::PrefNotSet; - } + // It's important that this goes last, as we'd like to know in + // telemetry and crash reporting if the only thing holding the user + // back from Win32k Lockdown is the-lack-of-asking-for-it + if (!StaticPrefs::security_sandbox_content_win32k_disable()) { + return ContentWin32kLockdownState::PrefNotSet; + } - return ContentWin32kLockdownState::LockdownEnabled; + return ContentWin32kLockdownState::LockdownEnabled; + }(); + + const char* stateStr = ContentWin32kLockdownStateToString(state); + CrashReporter::AnnotateCrashReport( + CrashReporter::Annotation::ContentSandboxWin32kState, + nsDependentCString(stateStr)); + + return state; }(); return result; @@ -149,6 +158,20 @@ NS_IMETHODIMP SandboxSettings::GetEffectiveContentSandboxLevel( return NS_OK; } +NS_IMETHODIMP SandboxSettings::GetContentWin32kLockdownState(int32_t* aRetVal) { + *aRetVal = static_cast(mozilla::GetContentWin32kLockdownState()); + return NS_OK; +} + +NS_IMETHODIMP +SandboxSettings::GetContentWin32kLockdownStateString(nsAString& aString) { + ContentWin32kLockdownState lockdownState = + mozilla::GetContentWin32kLockdownState(); + aString = NS_ConvertASCIItoUTF16( + mozilla::ContentWin32kLockdownStateToString(lockdownState)); + return NS_OK; +} + } // namespace mozilla NS_IMPL_COMPONENT_FACTORY(mozISandboxSettings) { diff --git a/security/sandbox/common/mozISandboxSettings.idl b/security/sandbox/common/mozISandboxSettings.idl index 0e2a879c2b47..98498b4ea3f0 100644 --- a/security/sandbox/common/mozISandboxSettings.idl +++ b/security/sandbox/common/mozISandboxSettings.idl @@ -12,6 +12,13 @@ interface mozISandboxSettings : nsISupports { readonly attribute long effectiveContentSandboxLevel; + + /* + * The possible values for this are defined in the ContentWin32kLockdownState + * enum in security/sandbox/common/SandboxSettings.h + */ + readonly attribute long contentWin32kLockdownState; + readonly attribute AString contentWin32kLockdownStateString; }; %{ C++ diff --git a/toolkit/components/telemetry/app/TelemetryEnvironment.jsm b/toolkit/components/telemetry/app/TelemetryEnvironment.jsm index fd9a57543705..adef5747f120 100644 --- a/toolkit/components/telemetry/app/TelemetryEnvironment.jsm +++ b/toolkit/components/telemetry/app/TelemetryEnvironment.jsm @@ -1595,15 +1595,27 @@ EnvironmentCache.prototype = { _getSandboxData() { let effectiveContentProcessLevel = null; + let contentWin32kLockdownState = null; try { let sandboxSettings = Cc[ "@mozilla.org/sandbox/sandbox-settings;1" ].getService(Ci.mozISandboxSettings); effectiveContentProcessLevel = sandboxSettings.effectiveContentSandboxLevel; + + // See `ContentWin32kLockdownState` in + // + // + // Values: + // 1 = LockdownEnabled + // 2 = MissingWebRender + // 3 = OperatingSystemNotSupported + // 4 = PrefNotSet + contentWin32kLockdownState = sandboxSettings.contentWin32kLockdownState; } catch (e) {} return { effectiveContentProcessLevel, + contentWin32kLockdownState, }; }, diff --git a/toolkit/components/telemetry/docs/data/environment.rst b/toolkit/components/telemetry/docs/data/environment.rst index bd378a7b458e..f7d228312d56 100644 --- a/toolkit/components/telemetry/docs/data/environment.rst +++ b/toolkit/components/telemetry/docs/data/environment.rst @@ -88,6 +88,7 @@ Structure: }, sandbox: { effectiveContentProcessLevel: , + contentWin32kLockdownState: , } }, // Optional, missing if fetching the information failed or had not yet completed. @@ -419,6 +420,7 @@ This object contains data about the state of Firefox's sandbox. Specific keys are: - ``effectiveContentProcessLevel``: The meanings of the values are OS dependent. Details of the meanings can be found in the `Firefox prefs file `_. The value here is the effective value, not the raw value, some platforms enforce a minimum sandbox level. If there is an error calculating this, it will be ``null``. +- ``contentWin32kLockdownState``: The status of Win32k Lockdown for Content process. 1 = "Lockdown enabled", 2 = "Lockdown disabled -- Missing WebRender", 3 = "Lockdown disabled -- Unsupported OS", 4 = "Lockdown disabled -- User pref not set". If there is an error calculating this, it will be ``null``. profile ------- diff --git a/toolkit/components/telemetry/tests/unit/TelemetryEnvironmentTesting.jsm b/toolkit/components/telemetry/tests/unit/TelemetryEnvironmentTesting.jsm index 8ded9a19179f..ebad8f593968 100644 --- a/toolkit/components/telemetry/tests/unit/TelemetryEnvironmentTesting.jsm +++ b/toolkit/components/telemetry/tests/unit/TelemetryEnvironmentTesting.jsm @@ -299,6 +299,21 @@ var TelemetryEnvironmentTesting = { Assert.equal(typeof update.autoDownload, "boolean"); Assert.equal(typeof update.background, "boolean"); + // Check sandbox settings exist and make sense + Assert.equal( + typeof data.settings.sandbox.effectiveContentProcessLevel, + "number", + "sandbox.effectiveContentProcessLevel must have the correct type" + ); + Assert.equal( + typeof data.settings.sandbox.contentWin32kLockdownState, + "number", + "sandbox.contentWin32kLockdownState must have the correct type" + ); + + let win32kLockdownState = data.settings.sandbox.contentWin32kLockdownState; + Assert.ok(win32kLockdownState >= 1 && win32kLockdownState <= 4); + // Check "defaultSearchEngine" separately, as it can either be undefined or string. if ("defaultSearchEngine" in data.settings) { this.checkString(data.settings.defaultSearchEngine); diff --git a/toolkit/crashreporter/CrashAnnotations.yaml b/toolkit/crashreporter/CrashAnnotations.yaml index 8d993ba58654..3297f3468db4 100644 --- a/toolkit/crashreporter/CrashAnnotations.yaml +++ b/toolkit/crashreporter/CrashAnnotations.yaml @@ -230,6 +230,11 @@ ContentSandboxLevel: Content sandbox level. type: integer +ContentSandboxWin32kState: + description: > + Content sandbox Win32k state + type: string + CoUnmarshalInterfaceResult: description: > Annotation describing the error returned by trying to unmarshal an object diff --git a/toolkit/locales/en-US/toolkit/about/aboutSupport.ftl b/toolkit/locales/en-US/toolkit/about/aboutSupport.ftl index 2140838fec0a..be0d9bc11f6a 100644 --- a/toolkit/locales/en-US/toolkit/about/aboutSupport.ftl +++ b/toolkit/locales/en-US/toolkit/about/aboutSupport.ftl @@ -343,6 +343,7 @@ can-sandbox-content = Content Process Sandboxing can-sandbox-media = Media Plugin Sandboxing content-sandbox-level = Content Process Sandbox Level effective-content-sandbox-level = Effective Content Process Sandbox Level +content-win32k-lockdown-state = Win32k Lockdown State for Content Process sandbox-proc-type-content = content sandbox-proc-type-file = file content sandbox-proc-type-media-plugin = media plugin diff --git a/toolkit/modules/Troubleshoot.jsm b/toolkit/modules/Troubleshoot.jsm index 3a96aa466b0d..5ecc6912dd85 100644 --- a/toolkit/modules/Troubleshoot.jsm +++ b/toolkit/modules/Troubleshoot.jsm @@ -1001,6 +1001,8 @@ if (AppConstants.MOZ_SANDBOX) { ); data.effectiveContentSandboxLevel = sandboxSettings.effectiveContentSandboxLevel; + data.contentWin32kLockdownState = + sandboxSettings.contentWin32kLockdownStateString; } done(data); diff --git a/toolkit/modules/tests/browser/browser_Troubleshoot.js b/toolkit/modules/tests/browser/browser_Troubleshoot.js index 0d2096bda8d6..cbb249366430 100644 --- a/toolkit/modules/tests/browser/browser_Troubleshoot.js +++ b/toolkit/modules/tests/browser/browser_Troubleshoot.js @@ -1000,6 +1000,10 @@ const SNAPSHOT_SCHEMA = { required: AppConstants.MOZ_SANDBOX, type: "number", }, + contentWin32kLockdownState: { + required: AppConstants.MOZ_SANDBOX, + type: "string", + }, syscallLog: { required: AppConstants.platform == "linux", type: "array",