Index: content/common/sandbox_linux.cc |
diff --git a/content/common/sandbox_linux.cc b/content/common/sandbox_linux.cc |
index 20eedfaeebe5c4883cf774089f97778bf4d5f910..7d35403905de48e36b7c853aa30a84e3574a0725 100644 |
--- a/content/common/sandbox_linux.cc |
+++ b/content/common/sandbox_linux.cc |
@@ -23,6 +23,8 @@ |
#include "content/public/common/sandbox_linux.h" |
#include "sandbox/linux/suid/client/setuid_sandbox_client.h" |
+using content::LinuxSandbox; |
+ |
namespace { |
void LogSandboxStarted(const std::string& sandbox_name) { |
@@ -59,9 +61,9 @@ bool IsSeccompLegacyDesired() { |
// Our "policy" on whether or not to enable seccomp-legacy. Only renderers are |
// supported. |
-bool ShouldEnableSeccompLegacy(const std::string& process_type) { |
+bool ShouldEnableSeccompLegacy(LinuxSandbox::SandboxConfig sandbox_config) { |
if (IsSeccompLegacyDesired() && |
- process_type == switches::kRendererProcess) { |
+ sandbox_config == LinuxSandbox::SANDBOX_CONFIG_RENDERER) { |
return true; |
} else { |
return false; |
@@ -156,10 +158,10 @@ void LinuxSandbox::PreinitializeSandboxBegin() { |
// Once we finally know our process type, we can cleanup proc_fd_ |
// or pass it to seccomp-legacy. |
void LinuxSandbox::PreinitializeSandboxFinish( |
- const std::string& process_type) { |
+ LinuxSandbox::SandboxConfig sandbox_config) { |
CHECK(pre_initialized_); |
if (proc_fd_ >= 0) { |
- if (ShouldEnableSeccompLegacy(process_type)) { |
+ if (ShouldEnableSeccompLegacy(sandbox_config)) { |
#if defined(SECCOMP_SANDBOX) |
SeccompSandboxSetProcFd(proc_fd_); |
#endif |
@@ -171,9 +173,44 @@ void LinuxSandbox::PreinitializeSandboxFinish( |
} |
} |
-void LinuxSandbox::PreinitializeSandbox(const std::string& process_type) { |
+void LinuxSandbox::PreinitializeSandbox( |
+ LinuxSandbox::SandboxConfig sandbox_config) { |
PreinitializeSandboxBegin(); |
- PreinitializeSandboxFinish(process_type); |
+ PreinitializeSandboxFinish(sandbox_config); |
+} |
+ |
+bool LinuxSandbox::InitializeSandbox( |
+ enum LinuxSandbox::SandboxConfig sandbox_config) { |
+ bool seccomp_legacy_started = false; |
+ bool seccomp_bpf_started = false; |
+ LinuxSandbox* linux_sandbox = LinuxSandbox::GetInstance(); |
+ const std::string process_type = |
+ CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
+ switches::kProcessType); |
+ |
+ // No matter what, it's always an error to call InitializeSandbox() after |
+ // threads have been created. |
+ if (!linux_sandbox->IsSingleThreaded()) { |
+ std::string error_message = "InitializeSandbox() called with multiple " |
+ "threads in process " + process_type; |
+ // TODO(jln): change this into a CHECK() once we are more comfortable it |
+ // does not trigger. |
+ LOG(ERROR) << error_message; |
+ return false; |
+ } |
+ |
+ // Attempt to limit the future size of the address space of the process. |
+ linux_sandbox->LimitAddressSpace(sandbox_config); |
+ |
+ // First, try to enable seccomp-bpf. |
+ seccomp_bpf_started = linux_sandbox->StartSeccompBpf(sandbox_config); |
+ |
+ // If that fails, try to enable seccomp-legacy. |
+ if (!seccomp_bpf_started) { |
+ seccomp_legacy_started = linux_sandbox->StartSeccompLegacy(sandbox_config); |
+ } |
+ |
+ return seccomp_legacy_started || seccomp_bpf_started; |
} |
int LinuxSandbox::GetStatus() const { |
@@ -187,8 +224,8 @@ int LinuxSandbox::GetStatus() const { |
sandbox_flags |= kSandboxLinuxNetNS; |
} |
- if (seccomp_bpf_supported() && |
- SandboxSeccompBpf::ShouldEnableSeccompBpf(switches::kRendererProcess)) { |
+ if (seccomp_bpf_supported() && SandboxSeccompBpf::ShouldEnableSeccompBpf( |
+ LinuxSandbox::SANDBOX_CONFIG_RENDERER)) { |
// We report whether the sandbox will be activated when renderers go |
// through sandbox initialization. |
sandbox_flags |= kSandboxLinuxSeccompBpf; |
@@ -198,7 +235,7 @@ int LinuxSandbox::GetStatus() const { |
// or not enabled. |
if (!(sandbox_flags & kSandboxLinuxSeccompBpf) && |
seccomp_legacy_supported() && |
- ShouldEnableSeccompLegacy(switches::kRendererProcess)) { |
+ ShouldEnableSeccompLegacy(LinuxSandbox::SANDBOX_CONFIG_RENDERER)) { |
// Same here, what we report is what we will do for the renderer. |
sandbox_flags |= kSandboxLinuxSeccompLegacy; |
} |
@@ -234,10 +271,11 @@ sandbox::SetuidSandboxClient* |
} |
// For seccomp-legacy, we implement the policy inline, here. |
-bool LinuxSandbox::StartSeccompLegacy(const std::string& process_type) { |
+bool LinuxSandbox::StartSeccompLegacy( |
+ LinuxSandbox::SandboxConfig sandbox_config) { |
if (!pre_initialized_) |
- PreinitializeSandbox(process_type); |
- if (seccomp_legacy_supported() && ShouldEnableSeccompLegacy(process_type)) { |
+ PreinitializeSandbox(sandbox_config); |
+ if (seccomp_legacy_supported() && ShouldEnableSeccompLegacy(sandbox_config)) { |
// SupportsSeccompSandbox() returns a cached result, as we already |
// called it earlier in the PreinitializeSandbox(). Thus, it is OK for us |
// to not pass in a file descriptor for "/proc". |
@@ -253,12 +291,13 @@ bool LinuxSandbox::StartSeccompLegacy(const std::string& process_type) { |
} |
// For seccomp-bpf, we use the SandboxSeccompBpf class. |
-bool LinuxSandbox::StartSeccompBpf(const std::string& process_type) { |
+bool LinuxSandbox::StartSeccompBpf( |
+ LinuxSandbox::SandboxConfig sandbox_config) { |
CHECK(!seccomp_bpf_started_); |
if (!pre_initialized_) |
- PreinitializeSandbox(process_type); |
+ PreinitializeSandbox(sandbox_config); |
if (seccomp_bpf_supported()) |
- seccomp_bpf_started_ = SandboxSeccompBpf::StartSandbox(process_type); |
+ seccomp_bpf_started_ = SandboxSeccompBpf::StartSandbox(sandbox_config); |
if (seccomp_bpf_started_) |
LogSandboxStarted("seccomp-bpf"); |
@@ -276,8 +315,9 @@ bool LinuxSandbox::seccomp_bpf_supported() const { |
return seccomp_bpf_supported_; |
} |
-bool LinuxSandbox::LimitAddressSpace(const std::string& process_type) { |
- (void) process_type; |
+bool LinuxSandbox::LimitAddressSpace( |
+ LinuxSandbox::SandboxConfig sandbox_config) { |
+ (void) sandbox_config; |
#if !defined(ADDRESS_SANITIZER) |
CommandLine* command_line = CommandLine::ForCurrentProcess(); |
if (command_line->HasSwitch(switches::kNoSandbox)) { |
@@ -295,8 +335,8 @@ bool LinuxSandbox::LimitAddressSpace(const std::string& process_type) { |
// See crbug.com/169327 for a discussion. |
// For now, increase limit to 16GB for renderer and worker processes to |
// accomodate. |
- if (process_type == switches::kRendererProcess || |
- process_type == switches::kWorkerProcess) { |
+ if (sandbox_config == LinuxSandbox::SANDBOX_CONFIG_RENDERER || |
+ sandbox_config == LinuxSandbox::SANDBOX_CONFIG_WORKER) { |
address_space_limit = 1L << 34; |
} |
#endif // defined(__LP64__) |