Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(221)

Side by Side Diff: content/browser/zygote_host/zygote_host_impl_linux.cc

Issue 897723005: Allow using the namespace sandbox in zygote host. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add back the flag check. Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/zygote_host/zygote_host_impl_linux.h" 5 #include "content/browser/zygote_host/zygote_host_impl_linux.h"
6 6
7 #include <string.h> 7 #include <string.h>
8 #include <sys/socket.h> 8 #include <sys/socket.h>
9 #include <sys/stat.h> 9 #include <sys/stat.h>
10 #include <sys/types.h> 10 #include <sys/types.h>
(...skipping 20 matching lines...) Expand all
31 #include "base/strings/string_number_conversions.h" 31 #include "base/strings/string_number_conversions.h"
32 #include "base/strings/string_util.h" 32 #include "base/strings/string_util.h"
33 #include "base/strings/utf_string_conversions.h" 33 #include "base/strings/utf_string_conversions.h"
34 #include "base/time/time.h" 34 #include "base/time/time.h"
35 #include "content/browser/renderer_host/render_sandbox_host_linux.h" 35 #include "content/browser/renderer_host/render_sandbox_host_linux.h"
36 #include "content/common/child_process_sandbox_support_impl_linux.h" 36 #include "content/common/child_process_sandbox_support_impl_linux.h"
37 #include "content/common/zygote_commands_linux.h" 37 #include "content/common/zygote_commands_linux.h"
38 #include "content/public/browser/content_browser_client.h" 38 #include "content/public/browser/content_browser_client.h"
39 #include "content/public/common/content_switches.h" 39 #include "content/public/common/content_switches.h"
40 #include "content/public/common/result_codes.h" 40 #include "content/public/common/result_codes.h"
41 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
42 #include "sandbox/linux/services/credentials.h"
43 #include "sandbox/linux/services/namespace_sandbox.h"
44 #include "sandbox/linux/services/namespace_utils.h"
41 #include "sandbox/linux/suid/client/setuid_sandbox_client.h" 45 #include "sandbox/linux/suid/client/setuid_sandbox_client.h"
42 #include "sandbox/linux/suid/common/sandbox.h" 46 #include "sandbox/linux/suid/common/sandbox.h"
43 #include "ui/base/ui_base_switches.h" 47 #include "ui/base/ui_base_switches.h"
44 #include "ui/gfx/switches.h" 48 #include "ui/gfx/switches.h"
45 49
46 #if defined(USE_TCMALLOC) 50 #if defined(USE_TCMALLOC)
47 #include "third_party/tcmalloc/chromium/src/gperftools/heap-profiler.h" 51 #include "third_party/tcmalloc/chromium/src/gperftools/heap-profiler.h"
48 #endif 52 #endif
49 53
50 namespace content { 54 namespace content {
51 55
56 namespace {
57
52 // Receive a fixed message on fd and return the sender's PID. 58 // Receive a fixed message on fd and return the sender's PID.
53 // Returns true if the message received matches the expected message. 59 // Returns true if the message received matches the expected message.
54 static bool ReceiveFixedMessage(int fd, 60 bool ReceiveFixedMessage(int fd,
55 const char* expect_msg, 61 const char* expect_msg,
56 size_t expect_len, 62 size_t expect_len,
57 base::ProcessId* sender_pid) { 63 base::ProcessId* sender_pid) {
58 char buf[expect_len + 1]; 64 char buf[expect_len + 1];
59 ScopedVector<base::ScopedFD> fds_vec; 65 ScopedVector<base::ScopedFD> fds_vec;
60 66
61 const ssize_t len = UnixDomainSocket::RecvMsgWithPid( 67 const ssize_t len = UnixDomainSocket::RecvMsgWithPid(
62 fd, buf, sizeof(buf), &fds_vec, sender_pid); 68 fd, buf, sizeof(buf), &fds_vec, sender_pid);
63 if (static_cast<size_t>(len) != expect_len) 69 if (static_cast<size_t>(len) != expect_len)
64 return false; 70 return false;
65 if (memcmp(buf, expect_msg, expect_len) != 0) 71 if (memcmp(buf, expect_msg, expect_len) != 0)
66 return false; 72 return false;
67 if (!fds_vec.empty()) 73 if (!fds_vec.empty())
68 return false; 74 return false;
69 return true; 75 return true;
70 } 76 }
71 77
78 } // namespace
79
72 // static 80 // static
73 ZygoteHost* ZygoteHost::GetInstance() { 81 ZygoteHost* ZygoteHost::GetInstance() {
74 return ZygoteHostImpl::GetInstance(); 82 return ZygoteHostImpl::GetInstance();
75 } 83 }
76 84
77 ZygoteHostImpl::ZygoteHostImpl() 85 ZygoteHostImpl::ZygoteHostImpl()
78 : control_fd_(-1), 86 : control_fd_(-1),
79 control_lock_(), 87 control_lock_(),
80 pid_(-1), 88 pid_(-1),
81 init_(false), 89 init_(false),
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 switches::kV, 142 switches::kV,
135 switches::kVModule, 143 switches::kVModule,
136 }; 144 };
137 cmd_line.CopySwitchesFrom(browser_command_line, kForwardSwitches, 145 cmd_line.CopySwitchesFrom(browser_command_line, kForwardSwitches,
138 arraysize(kForwardSwitches)); 146 arraysize(kForwardSwitches));
139 147
140 GetContentClient()->browser()->AppendExtraCommandLineSwitches(&cmd_line, -1); 148 GetContentClient()->browser()->AppendExtraCommandLineSwitches(&cmd_line, -1);
141 149
142 sandbox_binary_ = sandbox_cmd.c_str(); 150 sandbox_binary_ = sandbox_cmd.c_str();
143 151
152 bool using_namespace_sandbox = ShouldUseNamespaceSandbox();
144 // A non empty sandbox_cmd means we want a SUID sandbox. 153 // A non empty sandbox_cmd means we want a SUID sandbox.
145 using_suid_sandbox_ = !sandbox_cmd.empty(); 154 using_suid_sandbox_ = !sandbox_cmd.empty() && !using_namespace_sandbox;
146 155
147 // Start up the sandbox host process and get the file descriptor for the 156 // Start up the sandbox host process and get the file descriptor for the
148 // renderers to talk to it. 157 // renderers to talk to it.
149 const int sfd = RenderSandboxHostLinux::GetInstance()->GetRendererSocket(); 158 const int sfd = RenderSandboxHostLinux::GetInstance()->GetRendererSocket();
150 fds_to_map.push_back(std::make_pair(sfd, GetSandboxFD())); 159 fds_to_map.push_back(std::make_pair(sfd, GetSandboxFD()));
151 160
152 base::ScopedFD dummy_fd; 161 base::ScopedFD dummy_fd;
153 if (using_suid_sandbox_) { 162 if (using_suid_sandbox_) {
154 scoped_ptr<sandbox::SetuidSandboxClient> 163 scoped_ptr<sandbox::SetuidSandboxClient>
155 sandbox_client(sandbox::SetuidSandboxClient::Create()); 164 sandbox_client(sandbox::SetuidSandboxClient::Create());
156 sandbox_client->PrependWrapper(&cmd_line); 165 sandbox_client->PrependWrapper(&cmd_line);
157 sandbox_client->SetupLaunchOptions(&options, &fds_to_map, &dummy_fd); 166 sandbox_client->SetupLaunchOptions(&options, &fds_to_map, &dummy_fd);
158 sandbox_client->SetupLaunchEnvironment(); 167 sandbox_client->SetupLaunchEnvironment();
159 } 168 }
160 169
161 options.fds_to_remap = &fds_to_map; 170 options.fds_to_remap = &fds_to_map;
162 base::Process process = base::LaunchProcess(cmd_line.argv(), options); 171 base::Process process =
172 using_namespace_sandbox
173 ? sandbox::NamespaceSandbox::LaunchProcess(cmd_line, options)
174 : base::LaunchProcess(cmd_line, options);
163 CHECK(process.IsValid()) << "Failed to launch zygote process"; 175 CHECK(process.IsValid()) << "Failed to launch zygote process";
176
164 dummy_fd.reset(); 177 dummy_fd.reset();
165 178
166 if (using_suid_sandbox_) { 179 if (using_suid_sandbox_) {
167 // The SUID sandbox will execute the zygote in a new PID namespace, and 180 // The SUID sandbox will execute the zygote in a new PID namespace, and
168 // the main zygote process will then fork from there. Watch now our 181 // the main zygote process will then fork from there. Watch now our
169 // elaborate dance to find and validate the zygote's PID. 182 // elaborate dance to find and validate the zygote's PID.
170 183
171 // First we receive a message from the zygote boot process. 184 // First we receive a message from the zygote boot process.
172 base::ProcessId boot_pid; 185 base::ProcessId boot_pid;
173 CHECK(ReceiveFixedMessage( 186 CHECK(ReceiveFixedMessage(
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after
552 pid_t ZygoteHostImpl::GetPid() const { 565 pid_t ZygoteHostImpl::GetPid() const {
553 return pid_; 566 return pid_;
554 } 567 }
555 568
556 int ZygoteHostImpl::GetSandboxStatus() const { 569 int ZygoteHostImpl::GetSandboxStatus() const {
557 if (have_read_sandbox_status_word_) 570 if (have_read_sandbox_status_word_)
558 return sandbox_status_; 571 return sandbox_status_;
559 return 0; 572 return 0;
560 } 573 }
561 574
575 bool ZygoteHostImpl::ShouldUseNamespaceSandbox() {
576 const base::CommandLine& command_line =
577 *base::CommandLine::ForCurrentProcess();
578 if (command_line.HasSwitch(switches::kNoSandbox)) {
579 return false;
580 }
581
582 if (!command_line.HasSwitch(switches::kEnableNamespaceSandbox)) {
583 return false;
584 }
585
586 if (!sandbox::Credentials::CanCreateProcessInNewUserNS()) {
587 return false;
588 }
589
590 // Unlike the setuid sandbox, the namespace sandbox does not make processes
jln (very slow on Chromium) 2015/02/05 00:26:56 I wonder if we shouldn't have the NS sandbox as a
rickyz (no longer on Chrome) 2015/02/05 01:42:51 Yeah, that sounds good - I switched back to using
591 // non-dumpable. In order to use the namespace sandbox, we must be able to use
592 // seccomp-bpf for process isolation.
593 if (!sandbox::SandboxBPF::SupportsSeccompSandbox(
594 sandbox::SandboxBPF::SeccompLevel::SINGLE_THREADED)) {
595 return false;
596 }
597
598 return true;
599 }
600
562 } // namespace content 601 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698