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 |