summaryrefslogtreecommitdiff
path: root/chromium/content/browser/zygote_host/zygote_host_impl_linux.cc
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2015-06-18 14:10:49 +0200
committerOswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>2015-06-18 13:53:24 +0000
commit813fbf95af77a531c57a8c497345ad2c61d475b3 (patch)
tree821b2c8de8365f21b6c9ba17a236fb3006a1d506 /chromium/content/browser/zygote_host/zygote_host_impl_linux.cc
parentaf6588f8d723931a298c995fa97259bb7f7deb55 (diff)
downloadqtwebengine-chromium-813fbf95af77a531c57a8c497345ad2c61d475b3.tar.gz
BASELINE: Update chromium to 44.0.2403.47
Change-Id: Ie056fedba95cf5e5c76b30c4b2c80fca4764aa2f Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
Diffstat (limited to 'chromium/content/browser/zygote_host/zygote_host_impl_linux.cc')
-rw-r--r--chromium/content/browser/zygote_host/zygote_host_impl_linux.cc106
1 files changed, 73 insertions, 33 deletions
diff --git a/chromium/content/browser/zygote_host/zygote_host_impl_linux.cc b/chromium/content/browser/zygote_host/zygote_host_impl_linux.cc
index c2f1c908c0a..3506207247e 100644
--- a/chromium/content/browser/zygote_host/zygote_host_impl_linux.cc
+++ b/chromium/content/browser/zygote_host/zygote_host_impl_linux.cc
@@ -22,6 +22,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "base/metrics/histogram.h"
+#include "base/metrics/sparse_histogram.h"
#include "base/path_service.h"
#include "base/posix/eintr_wrapper.h"
#include "base/posix/unix_domain_socket_linux.h"
@@ -38,7 +39,10 @@
#include "content/public/browser/content_browser_client.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/result_codes.h"
-#include "sandbox/linux/suid/client/setuid_sandbox_client.h"
+#include "sandbox/linux/services/credentials.h"
+#include "sandbox/linux/services/namespace_sandbox.h"
+#include "sandbox/linux/services/namespace_utils.h"
+#include "sandbox/linux/suid/client/setuid_sandbox_host.h"
#include "sandbox/linux/suid/common/sandbox.h"
#include "ui/base/ui_base_switches.h"
#include "ui/gfx/switches.h"
@@ -49,12 +53,14 @@
namespace content {
+namespace {
+
// Receive a fixed message on fd and return the sender's PID.
// Returns true if the message received matches the expected message.
-static bool ReceiveFixedMessage(int fd,
- const char* expect_msg,
- size_t expect_len,
- base::ProcessId* sender_pid) {
+bool ReceiveFixedMessage(int fd,
+ const char* expect_msg,
+ size_t expect_len,
+ base::ProcessId* sender_pid) {
char buf[expect_len + 1];
ScopedVector<base::ScopedFD> fds_vec;
@@ -69,6 +75,8 @@ static bool ReceiveFixedMessage(int fd,
return true;
}
+} // namespace
+
// static
ZygoteHost* ZygoteHost::GetInstance() {
return ZygoteHostImpl::GetInstance();
@@ -79,7 +87,7 @@ ZygoteHostImpl::ZygoteHostImpl()
control_lock_(),
pid_(-1),
init_(false),
- using_suid_sandbox_(false),
+ use_suid_sandbox_for_adj_oom_score_(false),
sandbox_binary_(),
have_read_sandbox_status_word_(false),
sandbox_status_(0),
@@ -141,8 +149,16 @@ void ZygoteHostImpl::Init(const std::string& sandbox_cmd) {
sandbox_binary_ = sandbox_cmd.c_str();
+ const bool using_namespace_sandbox = ShouldUseNamespaceSandbox();
// A non empty sandbox_cmd means we want a SUID sandbox.
- using_suid_sandbox_ = !sandbox_cmd.empty();
+ const bool using_suid_sandbox =
+ !sandbox_cmd.empty() && !using_namespace_sandbox;
+
+ // Use the SUID sandbox for adjusting OOM scores when we are using the setuid
+ // or namespace sandbox. This is needed beacuse the processes are
+ // non-dumpable, so /proc/pid/oom_score_adj can only be written by root.
+ use_suid_sandbox_for_adj_oom_score_ =
+ using_namespace_sandbox || using_suid_sandbox;
// Start up the sandbox host process and get the file descriptor for the
// renderers to talk to it.
@@ -150,21 +166,24 @@ void ZygoteHostImpl::Init(const std::string& sandbox_cmd) {
fds_to_map.push_back(std::make_pair(sfd, GetSandboxFD()));
base::ScopedFD dummy_fd;
- if (using_suid_sandbox_) {
- scoped_ptr<sandbox::SetuidSandboxClient>
- sandbox_client(sandbox::SetuidSandboxClient::Create());
- sandbox_client->PrependWrapper(&cmd_line);
- sandbox_client->SetupLaunchOptions(&options, &fds_to_map, &dummy_fd);
- sandbox_client->SetupLaunchEnvironment();
+ if (using_suid_sandbox) {
+ scoped_ptr<sandbox::SetuidSandboxHost> sandbox_host(
+ sandbox::SetuidSandboxHost::Create());
+ sandbox_host->PrependWrapper(&cmd_line);
+ sandbox_host->SetupLaunchOptions(&options, &fds_to_map, &dummy_fd);
+ sandbox_host->SetupLaunchEnvironment();
}
- base::ProcessHandle process = -1;
options.fds_to_remap = &fds_to_map;
- base::LaunchProcess(cmd_line.argv(), options, &process);
- CHECK(process != -1) << "Failed to launch zygote process";
+ base::Process process =
+ using_namespace_sandbox
+ ? sandbox::NamespaceSandbox::LaunchProcess(cmd_line, options)
+ : base::LaunchProcess(cmd_line, options);
+ CHECK(process.IsValid()) << "Failed to launch zygote process";
+
dummy_fd.reset();
- if (using_suid_sandbox_) {
+ if (using_suid_sandbox || using_namespace_sandbox) {
// The SUID sandbox will execute the zygote in a new PID namespace, and
// the main zygote process will then fork from there. Watch now our
// elaborate dance to find and validate the zygote's PID.
@@ -188,13 +207,15 @@ void ZygoteHostImpl::Init(const std::string& sandbox_cmd) {
fds[0], kZygoteHelloMessage, sizeof(kZygoteHelloMessage), &pid_));
CHECK_GT(pid_, 1);
- if (process != pid_) {
+ if (process.Pid() != pid_) {
// Reap the sandbox.
- base::EnsureProcessGetsReaped(process);
+ base::EnsureProcessGetsReaped(process.Pid());
}
} else {
// Not using the SUID sandbox.
- pid_ = process;
+ // Note that ~base::Process() will reset the internal value, but there's no
+ // real "handle" on POSIX so that is safe.
+ pid_ = process.Pid();
}
close(fds[1]);
@@ -281,7 +302,9 @@ ssize_t ZygoteHostImpl::ReadReply(void* buf, size_t buf_len) {
sizeof(sandbox_status_)) {
return -1;
}
+
have_read_sandbox_status_word_ = true;
+ UMA_HISTOGRAM_SPARSE_SLOWLY("Linux.SandboxStatus", sandbox_status_);
}
return HANDLE_EINTR(read(control_fd_, buf, buf_len));
@@ -369,7 +392,7 @@ pid_t ZygoteHostImpl::ForkRequest(const std::vector<std::string>& argv,
Pickle reply_pickle(buf, len);
PickleIterator iter(reply_pickle);
- if (len <= 0 || !reply_pickle.ReadInt(&iter, &pid))
+ if (len <= 0 || !iter.ReadInt(&pid))
return base::kNullProcessHandle;
// If there is a nonempty UMA name string, then there is a UMA
@@ -377,10 +400,10 @@ pid_t ZygoteHostImpl::ForkRequest(const std::vector<std::string>& argv,
std::string uma_name;
int uma_sample;
int uma_boundary_value;
- if (reply_pickle.ReadString(&iter, &uma_name) &&
+ if (iter.ReadString(&uma_name) &&
!uma_name.empty() &&
- reply_pickle.ReadInt(&iter, &uma_sample) &&
- reply_pickle.ReadInt(&iter, &uma_boundary_value)) {
+ iter.ReadInt(&uma_sample) &&
+ iter.ReadInt(&uma_boundary_value)) {
// We cannot use the UMA_HISTOGRAM_ENUMERATION macro here,
// because that's only for when the name is the same every time.
// Here we're using whatever name we got from the other side.
@@ -457,7 +480,7 @@ void ZygoteHostImpl::AdjustRendererOOMScore(base::ProcessHandle pid,
selinux_valid = true;
}
- if (using_suid_sandbox_ && !selinux) {
+ if (use_suid_sandbox_for_adj_oom_score_ && !selinux) {
#if defined(USE_TCMALLOC)
// If heap profiling is running, these processes are not exiting, at least
// on ChromeOS. The easiest thing to do is not launch them when profiling.
@@ -471,17 +494,17 @@ void ZygoteHostImpl::AdjustRendererOOMScore(base::ProcessHandle pid,
adj_oom_score_cmdline.push_back(base::Int64ToString(pid));
adj_oom_score_cmdline.push_back(base::IntToString(score));
- base::ProcessHandle sandbox_helper_process;
+ base::Process sandbox_helper_process;
base::LaunchOptions options;
// sandbox_helper_process is a setuid binary.
options.allow_new_privs = true;
- if (base::LaunchProcess(adj_oom_score_cmdline, options,
- &sandbox_helper_process)) {
- base::EnsureProcessGetsReaped(sandbox_helper_process);
- }
- } else if (!using_suid_sandbox_) {
+ sandbox_helper_process =
+ base::LaunchProcess(adj_oom_score_cmdline, options);
+ if (sandbox_helper_process.IsValid())
+ base::EnsureProcessGetsReaped(sandbox_helper_process.Pid());
+ } else if (!use_suid_sandbox_for_adj_oom_score_) {
if (!base::AdjustOOMScore(pid, score))
PLOG(ERROR) << "Failed to adjust OOM score of renderer with pid " << pid;
}
@@ -532,8 +555,7 @@ base::TerminationStatus ZygoteHostImpl::GetTerminationStatus(
Pickle read_pickle(buf, len);
int tmp_status, tmp_exit_code;
PickleIterator iter(read_pickle);
- if (!read_pickle.ReadInt(&iter, &tmp_status) ||
- !read_pickle.ReadInt(&iter, &tmp_exit_code)) {
+ if (!iter.ReadInt(&tmp_status) || !iter.ReadInt(&tmp_exit_code)) {
LOG(WARNING)
<< "Error parsing GetTerminationStatus response from zygote.";
} else {
@@ -559,4 +581,22 @@ int ZygoteHostImpl::GetSandboxStatus() const {
return 0;
}
+bool ZygoteHostImpl::ShouldUseNamespaceSandbox() {
+ const base::CommandLine& command_line =
+ *base::CommandLine::ForCurrentProcess();
+ if (command_line.HasSwitch(switches::kNoSandbox)) {
+ return false;
+ }
+
+ if (command_line.HasSwitch(switches::kDisableNamespaceSandbox)) {
+ return false;
+ }
+
+ if (!sandbox::Credentials::CanCreateProcessInNewUserNS()) {
+ return false;
+ }
+
+ return true;
+}
+
} // namespace content