diff options
author | Allan Sandfeld Jensen <allan.jensen@theqtcompany.com> | 2015-06-18 14:10:49 +0200 |
---|---|---|
committer | Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com> | 2015-06-18 13:53:24 +0000 |
commit | 813fbf95af77a531c57a8c497345ad2c61d475b3 (patch) | |
tree | 821b2c8de8365f21b6c9ba17a236fb3006a1d506 /chromium/content/browser/zygote_host/zygote_host_impl_linux.cc | |
parent | af6588f8d723931a298c995fa97259bb7f7deb55 (diff) | |
download | qtwebengine-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.cc | 106 |
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 |