| 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 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 58 | 58 |
| 59 #if defined(ENABLE_PLUGINS) | 59 #if defined(ENABLE_PLUGINS) |
| 60 #include "content/common/pepper_plugin_list.h" | 60 #include "content/common/pepper_plugin_list.h" |
| 61 #include "content/public/common/pepper_plugin_info.h" | 61 #include "content/public/common/pepper_plugin_info.h" |
| 62 #endif | 62 #endif |
| 63 | 63 |
| 64 #if defined(ENABLE_WEBRTC) | 64 #if defined(ENABLE_WEBRTC) |
| 65 #include "third_party/libjingle/overrides/init_webrtc.h" | 65 #include "third_party/libjingle/overrides/init_webrtc.h" |
| 66 #endif | 66 #endif |
| 67 | 67 |
| 68 #if defined(ADDRESS_SANITIZER) | 68 #if defined(SANITIZER_COVERAGE) |
| 69 #include <sanitizer/asan_interface.h> | 69 #include <sanitizer/common_interface_defs.h> |
| 70 #endif | 70 #endif |
| 71 | 71 |
| 72 namespace content { | 72 namespace content { |
| 73 | 73 |
| 74 namespace { | 74 namespace { |
| 75 | 75 |
| 76 void CloseFds(const std::vector<int>& fds) { | 76 void CloseFds(const std::vector<int>& fds) { |
| 77 for (const auto& it : fds) { | 77 for (const auto& it : fds) { |
| 78 PCHECK(0 == IGNORE_EINTR(close(it))); | 78 PCHECK(0 == IGNORE_EINTR(close(it))); |
| 79 } | 79 } |
| (...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 408 | 408 |
| 409 static void EnterNamespaceSandbox(LinuxSandbox* linux_sandbox, | 409 static void EnterNamespaceSandbox(LinuxSandbox* linux_sandbox, |
| 410 base::Closure* post_fork_parent_callback) { | 410 base::Closure* post_fork_parent_callback) { |
| 411 linux_sandbox->EngageNamespaceSandbox(); | 411 linux_sandbox->EngageNamespaceSandbox(); |
| 412 | 412 |
| 413 if (getpid() == 1) { | 413 if (getpid() == 1) { |
| 414 CHECK(CreateInitProcessReaper(post_fork_parent_callback)); | 414 CHECK(CreateInitProcessReaper(post_fork_parent_callback)); |
| 415 } | 415 } |
| 416 } | 416 } |
| 417 | 417 |
| 418 #if defined(ADDRESS_SANITIZER) | 418 #if defined(SANITIZER_COVERAGE) |
| 419 const size_t kSanitizerMaxMessageLength = 1 * 1024 * 1024; | 419 const size_t kSanitizerMaxMessageLength = 1 * 1024 * 1024; |
| 420 | 420 |
| 421 // A helper process which collects code coverage data from the renderers over a | 421 // A helper process which collects code coverage data from the renderers over a |
| 422 // socket and dumps it to a file. See http://crbug.com/336212 for discussion. | 422 // socket and dumps it to a file. See http://crbug.com/336212 for discussion. |
| 423 static void SanitizerCoverageHelper(int socket_fd, int file_fd) { | 423 static void SanitizerCoverageHelper(int socket_fd, int file_fd) { |
| 424 scoped_ptr<char[]> buffer(new char[kSanitizerMaxMessageLength]); | 424 scoped_ptr<char[]> buffer(new char[kSanitizerMaxMessageLength]); |
| 425 while (true) { | 425 while (true) { |
| 426 ssize_t received_size = HANDLE_EINTR( | 426 ssize_t received_size = HANDLE_EINTR( |
| 427 recv(socket_fd, buffer.get(), kSanitizerMaxMessageLength, 0)); | 427 recv(socket_fd, buffer.get(), kSanitizerMaxMessageLength, 0)); |
| 428 PCHECK(received_size >= 0); | 428 PCHECK(received_size >= 0); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 462 CloseFds(extra_fds_to_close); | 462 CloseFds(extra_fds_to_close); |
| 463 SanitizerCoverageHelper(child_fd, file_fd.get()); | 463 SanitizerCoverageHelper(child_fd, file_fd.get()); |
| 464 _exit(0); | 464 _exit(0); |
| 465 } else { | 465 } else { |
| 466 // In the parent. | 466 // In the parent. |
| 467 PCHECK(0 == IGNORE_EINTR(close(child_fd))); | 467 PCHECK(0 == IGNORE_EINTR(close(child_fd))); |
| 468 return pid; | 468 return pid; |
| 469 } | 469 } |
| 470 } | 470 } |
| 471 | 471 |
| 472 #endif // defined(ADDRESS_SANITIZER) | 472 #endif // defined(SANITIZER_COVERAGE) |
| 473 | 473 |
| 474 static void EnterLayerOneSandbox(LinuxSandbox* linux_sandbox, | 474 static void EnterLayerOneSandbox(LinuxSandbox* linux_sandbox, |
| 475 const bool using_layer1_sandbox, | 475 const bool using_layer1_sandbox, |
| 476 base::Closure* post_fork_parent_callback) { | 476 base::Closure* post_fork_parent_callback) { |
| 477 DCHECK(linux_sandbox); | 477 DCHECK(linux_sandbox); |
| 478 | 478 |
| 479 ZygotePreSandboxInit(); | 479 ZygotePreSandboxInit(); |
| 480 | 480 |
| 481 // Check that the pre-sandbox initialization didn't spawn threads. | 481 // Check that the pre-sandbox initialization didn't spawn threads. |
| 482 #if !defined(THREAD_SANITIZER) | 482 #if !defined(THREAD_SANITIZER) |
| (...skipping 14 matching lines...) Expand all Loading... |
| 497 | 497 |
| 498 bool ZygoteMain(const MainFunctionParams& params, | 498 bool ZygoteMain(const MainFunctionParams& params, |
| 499 ScopedVector<ZygoteForkDelegate> fork_delegates) { | 499 ScopedVector<ZygoteForkDelegate> fork_delegates) { |
| 500 g_am_zygote_or_renderer = true; | 500 g_am_zygote_or_renderer = true; |
| 501 sandbox::InitLibcUrandomOverrides(); | 501 sandbox::InitLibcUrandomOverrides(); |
| 502 | 502 |
| 503 std::vector<int> fds_to_close_post_fork; | 503 std::vector<int> fds_to_close_post_fork; |
| 504 | 504 |
| 505 LinuxSandbox* linux_sandbox = LinuxSandbox::GetInstance(); | 505 LinuxSandbox* linux_sandbox = LinuxSandbox::GetInstance(); |
| 506 | 506 |
| 507 #if defined(ADDRESS_SANITIZER) | 507 #if defined(SANITIZER_COVERAGE) |
| 508 const std::string sancov_file_name = | 508 const std::string sancov_file_name = |
| 509 "zygote." + base::Uint64ToString(base::RandUint64()); | 509 "zygote." + base::Uint64ToString(base::RandUint64()); |
| 510 base::ScopedFD sancov_file_fd( | 510 base::ScopedFD sancov_file_fd( |
| 511 __sanitizer_maybe_open_cov_file(sancov_file_name.c_str())); | 511 __sanitizer_maybe_open_cov_file(sancov_file_name.c_str())); |
| 512 int sancov_socket_fds[2] = {-1, -1}; | 512 int sancov_socket_fds[2] = {-1, -1}; |
| 513 CreateSanitizerCoverageSocketPair(sancov_socket_fds); | 513 CreateSanitizerCoverageSocketPair(sancov_socket_fds); |
| 514 linux_sandbox->sanitizer_args()->coverage_sandboxed = 1; | 514 linux_sandbox->sanitizer_args()->coverage_sandboxed = 1; |
| 515 linux_sandbox->sanitizer_args()->coverage_fd = sancov_socket_fds[1]; | 515 linux_sandbox->sanitizer_args()->coverage_fd = sancov_socket_fds[1]; |
| 516 linux_sandbox->sanitizer_args()->coverage_max_block_size = | 516 linux_sandbox->sanitizer_args()->coverage_max_block_size = |
| 517 kSanitizerMaxMessageLength; | 517 kSanitizerMaxMessageLength; |
| 518 // Zygote termination will block until the helper process exits, which will | 518 // Zygote termination will block until the helper process exits, which will |
| 519 // not happen until the write end of the socket is closed everywhere. Make | 519 // not happen until the write end of the socket is closed everywhere. Make |
| 520 // sure the init process does not hold on to it. | 520 // sure the init process does not hold on to it. |
| 521 fds_to_close_post_fork.push_back(sancov_socket_fds[0]); | 521 fds_to_close_post_fork.push_back(sancov_socket_fds[0]); |
| 522 fds_to_close_post_fork.push_back(sancov_socket_fds[1]); | 522 fds_to_close_post_fork.push_back(sancov_socket_fds[1]); |
| 523 #endif | 523 #endif // SANITIZER_COVERAGE |
| 524 | 524 |
| 525 // Skip pre-initializing sandbox under --no-sandbox for crbug.com/444900. | 525 // Skip pre-initializing sandbox under --no-sandbox for crbug.com/444900. |
| 526 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( | 526 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 527 switches::kNoSandbox)) { | 527 switches::kNoSandbox)) { |
| 528 // This will pre-initialize the various sandboxes that need it. | 528 // This will pre-initialize the various sandboxes that need it. |
| 529 linux_sandbox->PreinitializeSandbox(); | 529 linux_sandbox->PreinitializeSandbox(); |
| 530 } | 530 } |
| 531 | 531 |
| 532 const bool using_setuid_sandbox = | 532 const bool using_setuid_sandbox = |
| 533 linux_sandbox->setuid_sandbox_client()->IsSuidSandboxChild(); | 533 linux_sandbox->setuid_sandbox_client()->IsSuidSandboxChild(); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 563 | 563 |
| 564 // Turn on the first layer of the sandbox if the configuration warrants it. | 564 // Turn on the first layer of the sandbox if the configuration warrants it. |
| 565 EnterLayerOneSandbox(linux_sandbox, using_layer1_sandbox, | 565 EnterLayerOneSandbox(linux_sandbox, using_layer1_sandbox, |
| 566 &post_fork_parent_callback); | 566 &post_fork_parent_callback); |
| 567 | 567 |
| 568 // Extra children and file descriptors created that the Zygote must have | 568 // Extra children and file descriptors created that the Zygote must have |
| 569 // knowledge of. | 569 // knowledge of. |
| 570 std::vector<pid_t> extra_children; | 570 std::vector<pid_t> extra_children; |
| 571 std::vector<int> extra_fds; | 571 std::vector<int> extra_fds; |
| 572 | 572 |
| 573 #if defined(ADDRESS_SANITIZER) | 573 #if defined(SANITIZER_COVERAGE) |
| 574 pid_t sancov_helper_pid = ForkSanitizerCoverageHelper( | 574 pid_t sancov_helper_pid = ForkSanitizerCoverageHelper( |
| 575 sancov_socket_fds[0], sancov_socket_fds[1], sancov_file_fd.Pass(), | 575 sancov_socket_fds[0], sancov_socket_fds[1], sancov_file_fd.Pass(), |
| 576 sandbox_fds_to_close_post_fork); | 576 sandbox_fds_to_close_post_fork); |
| 577 // It's important that the zygote reaps the helper before dying. Otherwise, | 577 // It's important that the zygote reaps the helper before dying. Otherwise, |
| 578 // the destruction of the PID namespace could kill the helper before it | 578 // the destruction of the PID namespace could kill the helper before it |
| 579 // completes its I/O tasks. |sancov_helper_pid| will exit once the last | 579 // completes its I/O tasks. |sancov_helper_pid| will exit once the last |
| 580 // renderer holding the write end of |sancov_socket_fds| closes it. | 580 // renderer holding the write end of |sancov_socket_fds| closes it. |
| 581 extra_children.push_back(sancov_helper_pid); | 581 extra_children.push_back(sancov_helper_pid); |
| 582 // Sanitizer code in the renderers will inherit the write end of the socket | 582 // Sanitizer code in the renderers will inherit the write end of the socket |
| 583 // from the zygote. We must keep it open until the very end of the zygote's | 583 // from the zygote. We must keep it open until the very end of the zygote's |
| 584 // lifetime, even though we don't explicitly use it. | 584 // lifetime, even though we don't explicitly use it. |
| 585 extra_fds.push_back(sancov_socket_fds[1]); | 585 extra_fds.push_back(sancov_socket_fds[1]); |
| 586 #endif | 586 #endif // SANITIZER_COVERAGE |
| 587 | 587 |
| 588 const int sandbox_flags = linux_sandbox->GetStatus(); | 588 const int sandbox_flags = linux_sandbox->GetStatus(); |
| 589 | 589 |
| 590 const bool setuid_sandbox_engaged = sandbox_flags & kSandboxLinuxSUID; | 590 const bool setuid_sandbox_engaged = sandbox_flags & kSandboxLinuxSUID; |
| 591 CHECK_EQ(using_setuid_sandbox, setuid_sandbox_engaged); | 591 CHECK_EQ(using_setuid_sandbox, setuid_sandbox_engaged); |
| 592 | 592 |
| 593 const bool namespace_sandbox_engaged = sandbox_flags & kSandboxLinuxUserNS; | 593 const bool namespace_sandbox_engaged = sandbox_flags & kSandboxLinuxUserNS; |
| 594 CHECK_EQ(using_namespace_sandbox, namespace_sandbox_engaged); | 594 CHECK_EQ(using_namespace_sandbox, namespace_sandbox_engaged); |
| 595 | 595 |
| 596 Zygote zygote(sandbox_flags, fork_delegates.Pass(), extra_children, | 596 Zygote zygote(sandbox_flags, fork_delegates.Pass(), extra_children, |
| 597 extra_fds); | 597 extra_fds); |
| 598 // This function call can return multiple times, once per fork(). | 598 // This function call can return multiple times, once per fork(). |
| 599 return zygote.ProcessRequests(); | 599 return zygote.ProcessRequests(); |
| 600 } | 600 } |
| 601 | 601 |
| 602 } // namespace content | 602 } // namespace content |
| OLD | NEW |