Index: content/common/sandbox_linux/sandbox_linux.cc |
diff --git a/content/common/sandbox_linux/sandbox_linux.cc b/content/common/sandbox_linux/sandbox_linux.cc |
index 12e11d8e1312d1480cbf7e7bb8bc27e9760ef156..fd9bf1bdd095f4a5ca69aa463de43d68097367f7 100644 |
--- a/content/common/sandbox_linux/sandbox_linux.cc |
+++ b/content/common/sandbox_linux/sandbox_linux.cc |
@@ -11,6 +11,8 @@ |
#include <unistd.h> |
#include <limits> |
+#include <string> |
+#include <vector> |
#include "base/bind.h" |
#include "base/callback_helpers.h" |
@@ -90,10 +92,12 @@ int OpenProcTaskFd(int proc_fd) { |
if (proc_fd >= 0) { |
// If a handle to /proc is available, use it. This allows to bypass file |
// system restrictions. |
- proc_self_task = openat(proc_fd, "self/task/", O_RDONLY | O_DIRECTORY); |
+ proc_self_task = |
+ openat(proc_fd, "self/task/", O_RDONLY | O_DIRECTORY | O_CLOEXEC); |
} else { |
// Otherwise, make an attempt to access the file system directly. |
- proc_self_task = open("/proc/self/task/", O_RDONLY | O_DIRECTORY); |
+ proc_self_task = |
+ open("/proc/self/task/", O_RDONLY | O_DIRECTORY | O_CLOEXEC); |
} |
return proc_self_task; |
} |
@@ -144,12 +148,14 @@ void LinuxSandbox::PreinitializeSandbox() { |
// its contents before the sandbox is enabled. It also pre-opens the |
// object files that are already loaded in the process address space. |
base::debug::EnableInProcessStackDumpingForSandbox(); |
+#endif // !defined(NDEBUG) |
- // Open proc_fd_ only in Debug mode so that forgetting to close it doesn't |
- // produce a sandbox escape in Release mode. |
+ // Open proc_fd_. It would break the security of the setuid sandbox if it was |
+ // not closed. |
+ // If LinuxSandbox::PreinitializeSandbox() runs, InitializeSandbox() must run |
mdempsky
2014/11/24 21:58:23
Can we CHECK this in ~LinuxSandbox()?
jln (very slow on Chromium)
2014/11/24 22:45:48
Done.
|
+ // as well. |
proc_fd_ = open("/proc", O_DIRECTORY | O_RDONLY | O_CLOEXEC); |
CHECK_GE(proc_fd_, 0); |
-#endif // !defined(NDEBUG) |
// We "pre-warm" the code that detects supports for seccomp BPF. |
if (SandboxSeccompBPF::IsSeccompBPFDesired()) { |
if (!SandboxSeccompBPF::SupportsSandbox()) { |
@@ -167,6 +173,10 @@ void LinuxSandbox::PreinitializeSandbox() { |
pre_initialized_ = true; |
} |
+std::vector<int> LinuxSandbox::GetFileDescriptorsToClose() { |
+ return std::vector<int>{proc_fd_}; |
+} |
+ |
bool LinuxSandbox::InitializeSandbox() { |
LinuxSandbox* linux_sandbox = LinuxSandbox::GetInstance(); |
return linux_sandbox->InitializeSandboxImpl(); |
@@ -209,27 +219,14 @@ int LinuxSandbox::GetStatus() { |
// PID namespaces and existing sandboxes, so "self" must really be used instead |
// of using the pid. |
bool LinuxSandbox::IsSingleThreaded() const { |
- bool is_single_threaded = false; |
base::ScopedFD proc_self_task(OpenProcTaskFd(proc_fd_)); |
-// In Debug mode, it's mandatory to be able to count threads to catch bugs. |
-#if !defined(NDEBUG) |
- // Using CHECK here since we want to check all the cases where |
- // !defined(NDEBUG) |
- // gets built. |
CHECK(proc_self_task.is_valid()) |
<< "Could not count threads, the sandbox was not " |
<< "pre-initialized properly."; |
-#endif // !defined(NDEBUG) |
- if (!proc_self_task.is_valid()) { |
- // Pretend to be monothreaded if it can't be determined (for instance the |
- // setuid sandbox is already engaged but no proc_fd_ is available). |
- is_single_threaded = true; |
- } else { |
- is_single_threaded = |
- sandbox::ThreadHelpers::IsSingleThreaded(proc_self_task.get()); |
- } |
+ const bool is_single_threaded = |
+ sandbox::ThreadHelpers::IsSingleThreaded(proc_self_task.get()); |
return is_single_threaded; |
} |
@@ -247,11 +244,15 @@ sandbox::SetuidSandboxClient* |
bool LinuxSandbox::StartSeccompBPF(const std::string& process_type) { |
CHECK(!seccomp_bpf_started_); |
CHECK(pre_initialized_); |
- if (seccomp_bpf_supported()) |
- seccomp_bpf_started_ = SandboxSeccompBPF::StartSandbox(process_type); |
+ if (seccomp_bpf_supported()) { |
+ base::ScopedFD proc_self_task(OpenProcTaskFd(proc_fd_)); |
+ seccomp_bpf_started_ = |
+ SandboxSeccompBPF::StartSandbox(process_type, proc_self_task.Pass()); |
+ } |
- if (seccomp_bpf_started_) |
+ if (seccomp_bpf_started_) { |
LogSandboxStarted("seccomp-bpf"); |
+ } |
return seccomp_bpf_started_; |
} |