Commit c249254e authored by Alex Gough's avatar Alex Gough Committed by Chromium LUCI CQ

Turn off CET for renderer processes

Adds sandbox mitigation flag to disable CET.

As these currently crash in v8 we apply this for renderer processes.

For the default build this will have no effect as CET is not yet
enabled for any binaries. However, for builds with
`enable_cet_shadow_stack = true` or where users have configured CET by
setting an appropriate `Image File Execution Option` in the registry
it should be possible to run Chrome on CET capable hardware.

A sandbox integration test is added which checks this policy works. On
hardware without CET support the test exits early.

Both browser_tests and content_browser_tests pass at least the same set
of tests that pass with CET disabled on test hardware. Manual tests
confirm chrome works with and without cetcompat, and with and without
IFEO to force strict checks.

Bug: 1131225
Change-Id: Icaf8d3f039c924e937973b6c01239c1635d43790
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2542726
Commit-Queue: Alex Gough <ajgo@chromium.org>
Reviewed-by: default avatarWill Harris <wfh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#836692}
parent 9fb4a830
...@@ -153,6 +153,11 @@ const wchar_t* const kTroublesomeDlls[] = { ...@@ -153,6 +153,11 @@ const wchar_t* const kTroublesomeDlls[] = {
const base::Feature kEnableCsrssLockdownFeature{ const base::Feature kEnableCsrssLockdownFeature{
"EnableCsrssLockdown", base::FEATURE_DISABLED_BY_DEFAULT}; "EnableCsrssLockdown", base::FEATURE_DISABLED_BY_DEFAULT};
// This allows IFEO to be used to enable for chrome.exe. We normally
// disable for renderers but do not do so if this feature is set.
const base::Feature kCetForRenderer{"CetForRenderer",
base::FEATURE_DISABLED_BY_DEFAULT};
// Helps emit trace events for sandbox policy. This mediates memory between // Helps emit trace events for sandbox policy. This mediates memory between
// chrome.exe and chrome.dll. // chrome.exe and chrome.dll.
class PolicyTraceHelper : public base::trace_event::ConvertableToTraceFormat { class PolicyTraceHelper : public base::trace_event::ConvertableToTraceFormat {
...@@ -970,6 +975,11 @@ ResultCode SandboxWin::StartSandboxedProcess( ...@@ -970,6 +975,11 @@ ResultCode SandboxWin::StartSandboxedProcess(
MITIGATION_IMAGE_LOAD_NO_LOW_LABEL | MITIGATION_IMAGE_LOAD_NO_LOW_LABEL |
MITIGATION_RESTRICT_INDIRECT_BRANCH_PREDICTION; MITIGATION_RESTRICT_INDIRECT_BRANCH_PREDICTION;
if (sandbox_type == SandboxType::kRenderer &&
!base::FeatureList::IsEnabled(sandbox::policy::kCetForRenderer)) {
mitigations |= sandbox::MITIGATION_CET_DISABLED;
}
ResultCode result = policy->SetProcessMitigations(mitigations); ResultCode result = policy->SetProcessMitigations(mitigations);
if (result != SBOX_ALL_OK) if (result != SBOX_ALL_OK)
return result; return result;
......
...@@ -494,8 +494,7 @@ void ConvertProcessMitigationsToPolicy(MitigationFlags flags, ...@@ -494,8 +494,7 @@ void ConvertProcessMitigationsToPolicy(MitigationFlags flags,
// 2018 security updates and any applicable firmware updates from the // 2018 security updates and any applicable firmware updates from the
// OEM device manufacturer. // OEM device manufacturer.
// Note: Applying this mitigation attribute on creation will succeed, even // Note: Applying this mitigation attribute on creation will succeed, even
// if // if the underlying hardware does not support the implementation.
// the underlying hardware does not support the implementation.
// Windows just does its best under the hood for the given hardware. // Windows just does its best under the hood for the given hardware.
if (flags & MITIGATION_RESTRICT_INDIRECT_BRANCH_PREDICTION) { if (flags & MITIGATION_RESTRICT_INDIRECT_BRANCH_PREDICTION) {
*policy_value_2 |= *policy_value_2 |=
...@@ -503,6 +502,15 @@ void ConvertProcessMitigationsToPolicy(MitigationFlags flags, ...@@ -503,6 +502,15 @@ void ConvertProcessMitigationsToPolicy(MitigationFlags flags,
} }
} }
// Mitigations >= Win10 20H1
//----------------------------------------------------------------------------
if (version >= base::win::Version::WIN10_20H1) {
if (flags & MITIGATION_CET_DISABLED) {
*policy_value_2 |=
PROCESS_CREATION_MITIGATION_POLICY2_CET_USER_SHADOW_STACKS_ALWAYS_OFF;
}
}
// When done setting policy flags, sanity check supported policies on this // When done setting policy flags, sanity check supported policies on this
// machine, and then update |size|. // machine, and then update |size|.
......
...@@ -368,6 +368,22 @@ SBOX_TESTS_COMMAND int CheckPolicy(int argc, wchar_t** argv) { ...@@ -368,6 +368,22 @@ SBOX_TESTS_COMMAND int CheckPolicy(int argc, wchar_t** argv) {
// UpdateProcThreadAttribute() with this mitigation succeeded. // UpdateProcThreadAttribute() with this mitigation succeeded.
break; break;
} }
//--------------------------------------------------
// MITIGATION_CET_DISABLED
//--------------------------------------------------
case (TESTPOLICY_CETDISABLED): {
PROCESS_MITIGATION_USER_SHADOW_STACK_POLICY policy = {};
if (!get_process_mitigation_policy(::GetCurrentProcess(),
ProcessUserShadowStackPolicy, &policy,
sizeof(policy))) {
return SBOX_TEST_NOT_FOUND;
}
// We wish to disable the policy.
if (policy.EnableUserShadowStack)
return SBOX_TEST_FAILED;
break;
}
default: default:
return SBOX_TEST_INVALID_PARAMETER; return SBOX_TEST_INVALID_PARAMETER;
} }
...@@ -1057,4 +1073,53 @@ TEST(ProcessMitigationsTest, ...@@ -1057,4 +1073,53 @@ TEST(ProcessMitigationsTest,
//--------------------------------- //---------------------------------
} }
//------------------------------------------------------------------------------
// Hardware shadow stack / Control(flow) Enforcement Technology / CETCOMPAT
// (MITIGATION_CET_DISABLED)
// >= Win10 2004
//------------------------------------------------------------------------------
// This test validates that setting the
// MITIGATION_CET_DISABLED mitigation disables CET in child processes. The test
// only makes sense where the parent was launched with CET enabled, hence we
// bail out early on systems that do not support CET.
TEST(ProcessMitigationsTest, CetDisablePolicy) {
if (base::win::GetVersion() < base::win::Version::WIN10_20H1)
return;
// Verify policy is available and set for this process (i.e. CET is
// enabled via IFEO or through the CETCOMPAT bit on the executable).
auto get_process_mitigation_policy =
reinterpret_cast<decltype(&GetProcessMitigationPolicy)>(::GetProcAddress(
::GetModuleHandleA("kernel32.dll"), "GetProcessMitigationPolicy"));
PROCESS_MITIGATION_USER_SHADOW_STACK_POLICY uss_policy;
if (!get_process_mitigation_policy(GetCurrentProcess(),
ProcessUserShadowStackPolicy, &uss_policy,
sizeof(uss_policy))) {
return;
}
if (!uss_policy.EnableUserShadowStack)
return;
std::wstring test_command = L"CheckPolicy ";
test_command += std::to_wstring(TESTPOLICY_CETDISABLED);
//---------------------------------
// 1) Test setting pre-startup.
//---------------------------------
TestRunner runner;
sandbox::TargetPolicy* policy = runner.GetPolicy();
EXPECT_EQ(policy->SetProcessMitigations(MITIGATION_CET_DISABLED),
SBOX_ALL_OK);
EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(test_command.c_str()));
//---------------------------------
// 2) Test setting post-startup.
// ** Post-startup not supported. Must be enabled on creation.
//---------------------------------
}
} // namespace sandbox } // namespace sandbox
...@@ -287,6 +287,12 @@ const MitigationFlags MITIGATION_IMAGE_LOAD_PREFER_SYS32 = 0x00100000; ...@@ -287,6 +287,12 @@ const MitigationFlags MITIGATION_IMAGE_LOAD_PREFER_SYS32 = 0x00100000;
const MitigationFlags MITIGATION_RESTRICT_INDIRECT_BRANCH_PREDICTION = const MitigationFlags MITIGATION_RESTRICT_INDIRECT_BRANCH_PREDICTION =
0x00200000; 0x00200000;
// Turns off CET for the process. This allows chrome.exe to
// be turned 'on' using IFEO or through build settings but children we know to
// have issues can be turned off. Corresponds to
// PROCESS_CREATION_MITIGATION_POLICY2_CET_USER_SHADOW_STACKS_ALWAYS_OFF.
const MitigationFlags MITIGATION_CET_DISABLED = 0x00400000;
} // namespace sandbox } // namespace sandbox
#endif // SANDBOX_SRC_SECURITY_LEVEL_H_ #endif // SANDBOX_SRC_SECURITY_LEVEL_H_
...@@ -28,7 +28,8 @@ enum TestPolicy { ...@@ -28,7 +28,8 @@ enum TestPolicy {
TESTPOLICY_LOADNOLOW, TESTPOLICY_LOADNOLOW,
TESTPOLICY_DYNAMICCODEOPTOUT, TESTPOLICY_DYNAMICCODEOPTOUT,
TESTPOLICY_LOADPREFERSYS32, TESTPOLICY_LOADPREFERSYS32,
TESTPOLICY_RESTRICTINDIRECTBRANCHPREDICTION TESTPOLICY_RESTRICTINDIRECTBRANCHPREDICTION,
TESTPOLICY_CETDISABLED
}; };
// Timeout for ::WaitForSingleObject synchronization. // Timeout for ::WaitForSingleObject synchronization.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment