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"
9 #include <sys/socket.h>
10 #include <sys/types.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"
40 #if defined(ADDRESS_SANITIZER)
41 #include <sanitizer/asan_interface.h>
44 // See http://code.google.com/p/chromium/wiki/LinuxZygote
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
;
62 void CreatePipe(base::ScopedFD
* read_pipe
, base::ScopedFD
* write_pipe
) {
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
) {
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";
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)));
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
) {}
100 bool Zygote::ProcessRequests() {
101 // A SOCK_SEQPACKET socket is installed in fd 3. We get commands from the
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
,
118 sizeof(kZygoteHelloMessage
),
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.
126 _exit(RESULT_CODE_NORMAL_EXIT
);
128 CHECK(r
) << "Sending zygote magic failed";
133 // This function call can return multiple times, once per fork().
134 if (HandleRequestFromBrowser(kZygoteSocketPairFd
))
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()) {
146 *process_info
= it
->second
;
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());
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)));
182 PLOG(ERROR
) << "Error reading message from browser";
186 Pickle
pickle(buf
, len
);
187 PickleIterator
iter(pickle
);
190 if (iter
.ReadInt(&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
:
199 HandleReapRequest(fd
, iter
);
201 case kZygoteCommandGetTerminationStatus
:
204 HandleGetTerminationStatus(fd
, iter
);
206 case kZygoteCommandGetSandboxStatus
:
207 HandleGetSandboxStatus(fd
, iter
);
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";
222 LOG(WARNING
) << "Error parsing message from browser";
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";
236 ZygoteProcessInfo child_info
;
237 if (!GetProcessInfo(child
, &child_info
)) {
238 LOG(ERROR
) << "Child not found!";
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
));
255 LOG(WARNING
) << "Zygote process omitting a call to "
256 << "base::EnsureProcessTerminated() for child pid " << child
257 << " under ThreadSanitizer. See http://crbug.com/274855.";
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
;
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
,
275 base::TerminationStatus
* status
,
278 ZygoteProcessInfo child_info
;
279 if (!GetProcessInfo(real_pid
, &child_info
)) {
280 LOG(ERROR
) << "Zygote::GetTerminationStatus for unknown PID "
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
)) {
293 // Handle the request directly.
295 *status
= base::GetKnownDeadTerminationStatus(child
, exit_code
);
297 // We don't know if the process is dying, so get its status but don't
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
);
310 void Zygote::HandleGetTerminationStatus(int fd
,
311 PickleIterator iter
) {
313 base::ProcessHandle child_requested
;
315 if (!iter
.ReadBool(&known_dead
) || !iter
.ReadInt(&child_requested
)) {
316 LOG(WARNING
) << "Error parsing GetTerminationStatus request "
321 base::TerminationStatus status
;
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.
330 status
= base::TERMINATION_STATUS_NORMAL_TERMINATION
;
331 exit_code
= RESULT_CODE_NORMAL_EXIT
;
335 write_pickle
.WriteInt(static_cast<int>(status
));
336 write_pickle
.WriteInt(exit_code
);
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
,
349 int* uma_boundary_value
) {
350 ZygoteForkDelegate
* helper
= NULL
;
351 for (ScopedVector
<ZygoteForkDelegate
>::iterator i
= helpers_
.begin();
354 if ((*i
)->CanHelp(process_type
, uma_name
, uma_sample
, uma_boundary_value
)) {
360 base::ScopedFD read_pipe
, write_pipe
;
361 base::ProcessId pid
= 0;
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";
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.
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);
383 // In the child process.
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
),
394 LOG(FATAL
) << "Failed to synchronise with parent zygote process";
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::trace_event::TraceLog::GetInstance()->SetProcessID(
406 static_cast<int>(real_pid
));
411 // In the parent process.
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
);
424 CHECK(recv_fds
.empty());
426 Pickle
pickle(buf
, len
);
427 PickleIterator
iter(pickle
);
430 CHECK(iter
.ReadInt(&kind
));
431 CHECK(kind
== kZygoteCommandForkRealPID
);
432 CHECK(iter
.ReadInt(&real_pid
));
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.
443 KillAndReap(pid
, helper
);
447 // If we're not using a helper, send the PID back to the child process.
450 HANDLE_EINTR(write(write_pipe
.get(), &real_pid
, sizeof(real_pid
)));
451 if (written
!= sizeof(real_pid
)) {
452 KillAndReap(pid
, helper
);
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
;
462 process_info_map_
[real_pid
].internal_pid
= pid
;
463 process_info_map_
[real_pid
].started_from_helper
= helper
;
468 base::ProcessId
Zygote::ReadArgsAndFork(PickleIterator iter
,
469 ScopedVector
<base::ScopedFD
> fds
,
470 std::string
* uma_name
,
472 int* uma_boundary_value
) {
473 std::vector
<std::string
> args
;
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
))
484 if (!iter
.ReadInt(&argc
))
487 for (int i
= 0; i
< argc
; ++i
) {
489 if (!iter
.ReadString(&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
))
498 if (numfds
!= static_cast<int>(fds
.size()))
501 // First FD is the PID oracle socket.
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
))
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
,
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();
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
;
553 bool Zygote::HandleForkRequest(int fd
,
555 ScopedVector
<base::ScopedFD
> fds
) {
556 std::string uma_name
;
558 int uma_boundary_value
;
559 base::ProcessId child_pid
= ReadArgsAndFork(
560 iter
, fds
.Pass(), &uma_name
, &uma_sample
, &uma_boundary_value
);
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.
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";
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";
593 } // namespace content