| 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 |