Move ForkWithFlags from process* to launch*.
[chromium-blink-merge.git] / content / zygote / zygote_linux.cc
blobf7e043ac523f1104b3c4c346ff8db9365172ffb6
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/debug/trace_event.h"
15 #include "base/files/file_util.h"
16 #include "base/linux_util.h"
17 #include "base/logging.h"
18 #include "base/macros.h"
19 #include "base/memory/scoped_vector.h"
20 #include "base/pickle.h"
21 #include "base/posix/eintr_wrapper.h"
22 #include "base/posix/global_descriptors.h"
23 #include "base/posix/unix_domain_socket_linux.h"
24 #include "base/process/kill.h"
25 #include "base/process/launch.h"
26 #include "base/process/process.h"
27 #include "base/process/process_handle.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"
40 #if defined(ADDRESS_SANITIZER)
41 #include <sanitizer/asan_interface.h>
42 #endif
44 // See http://code.google.com/p/chromium/wiki/LinuxZygote
46 namespace content {
48 namespace {
50 // NOP function. See below where this handler is installed.
51 void SIGCHLDHandler(int signal) {
54 int LookUpFd(const base::GlobalDescriptors::Mapping& fd_mapping, uint32_t key) {
55 for (size_t index = 0; index < fd_mapping.size(); ++index) {
56 if (fd_mapping[index].key == key)
57 return fd_mapping[index].fd;
59 return -1;
62 void CreatePipe(base::ScopedFD* read_pipe, base::ScopedFD* write_pipe) {
63 int raw_pipe[2];
64 PCHECK(0 == pipe(raw_pipe));
65 read_pipe->reset(raw_pipe[0]);
66 write_pipe->reset(raw_pipe[1]);
69 void KillAndReap(pid_t pid, ZygoteForkDelegate* helper) {
70 if (helper) {
71 // Helper children may be forked in another PID namespace, so |pid| might
72 // be meaningless to us; or we just might not be able to directly send it
73 // signals. So we can't kill it.
74 // Additionally, we're not its parent, so we can't reap it anyway.
75 // TODO(mdempsky): Extend the ZygoteForkDelegate API to handle this.
76 LOG(WARNING) << "Unable to kill or reap helper children";
77 return;
80 // Kill the child process in case it's not already dead, so we can safely
81 // perform a blocking wait.
82 PCHECK(0 == kill(pid, SIGKILL));
83 PCHECK(pid == HANDLE_EINTR(waitpid(pid, NULL, 0)));
86 } // namespace
88 Zygote::Zygote(int sandbox_flags, ScopedVector<ZygoteForkDelegate> helpers,
89 const std::vector<base::ProcessHandle>& extra_children,
90 const std::vector<int>& extra_fds)
91 : sandbox_flags_(sandbox_flags),
92 helpers_(helpers.Pass()),
93 initial_uma_index_(0),
94 extra_children_(extra_children),
95 extra_fds_(extra_fds) {}
97 Zygote::~Zygote() {
100 bool Zygote::ProcessRequests() {
101 // A SOCK_SEQPACKET socket is installed in fd 3. We get commands from the
102 // browser on it.
103 // A SOCK_DGRAM is installed in fd 5. This is the sandbox IPC channel.
104 // See http://code.google.com/p/chromium/wiki/LinuxSandboxIPC
106 // We need to accept SIGCHLD, even though our handler is a no-op because
107 // otherwise we cannot wait on children. (According to POSIX 2001.)
108 struct sigaction action;
109 memset(&action, 0, sizeof(action));
110 action.sa_handler = &SIGCHLDHandler;
111 CHECK(sigaction(SIGCHLD, &action, NULL) == 0);
113 if (UsingSUIDSandbox()) {
114 // Let the ZygoteHost know we are ready to go.
115 // The receiving code is in content/browser/zygote_host_linux.cc.
116 bool r = UnixDomainSocket::SendMsg(kZygoteSocketPairFd,
117 kZygoteHelloMessage,
118 sizeof(kZygoteHelloMessage),
119 std::vector<int>());
120 #if defined(OS_CHROMEOS)
121 LOG_IF(WARNING, !r) << "Sending zygote magic failed";
122 // Exit normally on chromeos because session manager may send SIGTERM
123 // right after the process starts and it may fail to send zygote magic
124 // number to browser process.
125 if (!r)
126 _exit(RESULT_CODE_NORMAL_EXIT);
127 #else
128 CHECK(r) << "Sending zygote magic failed";
129 #endif
132 for (;;) {
133 // This function call can return multiple times, once per fork().
134 if (HandleRequestFromBrowser(kZygoteSocketPairFd))
135 return true;
139 bool Zygote::GetProcessInfo(base::ProcessHandle pid,
140 ZygoteProcessInfo* process_info) {
141 DCHECK(process_info);
142 const ZygoteProcessMap::const_iterator it = process_info_map_.find(pid);
143 if (it == process_info_map_.end()) {
144 return false;
146 *process_info = it->second;
147 return true;
150 bool Zygote::UsingSUIDSandbox() const {
151 return sandbox_flags_ & kSandboxLinuxSUID;
154 bool Zygote::HandleRequestFromBrowser(int fd) {
155 ScopedVector<base::ScopedFD> fds;
156 char buf[kZygoteMaxMessageLength];
157 const ssize_t len = UnixDomainSocket::RecvMsg(fd, buf, sizeof(buf), &fds);
159 if (len == 0 || (len == -1 && errno == ECONNRESET)) {
160 // EOF from the browser. We should die.
161 // TODO(earthdok): call __sanititizer_cov_dump() here to obtain code
162 // coverage for the Zygote. Currently it's not possible because of
163 // confusion over who is responsible for closing the file descriptor.
164 for (std::vector<int>::iterator it = extra_fds_.begin();
165 it < extra_fds_.end(); ++it) {
166 PCHECK(0 == IGNORE_EINTR(close(*it)));
168 #if !defined(ADDRESS_SANITIZER)
169 // TODO(earthdok): add watchdog thread before using this in non-ASAN builds.
170 CHECK(extra_children_.empty());
171 #endif
172 for (std::vector<base::ProcessHandle>::iterator it =
173 extra_children_.begin();
174 it < extra_children_.end(); ++it) {
175 PCHECK(*it == HANDLE_EINTR(waitpid(*it, NULL, 0)));
177 _exit(0);
178 return false;
181 if (len == -1) {
182 PLOG(ERROR) << "Error reading message from browser";
183 return false;
186 Pickle pickle(buf, len);
187 PickleIterator iter(pickle);
189 int kind;
190 if (iter.ReadInt(&kind)) {
191 switch (kind) {
192 case kZygoteCommandFork:
193 // This function call can return multiple times, once per fork().
194 return HandleForkRequest(fd, iter, fds.Pass());
196 case kZygoteCommandReap:
197 if (!fds.empty())
198 break;
199 HandleReapRequest(fd, iter);
200 return false;
201 case kZygoteCommandGetTerminationStatus:
202 if (!fds.empty())
203 break;
204 HandleGetTerminationStatus(fd, iter);
205 return false;
206 case kZygoteCommandGetSandboxStatus:
207 HandleGetSandboxStatus(fd, iter);
208 return false;
209 case kZygoteCommandForkRealPID:
210 // This shouldn't happen in practice, but some failure paths in
211 // HandleForkRequest (e.g., if ReadArgsAndFork fails during depickling)
212 // could leave this command pending on the socket.
213 LOG(ERROR) << "Unexpected real PID message from browser";
214 NOTREACHED();
215 return false;
216 default:
217 NOTREACHED();
218 break;
222 LOG(WARNING) << "Error parsing message from browser";
223 return false;
226 // TODO(jln): remove callers to this broken API. See crbug.com/274855.
227 void Zygote::HandleReapRequest(int fd,
228 PickleIterator iter) {
229 base::ProcessId child;
231 if (!iter.ReadInt(&child)) {
232 LOG(WARNING) << "Error parsing reap request from browser";
233 return;
236 ZygoteProcessInfo child_info;
237 if (!GetProcessInfo(child, &child_info)) {
238 LOG(ERROR) << "Child not found!";
239 NOTREACHED();
240 return;
243 if (!child_info.started_from_helper) {
244 // Do not call base::EnsureProcessTerminated() under ThreadSanitizer, as it
245 // spawns a separate thread which may live until the call to fork() in the
246 // zygote. As a result, ThreadSanitizer will report an error and almost
247 // disable race detection in the child process.
248 // Not calling EnsureProcessTerminated() may result in zombie processes
249 // sticking around. This will only happen during testing, so we can live
250 // with this for now.
251 #if !defined(THREAD_SANITIZER)
252 // TODO(jln): this old code is completely broken. See crbug.com/274855.
253 base::EnsureProcessTerminated(base::Process(child_info.internal_pid));
254 #else
255 LOG(WARNING) << "Zygote process omitting a call to "
256 << "base::EnsureProcessTerminated() for child pid " << child
257 << " under ThreadSanitizer. See http://crbug.com/274855.";
258 #endif
259 } else {
260 // For processes from the helper, send a GetTerminationStatus request
261 // with known_dead set to true.
262 // This is not perfect, as the process may be killed instantly, but is
263 // better than ignoring the request.
264 base::TerminationStatus status;
265 int exit_code;
266 bool got_termination_status =
267 GetTerminationStatus(child, true /* known_dead */, &status, &exit_code);
268 DCHECK(got_termination_status);
270 process_info_map_.erase(child);
273 bool Zygote::GetTerminationStatus(base::ProcessHandle real_pid,
274 bool known_dead,
275 base::TerminationStatus* status,
276 int* exit_code) {
278 ZygoteProcessInfo child_info;
279 if (!GetProcessInfo(real_pid, &child_info)) {
280 LOG(ERROR) << "Zygote::GetTerminationStatus for unknown PID "
281 << real_pid;
282 NOTREACHED();
283 return false;
285 // We know about |real_pid|.
286 const base::ProcessHandle child = child_info.internal_pid;
287 if (child_info.started_from_helper) {
288 if (!child_info.started_from_helper->GetTerminationStatus(
289 child, known_dead, status, exit_code)) {
290 return false;
292 } else {
293 // Handle the request directly.
294 if (known_dead) {
295 *status = base::GetKnownDeadTerminationStatus(child, exit_code);
296 } else {
297 // We don't know if the process is dying, so get its status but don't
298 // wait.
299 *status = base::GetTerminationStatus(child, exit_code);
302 // Successfully got a status for |real_pid|.
303 if (*status != base::TERMINATION_STATUS_STILL_RUNNING) {
304 // Time to forget about this process.
305 process_info_map_.erase(real_pid);
307 return true;
310 void Zygote::HandleGetTerminationStatus(int fd,
311 PickleIterator iter) {
312 bool known_dead;
313 base::ProcessHandle child_requested;
315 if (!iter.ReadBool(&known_dead) || !iter.ReadInt(&child_requested)) {
316 LOG(WARNING) << "Error parsing GetTerminationStatus request "
317 << "from browser";
318 return;
321 base::TerminationStatus status;
322 int exit_code;
324 bool got_termination_status =
325 GetTerminationStatus(child_requested, known_dead, &status, &exit_code);
326 if (!got_termination_status) {
327 // Assume that if we can't find the child in the sandbox, then
328 // it terminated normally.
329 NOTREACHED();
330 status = base::TERMINATION_STATUS_NORMAL_TERMINATION;
331 exit_code = RESULT_CODE_NORMAL_EXIT;
334 Pickle write_pickle;
335 write_pickle.WriteInt(static_cast<int>(status));
336 write_pickle.WriteInt(exit_code);
337 ssize_t written =
338 HANDLE_EINTR(write(fd, write_pickle.data(), write_pickle.size()));
339 if (written != static_cast<ssize_t>(write_pickle.size()))
340 PLOG(ERROR) << "write";
343 int Zygote::ForkWithRealPid(const std::string& process_type,
344 const base::GlobalDescriptors::Mapping& fd_mapping,
345 const std::string& channel_id,
346 base::ScopedFD pid_oracle,
347 std::string* uma_name,
348 int* uma_sample,
349 int* uma_boundary_value) {
350 ZygoteForkDelegate* helper = NULL;
351 for (ScopedVector<ZygoteForkDelegate>::iterator i = helpers_.begin();
352 i != helpers_.end();
353 ++i) {
354 if ((*i)->CanHelp(process_type, uma_name, uma_sample, uma_boundary_value)) {
355 helper = *i;
356 break;
360 base::ScopedFD read_pipe, write_pipe;
361 base::ProcessId pid = 0;
362 if (helper) {
363 int ipc_channel_fd = LookUpFd(fd_mapping, kPrimaryIPCChannel);
364 if (ipc_channel_fd < 0) {
365 DLOG(ERROR) << "Failed to find kPrimaryIPCChannel in FD mapping";
366 return -1;
368 std::vector<int> fds;
369 fds.push_back(ipc_channel_fd); // kBrowserFDIndex
370 fds.push_back(pid_oracle.get()); // kPIDOracleFDIndex
371 pid = helper->Fork(process_type, fds, channel_id);
373 // Helpers should never return in the child process.
374 CHECK_NE(pid, 0);
375 } else {
376 CreatePipe(&read_pipe, &write_pipe);
377 // This is roughly equivalent to a fork(). We are using ForkWithFlags mainly
378 // to give it some more diverse test coverage.
379 pid = base::ForkWithFlags(SIGCHLD, nullptr, nullptr);
382 if (pid == 0) {
383 // In the child process.
384 write_pipe.reset();
386 // Ping the PID oracle socket so the browser can find our PID.
387 CHECK(SendZygoteChildPing(pid_oracle.get()));
389 // Now read back our real PID from the zygote.
390 base::ProcessId real_pid;
391 if (!base::ReadFromFD(read_pipe.get(),
392 reinterpret_cast<char*>(&real_pid),
393 sizeof(real_pid))) {
394 LOG(FATAL) << "Failed to synchronise with parent zygote process";
396 if (real_pid <= 0) {
397 LOG(FATAL) << "Invalid pid from parent zygote";
399 #if defined(OS_LINUX)
400 // Sandboxed processes need to send the global, non-namespaced PID when
401 // setting up an IPC channel to their parent.
402 IPC::Channel::SetGlobalPid(real_pid);
403 // Force the real PID so chrome event data have a PID that corresponds
404 // to system trace event data.
405 base::debug::TraceLog::GetInstance()->SetProcessID(
406 static_cast<int>(real_pid));
407 #endif
408 return 0;
411 // In the parent process.
412 read_pipe.reset();
413 pid_oracle.reset();
415 // Always receive a real PID from the zygote host, though it might
416 // be invalid (see below).
417 base::ProcessId real_pid;
419 ScopedVector<base::ScopedFD> recv_fds;
420 char buf[kZygoteMaxMessageLength];
421 const ssize_t len = UnixDomainSocket::RecvMsg(
422 kZygoteSocketPairFd, buf, sizeof(buf), &recv_fds);
423 CHECK_GT(len, 0);
424 CHECK(recv_fds.empty());
426 Pickle pickle(buf, len);
427 PickleIterator iter(pickle);
429 int kind;
430 CHECK(iter.ReadInt(&kind));
431 CHECK(kind == kZygoteCommandForkRealPID);
432 CHECK(iter.ReadInt(&real_pid));
435 // Fork failed.
436 if (pid < 0) {
437 return -1;
440 // If we successfully forked a child, but it crashed without sending
441 // a message to the browser, the browser won't have found its PID.
442 if (real_pid < 0) {
443 KillAndReap(pid, helper);
444 return -1;
447 // If we're not using a helper, send the PID back to the child process.
448 if (!helper) {
449 ssize_t written =
450 HANDLE_EINTR(write(write_pipe.get(), &real_pid, sizeof(real_pid)));
451 if (written != sizeof(real_pid)) {
452 KillAndReap(pid, helper);
453 return -1;
457 // Now set-up this process to be tracked by the Zygote.
458 if (process_info_map_.find(real_pid) != process_info_map_.end()) {
459 LOG(ERROR) << "Already tracking PID " << real_pid;
460 NOTREACHED();
462 process_info_map_[real_pid].internal_pid = pid;
463 process_info_map_[real_pid].started_from_helper = helper;
465 return real_pid;
468 base::ProcessId Zygote::ReadArgsAndFork(PickleIterator iter,
469 ScopedVector<base::ScopedFD> fds,
470 std::string* uma_name,
471 int* uma_sample,
472 int* uma_boundary_value) {
473 std::vector<std::string> args;
474 int argc = 0;
475 int numfds = 0;
476 base::GlobalDescriptors::Mapping mapping;
477 std::string process_type;
478 std::string channel_id;
479 const std::string channel_id_prefix = std::string("--")
480 + switches::kProcessChannelID + std::string("=");
482 if (!iter.ReadString(&process_type))
483 return -1;
484 if (!iter.ReadInt(&argc))
485 return -1;
487 for (int i = 0; i < argc; ++i) {
488 std::string arg;
489 if (!iter.ReadString(&arg))
490 return -1;
491 args.push_back(arg);
492 if (arg.compare(0, channel_id_prefix.length(), channel_id_prefix) == 0)
493 channel_id = arg.substr(channel_id_prefix.length());
496 if (!iter.ReadInt(&numfds))
497 return -1;
498 if (numfds != static_cast<int>(fds.size()))
499 return -1;
501 // First FD is the PID oracle socket.
502 if (fds.size() < 1)
503 return -1;
504 base::ScopedFD pid_oracle(fds[0]->Pass());
506 // Remaining FDs are for the global descriptor mapping.
507 for (int i = 1; i < numfds; ++i) {
508 base::GlobalDescriptors::Key key;
509 if (!iter.ReadUInt32(&key))
510 return -1;
511 mapping.push_back(base::GlobalDescriptors::Descriptor(key, fds[i]->get()));
514 mapping.push_back(base::GlobalDescriptors::Descriptor(
515 static_cast<uint32_t>(kSandboxIPCChannel), GetSandboxFD()));
517 // Returns twice, once per process.
518 base::ProcessId child_pid = ForkWithRealPid(process_type,
519 mapping,
520 channel_id,
521 pid_oracle.Pass(),
522 uma_name,
523 uma_sample,
524 uma_boundary_value);
525 if (!child_pid) {
526 // This is the child process.
528 // Our socket from the browser.
529 PCHECK(0 == IGNORE_EINTR(close(kZygoteSocketPairFd)));
531 // Pass ownership of file descriptors from fds to GlobalDescriptors.
532 for (ScopedVector<base::ScopedFD>::iterator i = fds.begin(); i != fds.end();
533 ++i)
534 ignore_result((*i)->release());
535 base::GlobalDescriptors::GetInstance()->Reset(mapping);
537 // Reset the process-wide command line to our new command line.
538 base::CommandLine::Reset();
539 base::CommandLine::Init(0, NULL);
540 base::CommandLine::ForCurrentProcess()->InitFromArgv(args);
542 // Update the process title. The argv was already cached by the call to
543 // SetProcessTitleFromCommandLine in ChromeMain, so we can pass NULL here
544 // (we don't have the original argv at this point).
545 SetProcessTitleFromCommandLine(NULL);
546 } else if (child_pid < 0) {
547 LOG(ERROR) << "Zygote could not fork: process_type " << process_type
548 << " numfds " << numfds << " child_pid " << child_pid;
550 return child_pid;
553 bool Zygote::HandleForkRequest(int fd,
554 PickleIterator iter,
555 ScopedVector<base::ScopedFD> fds) {
556 std::string uma_name;
557 int uma_sample;
558 int uma_boundary_value;
559 base::ProcessId child_pid = ReadArgsAndFork(
560 iter, fds.Pass(), &uma_name, &uma_sample, &uma_boundary_value);
561 if (child_pid == 0)
562 return true;
563 // If there's no UMA report for this particular fork, then check if any
564 // helpers have an initial UMA report for us to send instead.
565 while (uma_name.empty() && initial_uma_index_ < helpers_.size()) {
566 helpers_[initial_uma_index_++]->InitialUMA(
567 &uma_name, &uma_sample, &uma_boundary_value);
569 // Must always send reply, as ZygoteHost blocks while waiting for it.
570 Pickle reply_pickle;
571 reply_pickle.WriteInt(child_pid);
572 reply_pickle.WriteString(uma_name);
573 if (!uma_name.empty()) {
574 reply_pickle.WriteInt(uma_sample);
575 reply_pickle.WriteInt(uma_boundary_value);
577 if (HANDLE_EINTR(write(fd, reply_pickle.data(), reply_pickle.size())) !=
578 static_cast<ssize_t> (reply_pickle.size()))
579 PLOG(ERROR) << "write";
580 return false;
583 bool Zygote::HandleGetSandboxStatus(int fd,
584 PickleIterator iter) {
585 if (HANDLE_EINTR(write(fd, &sandbox_flags_, sizeof(sandbox_flags_))) !=
586 sizeof(sandbox_flags_)) {
587 PLOG(ERROR) << "write";
590 return false;
593 } // namespace content