0

Enable ACG for browser process behind a flag.

This uses ACG with thread opt-out as the launcher thread needs
to be able to write the sandbox intercepts into the child process
which would normally be blocked.

BUG=851565

Change-Id: I5e24c156700037fdd2f7849f4ce0210f01207f0d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1713906
Commit-Queue: Will Harris <wfh@chromium.org>
Reviewed-by: Avi Drissman <avi@chromium.org>
Reviewed-by: James Forshaw <forshaw@chromium.org>
Cr-Commit-Position: refs/heads/master@{#691459}
This commit is contained in:
Will Harris
2019-08-29 03:09:55 +00:00
committed by Commit Bot
parent dab51341e8
commit 4bed2eb502
2 changed files with 34 additions and 3 deletions
content/browser
sandbox/win/src

@ -202,6 +202,7 @@
#if defined(OS_WIN)
#include "media/device_monitors/system_message_window_win.h"
#include "sandbox/win/src/process_mitigations.h"
#elif defined(OS_LINUX) && defined(USE_UDEV)
#include "media/device_monitors/device_monitor_udev.h"
#elif defined(OS_MACOSX)
@ -388,6 +389,15 @@ mojo::PendingRemote<data_decoder::mojom::BleScanParser> GetBleScanParser() {
}
#endif // defined(OS_CHROMEOS)
#if defined(OS_WIN)
// Disable dynamic code using ACG. Prevents the browser process from generating
// dynamic code or modifying executable code. See comments in
// sandbox/win/src/security_level.h. Only available on Windows 10 RS1 (1607,
// Build 14393) onwards.
const base::Feature kBrowserDynamicCodeDisabled{
"BrowserDynamicCodeDisabled", base::FEATURE_DISABLED_BY_DEFAULT};
#endif // defined(OS_WIN)
} // namespace
#if defined(USE_X11)
@ -637,6 +647,15 @@ int BrowserMainLoop::EarlyInitialization() {
InitDefaultJob();
#endif
#if defined(OS_WIN)
if (!parsed_command_line_.HasSwitch(switches::kSingleProcess)) {
if (base::FeatureList::IsEnabled(kBrowserDynamicCodeDisabled)) {
sandbox::ApplyProcessMitigationsToCurrentProcess(
sandbox::MITIGATION_DYNAMIC_CODE_DISABLE_WITH_OPT_OUT);
}
}
#endif
if (parsed_command_line_.HasSwitch(switches::kRendererProcessLimit)) {
std::string limit_string = parsed_command_line_.GetSwitchValueASCII(
switches::kRendererProcessLimit);

@ -282,15 +282,27 @@ ResultCode BrokerServicesBase::SpawnTarget(const wchar_t* exe_path,
return SBOX_ERROR_BAD_PARAMS;
// Even though the resources touched by SpawnTarget can be accessed in
// multiple threads, the method itself cannot be called from more than
// 1 thread. This is to protect the global variables used while setting up
// the child process.
// multiple threads, the method itself cannot be called from more than one
// thread. This is to protect the global variables used while setting up the
// child process, and to make sure launcher thread mitigations are applied
// correctly.
static DWORD thread_id = ::GetCurrentThreadId();
DCHECK(thread_id == ::GetCurrentThreadId());
*last_warning = SBOX_ALL_OK;
AutoLock lock(&lock_);
// Launcher thread only needs to be opted out of ACG once. Do this on the
// first child process being spawned.
static bool launcher_thread_opted_out = false;
if (!launcher_thread_opted_out) {
// Soft fail this call. It will fail if ACG is not enabled for this process.
sandbox::ApplyMitigationsToCurrentThread(
sandbox::MITIGATION_DYNAMIC_CODE_OPT_OUT_THIS_THREAD);
launcher_thread_opted_out = true;
}
// This downcast is safe as long as we control CreatePolicy()
scoped_refptr<PolicyBase> policy_base(static_cast<PolicyBase*>(policy.get()));