Bug 1751494 - Move win32k logic from sandbox to apprunner r=bobowen

Differential Revision: https://phabricator.services.mozilla.com/D137324
This commit is contained in:
Tom Ritter 2022-02-02 16:33:11 +00:00
parent 6013bc9b5a
commit d59df896db
5 changed files with 155 additions and 128 deletions

View File

@ -6,7 +6,6 @@
#include "mozilla/SandboxSettings.h"
#include "mozISandboxSettings.h"
#include "nsIXULRuntime.h"
#include "nsServiceManagerUtils.h"
#include "mozilla/Components.h"
@ -28,142 +27,73 @@ using namespace mozilla;
namespace mozilla {
const char* ContentWin32kLockdownStateToString(
ContentWin32kLockdownState aValue) {
nsIXULRuntime::ContentWin32kLockdownState aValue) {
switch (aValue) {
case ContentWin32kLockdownState::LockdownEnabled:
case nsIXULRuntime::ContentWin32kLockdownState::LockdownEnabled:
return "Win32k Lockdown enabled";
case ContentWin32kLockdownState::MissingWebRender:
case nsIXULRuntime::ContentWin32kLockdownState::MissingWebRender:
return "Win32k Lockdown disabled -- Missing WebRender";
case ContentWin32kLockdownState::OperatingSystemNotSupported:
case nsIXULRuntime::ContentWin32kLockdownState::OperatingSystemNotSupported:
return "Win32k Lockdown disabled -- Operating system not supported";
case ContentWin32kLockdownState::PrefNotSet:
case nsIXULRuntime::ContentWin32kLockdownState::PrefNotSet:
return "Win32k Lockdown disabled -- Preference not set";
case ContentWin32kLockdownState::MissingRemoteWebGL:
case nsIXULRuntime::ContentWin32kLockdownState::MissingRemoteWebGL:
return "Win32k Lockdown disabled -- Missing Remote WebGL";
case ContentWin32kLockdownState::MissingNonNativeTheming:
case nsIXULRuntime::ContentWin32kLockdownState::MissingNonNativeTheming:
return "Win32k Lockdown disabled -- Missing Non-Native Theming";
case ContentWin32kLockdownState::DisabledByEnvVar:
case nsIXULRuntime::ContentWin32kLockdownState::DisabledByEnvVar:
return "Win32k Lockdown disabled -- MOZ_ENABLE_WIN32K is set";
case ContentWin32kLockdownState::DisabledBySafeMode:
case nsIXULRuntime::ContentWin32kLockdownState::DisabledBySafeMode:
return "Win32k Lockdown disabled -- Running in Safe Mode";
case ContentWin32kLockdownState::DisabledByE10S:
case nsIXULRuntime::ContentWin32kLockdownState::DisabledByE10S:
return "Win32k Lockdown disabled -- E10S is disabled";
case ContentWin32kLockdownState::DisabledByUserPref:
case nsIXULRuntime::ContentWin32kLockdownState::DisabledByUserPref:
return "Win32k Lockdown disabled -- manually set "
"security.sandbox.content.win32k-disable to false";
case ContentWin32kLockdownState::EnabledByUserPref:
case nsIXULRuntime::ContentWin32kLockdownState::EnabledByUserPref:
return "Win32k Lockdown enabled -- manually set "
"security.sandbox.content.win32k-disable to true";
case ContentWin32kLockdownState::DisabledByControlGroup:
case nsIXULRuntime::ContentWin32kLockdownState::DisabledByControlGroup:
return "Win32k Lockdown disabled -- user in Control Group";
case ContentWin32kLockdownState::EnabledByTreatmentGroup:
case nsIXULRuntime::ContentWin32kLockdownState::EnabledByTreatmentGroup:
return "Win32k Lockdown enabled -- user in Treatment Group";
case ContentWin32kLockdownState::DisabledByDefault:
case nsIXULRuntime::ContentWin32kLockdownState::DisabledByDefault:
return "Win32k Lockdown disabled -- default value is false";
case ContentWin32kLockdownState::EnabledByDefault:
case nsIXULRuntime::ContentWin32kLockdownState::EnabledByDefault:
return "Win32k Lockdown enabled -- default value is true";
}
MOZ_CRASH("Should never reach here");
}
bool InSafeMode() {
static bool sSafeModeInitialized = false;
static bool sInSafeMode = false;
if (!sSafeModeInitialized) {
sSafeModeInitialized = true;
nsCOMPtr<nsIXULRuntime> xr = do_GetService("@mozilla.org/xre/runtime;1");
if (xr) {
xr->GetInSafeMode(&sInSafeMode);
} else {
MOZ_CRASH("could not get service");
}
}
return sInSafeMode;
bool GetContentWin32kLockdownEnabled() {
auto state = GetContentWin32kLockdownState();
return state ==
nsIXULRuntime::ContentWin32kLockdownState::EnabledByUserPref ||
state == nsIXULRuntime::ContentWin32kLockdownState::
EnabledByTreatmentGroup ||
state == nsIXULRuntime::ContentWin32kLockdownState::EnabledByDefault;
}
ContentWin32kLockdownState GetContentWin32kLockdownState() {
nsIXULRuntime::ContentWin32kLockdownState GetContentWin32kLockdownState() {
#ifdef XP_WIN
static ContentWin32kLockdownState result = [] {
ContentWin32kLockdownState state = [] {
if (InSafeMode()) {
return ContentWin32kLockdownState::DisabledBySafeMode;
}
if (PR_GetEnv("MOZ_ENABLE_WIN32K")) {
return ContentWin32kLockdownState::DisabledByEnvVar;
}
if (!mozilla::BrowserTabsRemoteAutostart()) {
return ContentWin32kLockdownState::DisabledByE10S;
}
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;
}
// Non-native theming is required as well
if (!StaticPrefs::widget_non_native_theme_enabled()) {
return ContentWin32kLockdownState::MissingNonNativeTheming;
}
// Win32k Lockdown requires Remote WebGL, but it may be disabled on
// certain hardware or virtual machines.
if (!gfx::gfxVars::AllowWebglOop() ||
!StaticPrefs::webgl_out_of_process()) {
return ContentWin32kLockdownState::MissingRemoteWebGL;
}
bool prefSetByUser =
Preferences::HasUserValue("security.sandbox.content.win32k-disable");
bool prefValue =
Preferences::GetBool("security.sandbox.content.win32k-disable", false,
PrefValueKind::User);
bool defaultValue =
Preferences::GetBool("security.sandbox.content.win32k-disable", false,
PrefValueKind::Default);
if (prefSetByUser) {
if (prefValue) {
return ContentWin32kLockdownState::EnabledByUserPref;
} else {
return ContentWin32kLockdownState::DisabledByUserPref;
}
}
// enrollment pref
if (defaultValue) {
return ContentWin32kLockdownState::EnabledByDefault;
} else {
return ContentWin32kLockdownState::DisabledByDefault;
}
}();
static auto getLockdownState = [] {
auto state = GetWin32kLockdownState();
const char* stateStr = ContentWin32kLockdownStateToString(state);
CrashReporter::AnnotateCrashReport(
@ -171,13 +101,14 @@ ContentWin32kLockdownState GetContentWin32kLockdownState() {
nsDependentCString(stateStr));
return state;
}();
};
static nsIXULRuntime::ContentWin32kLockdownState result = getLockdownState();
return result;
#else // XP_WIN
return ContentWin32kLockdownState::OperatingSystemNotSupported;
return nsIXULRuntime::ContentWin32kLockdownState::OperatingSystemNotSupported;
#endif // XP_WIN
}
@ -259,7 +190,7 @@ NS_IMETHODIMP SandboxSettings::GetContentWin32kLockdownState(int32_t* aRetVal) {
NS_IMETHODIMP
SandboxSettings::GetContentWin32kLockdownStateString(nsAString& aString) {
ContentWin32kLockdownState lockdownState =
nsIXULRuntime::ContentWin32kLockdownState lockdownState =
mozilla::GetContentWin32kLockdownState();
aString = NS_ConvertASCIItoUTF16(
mozilla::ContentWin32kLockdownStateToString(lockdownState));

View File

@ -7,6 +7,8 @@
#define mozilla_SandboxSettings_h
#include <cinttypes>
#include "nsIXULRuntime.h"
#ifdef __OpenBSD__
# include "nsXULAppAPI.h"
#endif
@ -23,35 +25,12 @@ int GetEffectiveSocketProcessSandboxLevel();
// Checks whether the effective content sandbox level is > 0.
bool IsContentSandboxEnabled();
// If you update this enum, don't forget to raise the limit in
// TelemetryEnvironmentTesting.jsm and record the new value in
// environment.rst
enum class ContentWin32kLockdownState : int32_t {
LockdownEnabled = 1, // no longer used
MissingWebRender = 2,
OperatingSystemNotSupported = 3,
PrefNotSet = 4, // no longer used
MissingRemoteWebGL = 5,
MissingNonNativeTheming = 6,
DisabledByEnvVar = 7, // - MOZ_ENABLE_WIN32K is set
DisabledBySafeMode = 8,
DisabledByE10S = 9, // - E10S is disabled for whatever reason
DisabledByUserPref = 10, // - The user manually set
// security.sandbox.content.win32k-disable to false
EnabledByUserPref = 11, // The user manually set
// security.sandbox.content.win32k-disable to true
DisabledByControlGroup =
12, // The user is in the Control Group, so it is disabled
EnabledByTreatmentGroup =
13, // The user is in the Treatment Group, so it is enabled
DisabledByDefault = 14, // The default value of the pref is false
EnabledByDefault = 15 // The default value of the pref is true
};
const char* ContentWin32kLockdownStateToString(
ContentWin32kLockdownState aValue);
nsIXULRuntime::ContentWin32kLockdownState aValue);
ContentWin32kLockdownState GetContentWin32kLockdownState();
bool GetContentWin32kLockdownEnabled();
nsIXULRuntime::ContentWin32kLockdownState GetContentWin32kLockdownState();
#if defined(XP_MACOSX)
int ClampFlashSandboxLevel(const int aLevel);

View File

@ -31,6 +31,7 @@
#include "nsDirectoryServiceDefs.h"
#include "nsIFile.h"
#include "nsIProperties.h"
#include "nsIXULRuntime.h"
#include "nsServiceManagerUtils.h"
#include "nsString.h"
#include "nsTHashtable.h"
@ -684,13 +685,13 @@ void SandboxBroker::SetSecurityLevelForContentProcess(int32_t aSandboxLevel,
MOZ_RELEASE_ASSERT(sandbox::SBOX_ALL_OK == result,
"Invalid flags for SetProcessMitigations.");
ContentWin32kLockdownState win32kLockdownState =
nsIXULRuntime::ContentWin32kLockdownState win32kLockdownState =
GetContentWin32kLockdownState();
LOG_W("Win32k Lockdown State: '%s'",
ContentWin32kLockdownStateToString(win32kLockdownState));
if (win32kLockdownState == ContentWin32kLockdownState::LockdownEnabled) {
if (GetContentWin32kLockdownEnabled()) {
result = AddWin32kLockdownPolicy(mPolicy, false);
MOZ_RELEASE_ASSERT(result == sandbox::SBOX_ALL_OK,
"Failed to add the win32k lockdown policy");

View File

@ -25,10 +25,13 @@
#include "mozilla/ScopeExit.h"
#include "mozilla/StaticPrefs_browser.h"
#include "mozilla/StaticPrefs_fission.h"
#include "mozilla/StaticPrefs_webgl.h"
#include "mozilla/StaticPrefs_widget.h"
#include "mozilla/Telemetry.h"
#include "mozilla/Utf8.h"
#include "mozilla/intl/LocaleService.h"
#include "mozilla/JSONWriter.h"
#include "mozilla/gfx/gfxVars.h"
#include "BaseProfiler.h"
#include "nsAppRunner.h"
@ -590,6 +593,84 @@ bool BrowserTabsRemoteAutostart() {
return gBrowserTabsRemoteAutostart;
}
// Win32k Infrastructure ==============================================
namespace mozilla {
nsIXULRuntime::ContentWin32kLockdownState GetWin32kLockdownState() {
#ifdef XP_WIN
// HasUserValue The Pref functions can only be called on main thread
MOZ_ASSERT(NS_IsMainThread());
if (gSafeMode) {
return nsIXULRuntime::ContentWin32kLockdownState::DisabledBySafeMode;
}
if (EnvHasValue("MOZ_ENABLE_WIN32K")) {
return nsIXULRuntime::ContentWin32kLockdownState::DisabledByEnvVar;
}
if (!mozilla::BrowserTabsRemoteAutostart()) {
return nsIXULRuntime::ContentWin32kLockdownState::DisabledByE10S;
}
if (!IsWin8OrLater()) {
return nsIXULRuntime::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 nsIXULRuntime::ContentWin32kLockdownState::MissingWebRender;
}
// Non-native theming is required as well
if (!StaticPrefs::widget_non_native_theme_enabled()) {
return nsIXULRuntime::ContentWin32kLockdownState::MissingNonNativeTheming;
}
// Win32k Lockdown requires Remote WebGL, but it may be disabled on
// certain hardware or virtual machines.
if (!gfx::gfxVars::AllowWebglOop() || !StaticPrefs::webgl_out_of_process()) {
return nsIXULRuntime::ContentWin32kLockdownState::MissingRemoteWebGL;
}
bool prefSetByUser =
Preferences::HasUserValue("security.sandbox.content.win32k-disable");
bool prefValue = Preferences::GetBool(
"security.sandbox.content.win32k-disable", false, PrefValueKind::User);
bool defaultValue = Preferences::GetBool(
"security.sandbox.content.win32k-disable", false, PrefValueKind::Default);
if (prefSetByUser) {
if (prefValue) {
return nsIXULRuntime::ContentWin32kLockdownState::EnabledByUserPref;
} else {
return nsIXULRuntime::ContentWin32kLockdownState::DisabledByUserPref;
}
}
if (defaultValue) {
return nsIXULRuntime::ContentWin32kLockdownState::EnabledByDefault;
} else {
return nsIXULRuntime::ContentWin32kLockdownState::DisabledByDefault;
}
#else
return nsIXULRuntime::ContentWin32kLockdownState::OperatingSystemNotSupported;
#endif
}
} // namespace mozilla
// End Win32k Infrastructure ==========================================
bool FissionExperimentEnrolled() {
MOZ_ASSERT(XRE_IsParentProcess());
return gFissionExperimentStatus == nsIXULRuntime::eExperimentStatusControl ||

View File

@ -72,6 +72,30 @@ interface nsIXULRuntime : nsISupports
eExperimentStatusCount,
};
// If you update this enum, don't forget to raise the limit in
// TelemetryEnvironmentTesting.jsm and record the new value in
// environment.rst
cenum ContentWin32kLockdownState : 8 {
LockdownEnabled = 1, // no longer used
MissingWebRender = 2,
OperatingSystemNotSupported = 3,
PrefNotSet = 4, // no longer used
MissingRemoteWebGL = 5,
MissingNonNativeTheming = 6,
DisabledByEnvVar = 7, // - MOZ_ENABLE_WIN32K is set
DisabledBySafeMode = 8,
DisabledByE10S = 9, // - E10S is disabled for whatever reason
DisabledByUserPref = 10, // - The user manually set
// security.sandbox.content.win32k-disable to false
EnabledByUserPref = 11, // The user manually set
// security.sandbox.content.win32k-disable to true
DisabledByControlGroup =
12, // The user is in the Control Group, so it is disabled
EnabledByTreatmentGroup =
13, // The user is in the Treatment Group, so it is enabled
DisabledByDefault = 14, // The default value of the pref is false
EnabledByDefault = 15 // The default value of the pref is true
};
// NOTE: Please do not add new values to this enum without also updating the
// mapping in aboutSupport.js
cenum FissionDecisionStatus : 8 {
@ -351,3 +375,14 @@ interface nsIXULRuntime : nsISupports
*/
readonly attribute ACString lastAppBuildID;
};
%{C++
namespace mozilla {
nsIXULRuntime::ContentWin32kLockdownState GetWin32kLockdownState();
}
%}