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

Side by Side Diff: content/zygote/zygote_linux.cc

Issue 1508213002: Replace ScopedVector<ScopedFD> with std::vector<ScopedFD> (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix build Created 5 years 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/zygote/zygote_linux.h" 5 #include "content/zygote/zygote_linux.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <fcntl.h> 8 #include <fcntl.h>
9 #include <poll.h> 9 #include <poll.h>
10 #include <signal.h> 10 #include <signal.h>
11 #include <stdint.h> 11 #include <stdint.h>
12 #include <string.h> 12 #include <string.h>
13 #include <sys/socket.h> 13 #include <sys/socket.h>
14 #include <sys/types.h> 14 #include <sys/types.h>
15 #include <sys/wait.h> 15 #include <sys/wait.h>
16 #include <utility> 16 #include <utility>
jln (very slow on Chromium) 2015/12/08 23:06:24 Nit: vertical space Also include vector.
mdempsky 2015/12/08 23:13:55 Done.
17 17
18 #include "base/command_line.h" 18 #include "base/command_line.h"
19 #include "base/files/file_util.h" 19 #include "base/files/file_util.h"
20 #include "base/linux_util.h" 20 #include "base/linux_util.h"
21 #include "base/logging.h" 21 #include "base/logging.h"
22 #include "base/macros.h" 22 #include "base/macros.h"
23 #include "base/memory/scoped_vector.h"
24 #include "base/pickle.h" 23 #include "base/pickle.h"
25 #include "base/posix/eintr_wrapper.h" 24 #include "base/posix/eintr_wrapper.h"
26 #include "base/posix/global_descriptors.h" 25 #include "base/posix/global_descriptors.h"
27 #include "base/posix/unix_domain_socket_linux.h" 26 #include "base/posix/unix_domain_socket_linux.h"
28 #include "base/process/kill.h" 27 #include "base/process/kill.h"
29 #include "base/process/launch.h" 28 #include "base/process/launch.h"
30 #include "base/process/process.h" 29 #include "base/process/process.h"
31 #include "base/process/process_handle.h" 30 #include "base/process/process_handle.h"
32 #include "base/time/time.h" 31 #include "base/time/time.h"
33 #include "base/trace_event/trace_event.h" 32 #include "base/trace_event/trace_event.h"
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 221
223 bool Zygote::UsingSUIDSandbox() const { 222 bool Zygote::UsingSUIDSandbox() const {
224 return sandbox_flags_ & kSandboxLinuxSUID; 223 return sandbox_flags_ & kSandboxLinuxSUID;
225 } 224 }
226 225
227 bool Zygote::UsingNSSandbox() const { 226 bool Zygote::UsingNSSandbox() const {
228 return sandbox_flags_ & kSandboxLinuxUserNS; 227 return sandbox_flags_ & kSandboxLinuxUserNS;
229 } 228 }
230 229
231 bool Zygote::HandleRequestFromBrowser(int fd) { 230 bool Zygote::HandleRequestFromBrowser(int fd) {
232 ScopedVector<base::ScopedFD> fds; 231 std::vector<base::ScopedFD> fds;
233 char buf[kZygoteMaxMessageLength]; 232 char buf[kZygoteMaxMessageLength];
234 const ssize_t len = base::UnixDomainSocket::RecvMsg( 233 const ssize_t len = base::UnixDomainSocket::RecvMsg(
235 fd, buf, sizeof(buf), &fds); 234 fd, buf, sizeof(buf), &fds);
236 235
237 if (len == 0 || (len == -1 && errno == ECONNRESET)) { 236 if (len == 0 || (len == -1 && errno == ECONNRESET)) {
238 // EOF from the browser. We should die. 237 // EOF from the browser. We should die.
239 // TODO(earthdok): call __sanititizer_cov_dump() here to obtain code 238 // TODO(earthdok): call __sanititizer_cov_dump() here to obtain code
240 // coverage for the Zygote. Currently it's not possible because of 239 // coverage for the Zygote. Currently it's not possible because of
241 // confusion over who is responsible for closing the file descriptor. 240 // confusion over who is responsible for closing the file descriptor.
242 for (std::vector<int>::iterator it = extra_fds_.begin(); 241 for (int fd : extra_fds_) {
243 it < extra_fds_.end(); ++it) { 242 PCHECK(0 == IGNORE_EINTR(close(fd)));
244 PCHECK(0 == IGNORE_EINTR(close(*it)));
245 } 243 }
246 #if !defined(SANITIZER_COVERAGE) 244 #if !defined(SANITIZER_COVERAGE)
247 // TODO(earthdok): add watchdog thread before using this in builds not 245 // TODO(earthdok): add watchdog thread before using this in builds not
248 // using sanitizer coverage. 246 // using sanitizer coverage.
249 CHECK(extra_children_.empty()); 247 CHECK(extra_children_.empty());
250 #endif 248 #endif
251 for (std::vector<base::ProcessHandle>::iterator it = 249 for (base::ProcessHandle pid : extra_children_) {
252 extra_children_.begin(); 250 PCHECK(pid == HANDLE_EINTR(waitpid(pid, NULL, 0)));
253 it < extra_children_.end(); ++it) {
254 PCHECK(*it == HANDLE_EINTR(waitpid(*it, NULL, 0)));
255 } 251 }
256 _exit(0); 252 _exit(0);
257 return false; 253 return false;
258 } 254 }
259 255
260 if (len == -1) { 256 if (len == -1) {
261 PLOG(ERROR) << "Error reading message from browser"; 257 PLOG(ERROR) << "Error reading message from browser";
262 return false; 258 return false;
263 } 259 }
264 260
265 base::Pickle pickle(buf, len); 261 base::Pickle pickle(buf, len);
266 base::PickleIterator iter(pickle); 262 base::PickleIterator iter(pickle);
267 263
268 int kind; 264 int kind;
269 if (iter.ReadInt(&kind)) { 265 if (iter.ReadInt(&kind)) {
270 switch (kind) { 266 switch (kind) {
271 case kZygoteCommandFork: 267 case kZygoteCommandFork:
272 // This function call can return multiple times, once per fork(). 268 // This function call can return multiple times, once per fork().
273 return HandleForkRequest(fd, iter, fds.Pass()); 269 return HandleForkRequest(fd, iter, std::move(fds));
274 270
275 case kZygoteCommandReap: 271 case kZygoteCommandReap:
276 if (!fds.empty()) 272 if (!fds.empty())
277 break; 273 break;
278 HandleReapRequest(fd, iter); 274 HandleReapRequest(fd, iter);
279 return false; 275 return false;
280 case kZygoteCommandGetTerminationStatus: 276 case kZygoteCommandGetTerminationStatus:
281 if (!fds.empty()) 277 if (!fds.empty())
282 break; 278 break;
283 HandleGetTerminationStatus(fd, iter); 279 HandleGetTerminationStatus(fd, iter);
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 } 494 }
499 495
500 // In the parent process. 496 // In the parent process.
501 read_pipe.reset(); 497 read_pipe.reset();
502 pid_oracle.reset(); 498 pid_oracle.reset();
503 499
504 // Always receive a real PID from the zygote host, though it might 500 // Always receive a real PID from the zygote host, though it might
505 // be invalid (see below). 501 // be invalid (see below).
506 base::ProcessId real_pid; 502 base::ProcessId real_pid;
507 { 503 {
508 ScopedVector<base::ScopedFD> recv_fds; 504 std::vector<base::ScopedFD> recv_fds;
509 char buf[kZygoteMaxMessageLength]; 505 char buf[kZygoteMaxMessageLength];
510 const ssize_t len = base::UnixDomainSocket::RecvMsg( 506 const ssize_t len = base::UnixDomainSocket::RecvMsg(
511 kZygoteSocketPairFd, buf, sizeof(buf), &recv_fds); 507 kZygoteSocketPairFd, buf, sizeof(buf), &recv_fds);
512 CHECK_GT(len, 0); 508 CHECK_GT(len, 0);
513 CHECK(recv_fds.empty()); 509 CHECK(recv_fds.empty());
514 510
515 base::Pickle pickle(buf, len); 511 base::Pickle pickle(buf, len);
516 base::PickleIterator iter(pickle); 512 base::PickleIterator iter(pickle);
517 513
518 int kind; 514 int kind;
(...skipping 29 matching lines...) Expand all
548 LOG(ERROR) << "Already tracking PID " << real_pid; 544 LOG(ERROR) << "Already tracking PID " << real_pid;
549 NOTREACHED(); 545 NOTREACHED();
550 } 546 }
551 process_info_map_[real_pid].internal_pid = pid; 547 process_info_map_[real_pid].internal_pid = pid;
552 process_info_map_[real_pid].started_from_helper = helper; 548 process_info_map_[real_pid].started_from_helper = helper;
553 549
554 return real_pid; 550 return real_pid;
555 } 551 }
556 552
557 base::ProcessId Zygote::ReadArgsAndFork(base::PickleIterator iter, 553 base::ProcessId Zygote::ReadArgsAndFork(base::PickleIterator iter,
558 ScopedVector<base::ScopedFD> fds, 554 std::vector<base::ScopedFD> fds,
559 std::string* uma_name, 555 std::string* uma_name,
560 int* uma_sample, 556 int* uma_sample,
561 int* uma_boundary_value) { 557 int* uma_boundary_value) {
562 std::vector<std::string> args; 558 std::vector<std::string> args;
563 int argc = 0; 559 int argc = 0;
564 int numfds = 0; 560 int numfds = 0;
565 base::GlobalDescriptors::Mapping mapping; 561 base::GlobalDescriptors::Mapping mapping;
566 std::string process_type; 562 std::string process_type;
567 std::string channel_id; 563 std::string channel_id;
568 const std::string channel_id_prefix = std::string("--") 564 const std::string channel_id_prefix = std::string("--")
(...skipping 14 matching lines...) Expand all
583 } 579 }
584 580
585 if (!iter.ReadInt(&numfds)) 581 if (!iter.ReadInt(&numfds))
586 return -1; 582 return -1;
587 if (numfds != static_cast<int>(fds.size())) 583 if (numfds != static_cast<int>(fds.size()))
588 return -1; 584 return -1;
589 585
590 // First FD is the PID oracle socket. 586 // First FD is the PID oracle socket.
591 if (fds.size() < 1) 587 if (fds.size() < 1)
592 return -1; 588 return -1;
593 base::ScopedFD pid_oracle(std::move(*fds[0])); 589 base::ScopedFD pid_oracle(std::move(fds[0]));
594 590
595 // Remaining FDs are for the global descriptor mapping. 591 // Remaining FDs are for the global descriptor mapping.
596 for (int i = 1; i < numfds; ++i) { 592 for (int i = 1; i < numfds; ++i) {
597 base::GlobalDescriptors::Key key; 593 base::GlobalDescriptors::Key key;
598 if (!iter.ReadUInt32(&key)) 594 if (!iter.ReadUInt32(&key))
599 return -1; 595 return -1;
600 mapping.push_back(base::GlobalDescriptors::Descriptor(key, fds[i]->get())); 596 mapping.push_back(base::GlobalDescriptors::Descriptor(key, fds[i].get()));
601 } 597 }
602 598
603 mapping.push_back(base::GlobalDescriptors::Descriptor( 599 mapping.push_back(base::GlobalDescriptors::Descriptor(
604 static_cast<uint32_t>(kSandboxIPCChannel), GetSandboxFD())); 600 static_cast<uint32_t>(kSandboxIPCChannel), GetSandboxFD()));
605 601
606 // Returns twice, once per process. 602 // Returns twice, once per process.
607 base::ProcessId child_pid = 603 base::ProcessId child_pid =
608 ForkWithRealPid(process_type, mapping, channel_id, std::move(pid_oracle), 604 ForkWithRealPid(process_type, mapping, channel_id, std::move(pid_oracle),
609 uma_name, uma_sample, uma_boundary_value); 605 uma_name, uma_sample, uma_boundary_value);
610 if (!child_pid) { 606 if (!child_pid) {
611 // This is the child process. 607 // This is the child process.
612 608
613 // Our socket from the browser. 609 // Our socket from the browser.
614 PCHECK(0 == IGNORE_EINTR(close(kZygoteSocketPairFd))); 610 PCHECK(0 == IGNORE_EINTR(close(kZygoteSocketPairFd)));
615 611
616 // Pass ownership of file descriptors from fds to GlobalDescriptors. 612 // Pass ownership of file descriptors from fds to GlobalDescriptors.
617 for (ScopedVector<base::ScopedFD>::iterator i = fds.begin(); i != fds.end(); 613 for (base::ScopedFD& fd : fds)
618 ++i) 614 ignore_result(fd.release());
619 ignore_result((*i)->release());
620 base::GlobalDescriptors::GetInstance()->Reset(mapping); 615 base::GlobalDescriptors::GetInstance()->Reset(mapping);
621 616
622 // Reset the process-wide command line to our new command line. 617 // Reset the process-wide command line to our new command line.
623 base::CommandLine::Reset(); 618 base::CommandLine::Reset();
624 base::CommandLine::Init(0, NULL); 619 base::CommandLine::Init(0, NULL);
625 base::CommandLine::ForCurrentProcess()->InitFromArgv(args); 620 base::CommandLine::ForCurrentProcess()->InitFromArgv(args);
626 621
627 // Update the process title. The argv was already cached by the call to 622 // Update the process title. The argv was already cached by the call to
628 // SetProcessTitleFromCommandLine in ChromeMain, so we can pass NULL here 623 // SetProcessTitleFromCommandLine in ChromeMain, so we can pass NULL here
629 // (we don't have the original argv at this point). 624 // (we don't have the original argv at this point).
630 SetProcessTitleFromCommandLine(NULL); 625 SetProcessTitleFromCommandLine(NULL);
631 } else if (child_pid < 0) { 626 } else if (child_pid < 0) {
632 LOG(ERROR) << "Zygote could not fork: process_type " << process_type 627 LOG(ERROR) << "Zygote could not fork: process_type " << process_type
633 << " numfds " << numfds << " child_pid " << child_pid; 628 << " numfds " << numfds << " child_pid " << child_pid;
634 } 629 }
635 return child_pid; 630 return child_pid;
636 } 631 }
637 632
638 bool Zygote::HandleForkRequest(int fd, 633 bool Zygote::HandleForkRequest(int fd,
639 base::PickleIterator iter, 634 base::PickleIterator iter,
640 ScopedVector<base::ScopedFD> fds) { 635 std::vector<base::ScopedFD> fds) {
641 std::string uma_name; 636 std::string uma_name;
642 int uma_sample; 637 int uma_sample;
643 int uma_boundary_value; 638 int uma_boundary_value;
644 base::ProcessId child_pid = ReadArgsAndFork( 639 base::ProcessId child_pid = ReadArgsAndFork(
645 iter, fds.Pass(), &uma_name, &uma_sample, &uma_boundary_value); 640 iter, std::move(fds), &uma_name, &uma_sample, &uma_boundary_value);
646 if (child_pid == 0) 641 if (child_pid == 0)
647 return true; 642 return true;
648 // If there's no UMA report for this particular fork, then check if any 643 // If there's no UMA report for this particular fork, then check if any
649 // helpers have an initial UMA report for us to send instead. 644 // helpers have an initial UMA report for us to send instead.
650 while (uma_name.empty() && initial_uma_index_ < helpers_.size()) { 645 while (uma_name.empty() && initial_uma_index_ < helpers_.size()) {
651 helpers_[initial_uma_index_++]->InitialUMA( 646 helpers_[initial_uma_index_++]->InitialUMA(
652 &uma_name, &uma_sample, &uma_boundary_value); 647 &uma_name, &uma_sample, &uma_boundary_value);
653 } 648 }
654 // Must always send reply, as ZygoteHost blocks while waiting for it. 649 // Must always send reply, as ZygoteHost blocks while waiting for it.
655 base::Pickle reply_pickle; 650 base::Pickle reply_pickle;
(...skipping 12 matching lines...) Expand all
668 bool Zygote::HandleGetSandboxStatus(int fd, base::PickleIterator iter) { 663 bool Zygote::HandleGetSandboxStatus(int fd, base::PickleIterator iter) {
669 if (HANDLE_EINTR(write(fd, &sandbox_flags_, sizeof(sandbox_flags_))) != 664 if (HANDLE_EINTR(write(fd, &sandbox_flags_, sizeof(sandbox_flags_))) !=
670 sizeof(sandbox_flags_)) { 665 sizeof(sandbox_flags_)) {
671 PLOG(ERROR) << "write"; 666 PLOG(ERROR) << "write";
672 } 667 }
673 668
674 return false; 669 return false;
675 } 670 }
676 671
677 } // namespace content 672 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698