Roll ANGLE e754fb8..6ffeb74
[chromium-blink-merge.git] / content / zygote / zygote_linux.cc
blob59a14c1c9ef3f12102a581125d1ff584598048b4
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
3 // found in the LICENSE file.
5 #include "content/zygote/zygote_linux.h"
7 #include <fcntl.h>
8 #include <string.h>
9 #include <sys/socket.h>
10 #include <sys/types.h>
11 #include <sys/wait.h>
13 #include "base/command_line.h"
14 #include "base/files/file_util.h"
15 #include "base/linux_util.h"
16 #include "base/logging.h"
17 #include "base/macros.h"
18 #include "base/memory/scoped_vector.h"
19 #include "base/pickle.h"
20 #include "base/posix/eintr_wrapper.h"
21 #include "base/posix/global_descriptors.h"
22 #include "base/posix/unix_domain_socket_linux.h"
23 #include "base/process/kill.h"
24 #include "base/process/launch.h"
25 #include "base/process/process.h"
26 #include "base/process/process_handle.h"
27 #include "base/trace_event/trace_event.h"
28 #include "content/common/child_process_sandbox_support_impl_linux.h"
29 #include "content/common/sandbox_linux/sandbox_linux.h"
30 #include "content/common/set_process_title.h"
31 #include "content/common/zygote_commands_linux.h"
32 #include "content/public/common/content_descriptors.h"
33 #include "content/public/common/result_codes.h"
34 #include "content/public/common/sandbox_linux.h"
35 #include "content/public/common/send_zygote_child_ping_linux.h"
36 #include "content/public/common/zygote_fork_delegate_linux.h"
37 #include "ipc/ipc_channel.h"
38 #include "ipc/ipc_switches.h"
39 #include "sandbox/linux/services/credentials.h"
40 #include "sandbox/linux/services/namespace_sandbox.h"
42 // See http://code.google.com/p/chromium/wiki/LinuxZygote
44 namespace content {
46 namespace {
48 // NOP function. See below where this handler is installed.
49 void SIGCHLDHandler(int signal) {
52 // On Linux, when a process is the init process of a PID namespace, it cannot be
53 // terminated by signals like SIGTERM or SIGINT, since they are ignored unless
54 // we register a handler for them. In the handlers, we exit with this special
55 // exit code that GetTerminationStatus understands to mean that we were
56 // terminated by an external signal.
57 const int kKilledExitCode = 0x80;
58 const int kUnexpectedExitCode = 0x81;
60 int LookUpFd(const base::GlobalDescriptors::Mapping& fd_mapping, uint32_t key) {
61 for (size_t index = 0; index < fd_mapping.size(); ++index) {
62 if (fd_mapping[index].key == key)
63 return fd_mapping[index].fd;
65 return -1;
68 void CreatePipe(base::ScopedFD* read_pipe, base::ScopedFD* write_pipe) {
69 int raw_pipe[2];
70 PCHECK(0 == pipe(raw_pipe));
71 read_pipe->reset(raw_pipe[0]);
72 write_pipe->reset(raw_pipe[1]);
75 void KillAndReap(pid_t pid, ZygoteForkDelegate* helper) {
76 if (helper) {
77 // Helper children may be forked in another PID namespace, so |pid| might
78 // be meaningless to us; or we just might not be able to directly send it
79 // signals. So we can't kill it.
80 // Additionally, we're not its parent, so we can't reap it anyway.
81 // TODO(mdempsky): Extend the ZygoteForkDelegate API to handle this.
82 LOG(WARNING) << "Unable to kill or reap helper children";
83 return;
86 // Kill the child process in case it's not already dead, so we can safely
87 // perform a blocking wait.
88 PCHECK(0 == kill(pid, SIGKILL));
89 PCHECK(pid == HANDLE_EINTR(waitpid(pid, NULL, 0)));
92 } // namespace
94 Zygote::Zygote(int sandbox_flags, ScopedVector<ZygoteForkDelegate> helpers,
95 const std::vector<base::ProcessHandle>& extra_children,
96 const std::vector<int>& extra_fds)
97 : sandbox_flags_(sandbox_flags),
98 helpers_(helpers.Pass()),
99 initial_uma_index_(0),
100 extra_children_(extra_children),
101 extra_fds_(extra_fds) {}
103 Zygote::~Zygote() {
106 bool Zygote::ProcessRequests() {
107 // A SOCK_SEQPACKET socket is installed in fd 3. We get commands from the
108 // browser on it.
109 // A SOCK_DGRAM is installed in fd 5. This is the sandbox IPC channel.
110 // See http://code.google.com/p/chromium/wiki/LinuxSandboxIPC
112 // We need to accept SIGCHLD, even though our handler is a no-op because
113 // otherwise we cannot wait on children. (According to POSIX 2001.)
114 struct sigaction action;
115 memset(&action, 0, sizeof(action));
116 action.sa_handler = &SIGCHLDHandler;
117 PCHECK(sigaction(SIGCHLD, &action, NULL) == 0);
119 if (UsingSUIDSandbox() || UsingNSSandbox()) {
120 // Let the ZygoteHost know we are ready to go.
121 // The receiving code is in content/browser/zygote_host_linux.cc.
122 bool r = base::UnixDomainSocket::SendMsg(kZygoteSocketPairFd,
123 kZygoteHelloMessage,
124 sizeof(kZygoteHelloMessage),
125 std::vector<int>());
126 #if defined(OS_CHROMEOS)
127 LOG_IF(WARNING, !r) << "Sending zygote magic failed";
128 // Exit normally on chromeos because session manager may send SIGTERM
129 // right after the process starts and it may fail to send zygote magic
130 // number to browser process.
131 if (!r)
132 _exit(RESULT_CODE_NORMAL_EXIT);
133 #else
134 CHECK(r) << "Sending zygote magic failed";
135 #endif
138 for (;;) {
139 // This function call can return multiple times, once per fork().
140 if (HandleRequestFromBrowser(kZygoteSocketPairFd))
141 return true;
145 bool Zygote::GetProcessInfo(base::ProcessHandle pid,
146 ZygoteProcessInfo* process_info) {
147 DCHECK(process_info);
148 const ZygoteProcessMap::const_iterator it = process_info_map_.find(pid);
149 if (it == process_info_map_.end()) {
150 return false;
152 *process_info = it->second;
153 return true;
156 bool Zygote::UsingSUIDSandbox() const {
157 return sandbox_flags_ & kSandboxLinuxSUID;
160 bool Zygote::UsingNSSandbox() const {
161 return sandbox_flags_ & kSandboxLinuxUserNS;
164 bool Zygote::HandleRequestFromBrowser(int fd) {
165 ScopedVector<base::ScopedFD> fds;
166 char buf[kZygoteMaxMessageLength];
167 const ssize_t len = base::UnixDomainSocket::RecvMsg(
168 fd, buf, sizeof(buf), &fds);
170 if (len == 0 || (len == -1 && errno == ECONNRESET)) {
171 // EOF from the browser. We should die.
172 // TODO(earthdok): call __sanititizer_cov_dump() here to obtain code
173 // coverage for the Zygote. Currently it's not possible because of
174 // confusion over who is responsible for closing the file descriptor.
175 for (std::vector<int>::iterator it = extra_fds_.begin();
176 it < extra_fds_.end(); ++it) {
177 PCHECK(0 == IGNORE_EINTR(close(*it)));
179 #if !defined(SANITIZER_COVERAGE)
180 // TODO(earthdok): add watchdog thread before using this in builds not
181 // using sanitizer coverage.
182 CHECK(extra_children_.empty());
183 #endif
184 for (std::vector<base::ProcessHandle>::iterator it =
185 extra_children_.begin();
186 it < extra_children_.end(); ++it) {
187 PCHECK(*it == HANDLE_EINTR(waitpid(*it, NULL, 0)));
189 _exit(0);
190 return false;
193 if (len == -1) {
194 PLOG(ERROR) << "Error reading message from browser";
195 return false;
198 base::Pickle pickle(buf, len);
199 base::PickleIterator iter(pickle);
201 int kind;
202 if (iter.ReadInt(&kind)) {
203 switch (kind) {
204 case kZygoteCommandFork:
205 // This function call can return multiple times, once per fork().
206 return HandleForkRequest(fd, iter, fds.Pass());
208 case kZygoteCommandReap:
209 if (!fds.empty())
210 break;
211 HandleReapRequest(fd, iter);
212 return false;
213 case kZygoteCommandGetTerminationStatus:
214 if (!fds.empty())
215 break;
216 HandleGetTerminationStatus(fd, iter);
217 return false;
218 case kZygoteCommandGetSandboxStatus:
219 HandleGetSandboxStatus(fd, iter);
220 return false;
221 case kZygoteCommandForkRealPID:
222 // This shouldn't happen in practice, but some failure paths in
223 // HandleForkRequest (e.g., if ReadArgsAndFork fails during depickling)
224 // could leave this command pending on the socket.
225 LOG(ERROR) << "Unexpected real PID message from browser";
226 NOTREACHED();
227 return false;
228 default:
229 NOTREACHED();
230 break;
234 LOG(WARNING) << "Error parsing message from browser";
235 return false;
238 // TODO(jln): remove callers to this broken API. See crbug.com/274855.
239 void Zygote::HandleReapRequest(int fd, base::PickleIterator iter) {
240 base::ProcessId child;
242 if (!iter.ReadInt(&child)) {
243 LOG(WARNING) << "Error parsing reap request from browser";
244 return;
247 ZygoteProcessInfo child_info;
248 if (!GetProcessInfo(child, &child_info)) {
249 LOG(ERROR) << "Child not found!";
250 NOTREACHED();
251 return;
254 if (!child_info.started_from_helper) {
255 // Do not call base::EnsureProcessTerminated() under ThreadSanitizer, as it
256 // spawns a separate thread which may live until the call to fork() in the
257 // zygote. As a result, ThreadSanitizer will report an error and almost
258 // disable race detection in the child process.
259 // Not calling EnsureProcessTerminated() may result in zombie processes
260 // sticking around. This will only happen during testing, so we can live
261 // with this for now.
262 #if !defined(THREAD_SANITIZER)
263 // TODO(jln): this old code is completely broken. See crbug.com/274855.
264 base::EnsureProcessTerminated(base::Process(child_info.internal_pid));
265 #else
266 LOG(WARNING) << "Zygote process omitting a call to "
267 << "base::EnsureProcessTerminated() for child pid " << child
268 << " under ThreadSanitizer. See http://crbug.com/274855.";
269 #endif
270 } else {
271 // For processes from the helper, send a GetTerminationStatus request
272 // with known_dead set to true.
273 // This is not perfect, as the process may be killed instantly, but is
274 // better than ignoring the request.
275 base::TerminationStatus status;
276 int exit_code;
277 bool got_termination_status =
278 GetTerminationStatus(child, true /* known_dead */, &status, &exit_code);
279 DCHECK(got_termination_status);
281 process_info_map_.erase(child);
284 bool Zygote::GetTerminationStatus(base::ProcessHandle real_pid,
285 bool known_dead,
286 base::TerminationStatus* status,
287 int* exit_code) {
289 ZygoteProcessInfo child_info;
290 if (!GetProcessInfo(real_pid, &child_info)) {
291 LOG(ERROR) << "Zygote::GetTerminationStatus for unknown PID "
292 << real_pid;
293 NOTREACHED();
294 return false;
296 // We know about |real_pid|.
297 const base::ProcessHandle child = child_info.internal_pid;
298 if (child_info.started_from_helper) {
299 if (!child_info.started_from_helper->GetTerminationStatus(
300 child, known_dead, status, exit_code)) {
301 return false;
303 } else {
304 // Handle the request directly.
305 if (known_dead) {
306 *status = base::GetKnownDeadTerminationStatus(child, exit_code);
307 } else {
308 // We don't know if the process is dying, so get its status but don't
309 // wait.
310 *status = base::GetTerminationStatus(child, exit_code);
313 // Successfully got a status for |real_pid|.
314 if (*status != base::TERMINATION_STATUS_STILL_RUNNING) {
315 // Time to forget about this process.
316 process_info_map_.erase(real_pid);
319 if (WIFEXITED(*exit_code) && WEXITSTATUS(*exit_code) == kKilledExitCode) {
320 *status = base::TERMINATION_STATUS_PROCESS_WAS_KILLED;
323 return true;
326 void Zygote::HandleGetTerminationStatus(int fd, base::PickleIterator iter) {
327 bool known_dead;
328 base::ProcessHandle child_requested;
330 if (!iter.ReadBool(&known_dead) || !iter.ReadInt(&child_requested)) {
331 LOG(WARNING) << "Error parsing GetTerminationStatus request "
332 << "from browser";
333 return;
336 base::TerminationStatus status;
337 int exit_code;
339 bool got_termination_status =
340 GetTerminationStatus(child_requested, known_dead, &status, &exit_code);
341 if (!got_termination_status) {
342 // Assume that if we can't find the child in the sandbox, then
343 // it terminated normally.
344 NOTREACHED();
345 status = base::TERMINATION_STATUS_NORMAL_TERMINATION;
346 exit_code = RESULT_CODE_NORMAL_EXIT;
349 base::Pickle write_pickle;
350 write_pickle.WriteInt(static_cast<int>(status));
351 write_pickle.WriteInt(exit_code);
352 ssize_t written =
353 HANDLE_EINTR(write(fd, write_pickle.data(), write_pickle.size()));
354 if (written != static_cast<ssize_t>(write_pickle.size()))
355 PLOG(ERROR) << "write";
358 int Zygote::ForkWithRealPid(const std::string& process_type,
359 const base::GlobalDescriptors::Mapping& fd_mapping,
360 const std::string& channel_id,
361 base::ScopedFD pid_oracle,
362 std::string* uma_name,
363 int* uma_sample,
364 int* uma_boundary_value) {
365 ZygoteForkDelegate* helper = NULL;
366 for (ScopedVector<ZygoteForkDelegate>::iterator i = helpers_.begin();
367 i != helpers_.end();
368 ++i) {
369 if ((*i)->CanHelp(process_type, uma_name, uma_sample, uma_boundary_value)) {
370 helper = *i;
371 break;
375 base::ScopedFD read_pipe, write_pipe;
376 base::ProcessId pid = 0;
377 if (helper) {
378 int ipc_channel_fd = LookUpFd(fd_mapping, kPrimaryIPCChannel);
379 if (ipc_channel_fd < 0) {
380 DLOG(ERROR) << "Failed to find kPrimaryIPCChannel in FD mapping";
381 return -1;
383 std::vector<int> fds;
384 fds.push_back(ipc_channel_fd); // kBrowserFDIndex
385 fds.push_back(pid_oracle.get()); // kPIDOracleFDIndex
386 pid = helper->Fork(process_type, fds, channel_id);
388 // Helpers should never return in the child process.
389 CHECK_NE(pid, 0);
390 } else {
391 CreatePipe(&read_pipe, &write_pipe);
392 if (sandbox_flags_ & kSandboxLinuxPIDNS &&
393 sandbox_flags_ & kSandboxLinuxUserNS) {
394 pid = sandbox::NamespaceSandbox::ForkInNewPidNamespace(
395 /*drop_capabilities_in_child=*/true);
396 } else {
397 pid = fork();
401 if (pid == 0) {
402 // If the process is the init process inside a PID namespace, it must have
403 // explicit signal handlers.
404 if (getpid() == 1) {
405 for (const int sig : {SIGINT, SIGTERM}) {
406 sandbox::NamespaceSandbox::InstallTerminationSignalHandler(
407 sig, kKilledExitCode);
410 static const int kUnexpectedSignals[] = {
411 SIGHUP, SIGQUIT, SIGABRT, SIGPIPE, SIGUSR1, SIGUSR2,
413 for (const int sig : kUnexpectedSignals) {
414 sandbox::NamespaceSandbox::InstallTerminationSignalHandler(
415 sig, kUnexpectedExitCode);
419 // In the child process.
420 write_pipe.reset();
422 // Ping the PID oracle socket so the browser can find our PID.
423 CHECK(SendZygoteChildPing(pid_oracle.get()));
425 // Now read back our real PID from the zygote.
426 base::ProcessId real_pid;
427 if (!base::ReadFromFD(read_pipe.get(),
428 reinterpret_cast<char*>(&real_pid),
429 sizeof(real_pid))) {
430 LOG(FATAL) << "Failed to synchronise with parent zygote process";
432 if (real_pid <= 0) {
433 LOG(FATAL) << "Invalid pid from parent zygote";
435 #if defined(OS_LINUX)
436 // Sandboxed processes need to send the global, non-namespaced PID when
437 // setting up an IPC channel to their parent.
438 IPC::Channel::SetGlobalPid(real_pid);
439 // Force the real PID so chrome event data have a PID that corresponds
440 // to system trace event data.
441 base::trace_event::TraceLog::GetInstance()->SetProcessID(
442 static_cast<int>(real_pid));
443 #endif
444 return 0;
447 // In the parent process.
448 read_pipe.reset();
449 pid_oracle.reset();
451 // Always receive a real PID from the zygote host, though it might
452 // be invalid (see below).
453 base::ProcessId real_pid;
455 ScopedVector<base::ScopedFD> recv_fds;
456 char buf[kZygoteMaxMessageLength];
457 const ssize_t len = base::UnixDomainSocket::RecvMsg(
458 kZygoteSocketPairFd, buf, sizeof(buf), &recv_fds);
459 CHECK_GT(len, 0);
460 CHECK(recv_fds.empty());
462 base::Pickle pickle(buf, len);
463 base::PickleIterator iter(pickle);
465 int kind;
466 CHECK(iter.ReadInt(&kind));
467 CHECK(kind == kZygoteCommandForkRealPID);
468 CHECK(iter.ReadInt(&real_pid));
471 // Fork failed.
472 if (pid < 0) {
473 return -1;
476 // If we successfully forked a child, but it crashed without sending
477 // a message to the browser, the browser won't have found its PID.
478 if (real_pid < 0) {
479 KillAndReap(pid, helper);
480 return -1;
483 // If we're not using a helper, send the PID back to the child process.
484 if (!helper) {
485 ssize_t written =
486 HANDLE_EINTR(write(write_pipe.get(), &real_pid, sizeof(real_pid)));
487 if (written != sizeof(real_pid)) {
488 KillAndReap(pid, helper);
489 return -1;
493 // Now set-up this process to be tracked by the Zygote.
494 if (process_info_map_.find(real_pid) != process_info_map_.end()) {
495 LOG(ERROR) << "Already tracking PID " << real_pid;
496 NOTREACHED();
498 process_info_map_[real_pid].internal_pid = pid;
499 process_info_map_[real_pid].started_from_helper = helper;
501 return real_pid;
504 base::ProcessId Zygote::ReadArgsAndFork(base::PickleIterator iter,
505 ScopedVector<base::ScopedFD> fds,
506 std::string* uma_name,
507 int* uma_sample,
508 int* uma_boundary_value) {
509 std::vector<std::string> args;
510 int argc = 0;
511 int numfds = 0;
512 base::GlobalDescriptors::Mapping mapping;
513 std::string process_type;
514 std::string channel_id;
515 const std::string channel_id_prefix = std::string("--")
516 + switches::kProcessChannelID + std::string("=");
518 if (!iter.ReadString(&process_type))
519 return -1;
520 if (!iter.ReadInt(&argc))
521 return -1;
523 for (int i = 0; i < argc; ++i) {
524 std::string arg;
525 if (!iter.ReadString(&arg))
526 return -1;
527 args.push_back(arg);
528 if (arg.compare(0, channel_id_prefix.length(), channel_id_prefix) == 0)
529 channel_id = arg.substr(channel_id_prefix.length());
532 if (!iter.ReadInt(&numfds))
533 return -1;
534 if (numfds != static_cast<int>(fds.size()))
535 return -1;
537 // First FD is the PID oracle socket.
538 if (fds.size() < 1)
539 return -1;
540 base::ScopedFD pid_oracle(fds[0]->Pass());
542 // Remaining FDs are for the global descriptor mapping.
543 for (int i = 1; i < numfds; ++i) {
544 base::GlobalDescriptors::Key key;
545 if (!iter.ReadUInt32(&key))
546 return -1;
547 mapping.push_back(base::GlobalDescriptors::Descriptor(key, fds[i]->get()));
550 mapping.push_back(base::GlobalDescriptors::Descriptor(
551 static_cast<uint32_t>(kSandboxIPCChannel), GetSandboxFD()));
553 // Returns twice, once per process.
554 base::ProcessId child_pid = ForkWithRealPid(process_type,
555 mapping,
556 channel_id,
557 pid_oracle.Pass(),
558 uma_name,
559 uma_sample,
560 uma_boundary_value);
561 if (!child_pid) {
562 // This is the child process.
564 // Our socket from the browser.
565 PCHECK(0 == IGNORE_EINTR(close(kZygoteSocketPairFd)));
567 // Pass ownership of file descriptors from fds to GlobalDescriptors.
568 for (ScopedVector<base::ScopedFD>::iterator i = fds.begin(); i != fds.end();
569 ++i)
570 ignore_result((*i)->release());
571 base::GlobalDescriptors::GetInstance()->Reset(mapping);
573 // Reset the process-wide command line to our new command line.
574 base::CommandLine::Reset();
575 base::CommandLine::Init(0, NULL);
576 base::CommandLine::ForCurrentProcess()->InitFromArgv(args);
578 // Update the process title. The argv was already cached by the call to
579 // SetProcessTitleFromCommandLine in ChromeMain, so we can pass NULL here
580 // (we don't have the original argv at this point).
581 SetProcessTitleFromCommandLine(NULL);
582 } else if (child_pid < 0) {
583 LOG(ERROR) << "Zygote could not fork: process_type " << process_type
584 << " numfds " << numfds << " child_pid " << child_pid;
586 return child_pid;
589 bool Zygote::HandleForkRequest(int fd,
590 base::PickleIterator iter,
591 ScopedVector<base::ScopedFD> fds) {
592 std::string uma_name;
593 int uma_sample;
594 int uma_boundary_value;
595 base::ProcessId child_pid = ReadArgsAndFork(
596 iter, fds.Pass(), &uma_name, &uma_sample, &uma_boundary_value);
597 if (child_pid == 0)
598 return true;
599 // If there's no UMA report for this particular fork, then check if any
600 // helpers have an initial UMA report for us to send instead.
601 while (uma_name.empty() && initial_uma_index_ < helpers_.size()) {
602 helpers_[initial_uma_index_++]->InitialUMA(
603 &uma_name, &uma_sample, &uma_boundary_value);
605 // Must always send reply, as ZygoteHost blocks while waiting for it.
606 base::Pickle reply_pickle;
607 reply_pickle.WriteInt(child_pid);
608 reply_pickle.WriteString(uma_name);
609 if (!uma_name.empty()) {
610 reply_pickle.WriteInt(uma_sample);
611 reply_pickle.WriteInt(uma_boundary_value);
613 if (HANDLE_EINTR(write(fd, reply_pickle.data(), reply_pickle.size())) !=
614 static_cast<ssize_t> (reply_pickle.size()))
615 PLOG(ERROR) << "write";
616 return false;
619 bool Zygote::HandleGetSandboxStatus(int fd, base::PickleIterator iter) {
620 if (HANDLE_EINTR(write(fd, &sandbox_flags_, sizeof(sandbox_flags_))) !=
621 sizeof(sandbox_flags_)) {
622 PLOG(ERROR) << "write";
625 return false;
628 } // namespace content