OLD | NEW |
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_main.h" | 5 #include "content/zygote/zygote_main.h" |
6 | 6 |
7 #include <dlfcn.h> | 7 #include <dlfcn.h> |
8 #include <fcntl.h> | 8 #include <fcntl.h> |
9 #include <pthread.h> | 9 #include <pthread.h> |
10 #include <signal.h> | 10 #include <signal.h> |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 | 55 |
56 #if defined(ENABLE_PLUGINS) | 56 #if defined(ENABLE_PLUGINS) |
57 #include "content/common/pepper_plugin_list.h" | 57 #include "content/common/pepper_plugin_list.h" |
58 #include "content/public/common/pepper_plugin_info.h" | 58 #include "content/public/common/pepper_plugin_info.h" |
59 #endif | 59 #endif |
60 | 60 |
61 #if defined(ENABLE_WEBRTC) | 61 #if defined(ENABLE_WEBRTC) |
62 #include "third_party/libjingle/overrides/init_webrtc.h" | 62 #include "third_party/libjingle/overrides/init_webrtc.h" |
63 #endif | 63 #endif |
64 | 64 |
65 #if defined(ADDRESS_SANITIZER) | 65 #if defined(SANITIZER_COVERAGE) |
66 #include <sanitizer/asan_interface.h> | 66 #include <sanitizer/common_interface_defs.h> |
67 #endif | 67 #endif |
68 | 68 |
69 namespace content { | 69 namespace content { |
70 | 70 |
71 namespace { | 71 namespace { |
72 | 72 |
73 void DoChrootSignalHandler(int) { | 73 void DoChrootSignalHandler(int) { |
74 const int old_errno = errno; | 74 const int old_errno = errno; |
75 const char kFirstMessage[] = "Chroot signal handler called.\n"; | 75 const char kFirstMessage[] = "Chroot signal handler called.\n"; |
76 ignore_result(write(STDERR_FILENO, kFirstMessage, sizeof(kFirstMessage) - 1)); | 76 ignore_result(write(STDERR_FILENO, kFirstMessage, sizeof(kFirstMessage) - 1)); |
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
463 // If sandbox debugging is allowed, install a handler for sandbox-related | 463 // If sandbox debugging is allowed, install a handler for sandbox-related |
464 // crash testing. | 464 // crash testing. |
465 InstallSandboxCrashTestHandler(); | 465 InstallSandboxCrashTestHandler(); |
466 } | 466 } |
467 | 467 |
468 #endif | 468 #endif |
469 | 469 |
470 return true; | 470 return true; |
471 } | 471 } |
472 | 472 |
473 #if defined(ADDRESS_SANITIZER) | 473 #if defined(SANITIZER_COVERAGE) |
474 const size_t kSanitizerMaxMessageLength = 1 * 1024 * 1024; | 474 const size_t kSanitizerMaxMessageLength = 1 * 1024 * 1024; |
475 | 475 |
476 // A helper process which collects code coverage data from the renderers over a | 476 // A helper process which collects code coverage data from the renderers over a |
477 // socket and dumps it to a file. See http://crbug.com/336212 for discussion. | 477 // socket and dumps it to a file. See http://crbug.com/336212 for discussion. |
478 static void SanitizerCoverageHelper(int socket_fd, int file_fd) { | 478 static void SanitizerCoverageHelper(int socket_fd, int file_fd) { |
479 scoped_ptr<char[]> buffer(new char[kSanitizerMaxMessageLength]); | 479 scoped_ptr<char[]> buffer(new char[kSanitizerMaxMessageLength]); |
480 while (true) { | 480 while (true) { |
481 ssize_t received_size = HANDLE_EINTR( | 481 ssize_t received_size = HANDLE_EINTR( |
482 recv(socket_fd, buffer.get(), kSanitizerMaxMessageLength, 0)); | 482 recv(socket_fd, buffer.get(), kSanitizerMaxMessageLength, 0)); |
483 PCHECK(received_size >= 0); | 483 PCHECK(received_size >= 0); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
517 CloseFds(extra_fds_to_close); | 517 CloseFds(extra_fds_to_close); |
518 SanitizerCoverageHelper(child_fd, file_fd.get()); | 518 SanitizerCoverageHelper(child_fd, file_fd.get()); |
519 _exit(0); | 519 _exit(0); |
520 } else { | 520 } else { |
521 // In the parent. | 521 // In the parent. |
522 PCHECK(0 == IGNORE_EINTR(close(child_fd))); | 522 PCHECK(0 == IGNORE_EINTR(close(child_fd))); |
523 return pid; | 523 return pid; |
524 } | 524 } |
525 } | 525 } |
526 | 526 |
527 #endif // defined(ADDRESS_SANITIZER) | 527 #endif // defined(SANITIZER_COVERAGE) |
528 | 528 |
529 // If |is_suid_sandbox_child|, then make sure that the setuid sandbox is | 529 // If |is_suid_sandbox_child|, then make sure that the setuid sandbox is |
530 // engaged. | 530 // engaged. |
531 static void EnterLayerOneSandbox(LinuxSandbox* linux_sandbox, | 531 static void EnterLayerOneSandbox(LinuxSandbox* linux_sandbox, |
532 bool is_suid_sandbox_child, | 532 bool is_suid_sandbox_child, |
533 base::Closure* post_fork_parent_callback) { | 533 base::Closure* post_fork_parent_callback) { |
534 DCHECK(linux_sandbox); | 534 DCHECK(linux_sandbox); |
535 | 535 |
536 ZygotePreSandboxInit(); | 536 ZygotePreSandboxInit(); |
537 | 537 |
(...skipping 13 matching lines...) Expand all Loading... |
551 | 551 |
552 bool ZygoteMain(const MainFunctionParams& params, | 552 bool ZygoteMain(const MainFunctionParams& params, |
553 ScopedVector<ZygoteForkDelegate> fork_delegates) { | 553 ScopedVector<ZygoteForkDelegate> fork_delegates) { |
554 g_am_zygote_or_renderer = true; | 554 g_am_zygote_or_renderer = true; |
555 sandbox::InitLibcUrandomOverrides(); | 555 sandbox::InitLibcUrandomOverrides(); |
556 | 556 |
557 std::vector<int> fds_to_close_post_fork; | 557 std::vector<int> fds_to_close_post_fork; |
558 | 558 |
559 LinuxSandbox* linux_sandbox = LinuxSandbox::GetInstance(); | 559 LinuxSandbox* linux_sandbox = LinuxSandbox::GetInstance(); |
560 | 560 |
561 #if defined(ADDRESS_SANITIZER) | 561 #if defined(SANITIZER_COVERAGE) |
562 const std::string sancov_file_name = | 562 const std::string sancov_file_name = |
563 "zygote." + base::Uint64ToString(base::RandUint64()); | 563 "zygote." + base::Uint64ToString(base::RandUint64()); |
564 base::ScopedFD sancov_file_fd( | 564 base::ScopedFD sancov_file_fd( |
565 __sanitizer_maybe_open_cov_file(sancov_file_name.c_str())); | 565 __sanitizer_maybe_open_cov_file(sancov_file_name.c_str())); |
566 int sancov_socket_fds[2] = {-1, -1}; | 566 int sancov_socket_fds[2] = {-1, -1}; |
567 CreateSanitizerCoverageSocketPair(sancov_socket_fds); | 567 CreateSanitizerCoverageSocketPair(sancov_socket_fds); |
568 linux_sandbox->sanitizer_args()->coverage_sandboxed = 1; | 568 linux_sandbox->sanitizer_args()->coverage_sandboxed = 1; |
569 linux_sandbox->sanitizer_args()->coverage_fd = sancov_socket_fds[1]; | 569 linux_sandbox->sanitizer_args()->coverage_fd = sancov_socket_fds[1]; |
570 linux_sandbox->sanitizer_args()->coverage_max_block_size = | 570 linux_sandbox->sanitizer_args()->coverage_max_block_size = |
571 kSanitizerMaxMessageLength; | 571 kSanitizerMaxMessageLength; |
572 // Zygote termination will block until the helper process exits, which will | 572 // Zygote termination will block until the helper process exits, which will |
573 // not happen until the write end of the socket is closed everywhere. Make | 573 // not happen until the write end of the socket is closed everywhere. Make |
574 // sure the init process does not hold on to it. | 574 // sure the init process does not hold on to it. |
575 fds_to_close_post_fork.push_back(sancov_socket_fds[0]); | 575 fds_to_close_post_fork.push_back(sancov_socket_fds[0]); |
576 fds_to_close_post_fork.push_back(sancov_socket_fds[1]); | 576 fds_to_close_post_fork.push_back(sancov_socket_fds[1]); |
577 #endif | 577 #endif // SANITIZER_COVERAGE |
578 | 578 |
579 // Skip pre-initializing sandbox under --no-sandbox for crbug.com/444900. | 579 // Skip pre-initializing sandbox under --no-sandbox for crbug.com/444900. |
580 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( | 580 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( |
581 switches::kNoSandbox)) { | 581 switches::kNoSandbox)) { |
582 // This will pre-initialize the various sandboxes that need it. | 582 // This will pre-initialize the various sandboxes that need it. |
583 linux_sandbox->PreinitializeSandbox(); | 583 linux_sandbox->PreinitializeSandbox(); |
584 } | 584 } |
585 | 585 |
586 const bool must_enable_setuid_sandbox = | 586 const bool must_enable_setuid_sandbox = |
587 linux_sandbox->setuid_sandbox_client()->IsSuidSandboxChild(); | 587 linux_sandbox->setuid_sandbox_client()->IsSuidSandboxChild(); |
(...skipping 26 matching lines...) Expand all Loading... |
614 | 614 |
615 // Turn on the first layer of the sandbox if the configuration warrants it. | 615 // Turn on the first layer of the sandbox if the configuration warrants it. |
616 EnterLayerOneSandbox(linux_sandbox, must_enable_setuid_sandbox, | 616 EnterLayerOneSandbox(linux_sandbox, must_enable_setuid_sandbox, |
617 &post_fork_parent_callback); | 617 &post_fork_parent_callback); |
618 | 618 |
619 // Extra children and file descriptors created that the Zygote must have | 619 // Extra children and file descriptors created that the Zygote must have |
620 // knowledge of. | 620 // knowledge of. |
621 std::vector<pid_t> extra_children; | 621 std::vector<pid_t> extra_children; |
622 std::vector<int> extra_fds; | 622 std::vector<int> extra_fds; |
623 | 623 |
624 #if defined(ADDRESS_SANITIZER) | 624 #if defined(SANITIZER_COVERAGE) |
625 pid_t sancov_helper_pid = ForkSanitizerCoverageHelper( | 625 pid_t sancov_helper_pid = ForkSanitizerCoverageHelper( |
626 sancov_socket_fds[0], sancov_socket_fds[1], sancov_file_fd.Pass(), | 626 sancov_socket_fds[0], sancov_socket_fds[1], sancov_file_fd.Pass(), |
627 sandbox_fds_to_close_post_fork); | 627 sandbox_fds_to_close_post_fork); |
628 // It's important that the zygote reaps the helper before dying. Otherwise, | 628 // It's important that the zygote reaps the helper before dying. Otherwise, |
629 // the destruction of the PID namespace could kill the helper before it | 629 // the destruction of the PID namespace could kill the helper before it |
630 // completes its I/O tasks. |sancov_helper_pid| will exit once the last | 630 // completes its I/O tasks. |sancov_helper_pid| will exit once the last |
631 // renderer holding the write end of |sancov_socket_fds| closes it. | 631 // renderer holding the write end of |sancov_socket_fds| closes it. |
632 extra_children.push_back(sancov_helper_pid); | 632 extra_children.push_back(sancov_helper_pid); |
633 // Sanitizer code in the renderers will inherit the write end of the socket | 633 // Sanitizer code in the renderers will inherit the write end of the socket |
634 // from the zygote. We must keep it open until the very end of the zygote's | 634 // from the zygote. We must keep it open until the very end of the zygote's |
635 // lifetime, even though we don't explicitly use it. | 635 // lifetime, even though we don't explicitly use it. |
636 extra_fds.push_back(sancov_socket_fds[1]); | 636 extra_fds.push_back(sancov_socket_fds[1]); |
637 #endif | 637 #endif // SANITIZER_COVERAGE |
638 | 638 |
639 int sandbox_flags = linux_sandbox->GetStatus(); | 639 int sandbox_flags = linux_sandbox->GetStatus(); |
640 bool setuid_sandbox_engaged = sandbox_flags & kSandboxLinuxSUID; | 640 bool setuid_sandbox_engaged = sandbox_flags & kSandboxLinuxSUID; |
641 CHECK_EQ(must_enable_setuid_sandbox, setuid_sandbox_engaged); | 641 CHECK_EQ(must_enable_setuid_sandbox, setuid_sandbox_engaged); |
642 | 642 |
643 Zygote zygote(sandbox_flags, fork_delegates.Pass(), extra_children, | 643 Zygote zygote(sandbox_flags, fork_delegates.Pass(), extra_children, |
644 extra_fds); | 644 extra_fds); |
645 // This function call can return multiple times, once per fork(). | 645 // This function call can return multiple times, once per fork(). |
646 return zygote.ProcessRequests(); | 646 return zygote.ProcessRequests(); |
647 } | 647 } |
648 | 648 |
649 } // namespace content | 649 } // namespace content |
OLD | NEW |