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

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

Issue 280303002: Add sandbox support for AsanCoverage. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: address remaining comments Created 6 years, 7 months 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 | Annotate | Revision Log
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_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 <pthread.h> 9 #include <pthread.h>
9 #include <string.h> 10 #include <string.h>
11 #include <sys/socket.h>
10 #include <sys/types.h> 12 #include <sys/types.h>
11 #include <unistd.h> 13 #include <unistd.h>
12 14
13 #include "base/basictypes.h" 15 #include "base/basictypes.h"
14 #include "base/bind.h" 16 #include "base/bind.h"
15 #include "base/command_line.h" 17 #include "base/command_line.h"
16 #include "base/compiler_specific.h" 18 #include "base/compiler_specific.h"
17 #include "base/memory/scoped_vector.h" 19 #include "base/memory/scoped_vector.h"
18 #include "base/native_library.h" 20 #include "base/native_library.h"
19 #include "base/pickle.h" 21 #include "base/pickle.h"
22 #include "base/posix/eintr_wrapper.h"
20 #include "base/posix/unix_domain_socket_linux.h" 23 #include "base/posix/unix_domain_socket_linux.h"
21 #include "base/rand_util.h" 24 #include "base/rand_util.h"
22 #include "base/sys_info.h" 25 #include "base/sys_info.h"
23 #include "build/build_config.h" 26 #include "build/build_config.h"
24 #include "content/common/child_process_sandbox_support_impl_linux.h" 27 #include "content/common/child_process_sandbox_support_impl_linux.h"
25 #include "content/common/font_config_ipc_linux.h" 28 #include "content/common/font_config_ipc_linux.h"
26 #include "content/common/pepper_plugin_list.h" 29 #include "content/common/pepper_plugin_list.h"
27 #include "content/common/sandbox_linux/sandbox_linux.h" 30 #include "content/common/sandbox_linux/sandbox_linux.h"
28 #include "content/common/zygote_commands_linux.h" 31 #include "content/common/zygote_commands_linux.h"
29 #include "content/public/common/content_switches.h" 32 #include "content/public/common/content_switches.h"
(...skipping 10 matching lines...) Expand all
40 #include "third_party/skia/include/ports/SkFontConfigInterface.h" 43 #include "third_party/skia/include/ports/SkFontConfigInterface.h"
41 44
42 #if defined(OS_LINUX) 45 #if defined(OS_LINUX)
43 #include <sys/prctl.h> 46 #include <sys/prctl.h>
44 #endif 47 #endif
45 48
46 #if defined(ENABLE_WEBRTC) 49 #if defined(ENABLE_WEBRTC)
47 #include "third_party/libjingle/overrides/init_webrtc.h" 50 #include "third_party/libjingle/overrides/init_webrtc.h"
48 #endif 51 #endif
49 52
53 #if defined(ADDRESS_SANITIZER)
54 #include <sanitizer/asan_interface.h>
55 #endif
56
50 namespace content { 57 namespace content {
51 58
52 // See http://code.google.com/p/chromium/wiki/LinuxZygote 59 // See http://code.google.com/p/chromium/wiki/LinuxZygote
53 60
54 static void ProxyLocaltimeCallToBrowser(time_t input, struct tm* output, 61 static void ProxyLocaltimeCallToBrowser(time_t input, struct tm* output,
55 char* timezone_out, 62 char* timezone_out,
56 size_t timezone_out_len) { 63 size_t timezone_out_len) {
57 Pickle request; 64 Pickle request;
58 request.WriteInt(LinuxSandbox::METHOD_LOCALTIME); 65 request.WriteInt(LinuxSandbox::METHOD_LOCALTIME);
59 request.WriteString( 66 request.WriteString(
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)) { 398 if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)) {
392 LOG(ERROR) << "Failed to set non-dumpable flag"; 399 LOG(ERROR) << "Failed to set non-dumpable flag";
393 return false; 400 return false;
394 } 401 }
395 } 402 }
396 #endif 403 #endif
397 404
398 return true; 405 return true;
399 } 406 }
400 407
408 #if defined(ADDRESS_SANITIZER)
409 const size_t kSanitizerMaxMessageLength = 1 * 1024 * 1024;
410
411 static void SanitizerCoverageHelper(int socket_fd, int file_fd) {
412 scoped_ptr<char[]> buffer(new char[kSanitizerMaxMessageLength]);
413 while (true) {
414 ssize_t received_size = HANDLE_EINTR(
415 recv(socket_fd, buffer.get(), kSanitizerMaxMessageLength, 0));
jln (very slow on Chromium) 2014/05/21 01:07:37 Once the all renderers have exited and the Zygote
416 PCHECK(received_size >= 0);
417 if (received_size > 0) {
418 PCHECK(file_fd >= 0);
419 ssize_t written_size = 0;
420 while (written_size < received_size) {
421 ssize_t write_res =
422 HANDLE_EINTR(write(file_fd, buffer.get() + written_size,
423 received_size - written_size));
424 PCHECK(write_res >= 0);
425 written_size += write_res;
426 }
427 PCHECK(0 == HANDLE_EINTR(fsync(file_fd)));
428 }
429 }
430 }
431
432 // fds[0] is the read end, fds[1] is the write end.
433 static void CreateSanitizerCoverageSocketPair(int fds[2]) {
jln (very slow on Chromium) 2014/05/21 01:07:37 How are you handling this socketpair on the *SAN s
434 PCHECK(0 == socketpair(AF_UNIX, SOCK_SEQPACKET, 0, fds));
435 PCHECK(0 == shutdown(fds[0], SHUT_WR));
436 PCHECK(0 == shutdown(fds[1], SHUT_RD));
437 }
438
439 static void ForkSanitizerCoverageHelper(int child_fd, int parent_fd,
440 base::ScopedFD file_fd) {
441 pid_t pid = fork();
442 PCHECK(pid >= 0);
443 if (pid == 0) {
444 // In the child.
445 PCHECK(0 == IGNORE_EINTR(close(parent_fd)));
446 SanitizerCoverageHelper(child_fd, file_fd.get());
447 _exit(0);
448 } else {
449 // In the parent.
jln (very slow on Chromium) 2014/05/21 01:07:37 Could you add a note along the lines of: - We wil
450 PCHECK(0 == IGNORE_EINTR(close(child_fd)));
451 }
452 }
453 #endif
jln (very slow on Chromium) 2014/05/21 01:07:37 // defined(...)
454
401 // If |is_suid_sandbox_child|, then make sure that the setuid sandbox is 455 // If |is_suid_sandbox_child|, then make sure that the setuid sandbox is
402 // engaged. 456 // engaged.
403 static void EnterLayerOneSandbox(LinuxSandbox* linux_sandbox, 457 static void EnterLayerOneSandbox(LinuxSandbox* linux_sandbox,
404 bool is_suid_sandbox_child) { 458 bool is_suid_sandbox_child) {
405 DCHECK(linux_sandbox); 459 DCHECK(linux_sandbox);
406 460
407 ZygotePreSandboxInit(); 461 ZygotePreSandboxInit();
408 462
409 // Check that the pre-sandbox initialization didn't spawn threads. 463 // Check that the pre-sandbox initialization didn't spawn threads.
410 #if !defined(THREAD_SANITIZER) 464 #if !defined(THREAD_SANITIZER)
411 DCHECK(linux_sandbox->IsSingleThreaded()); 465 DCHECK(linux_sandbox->IsSingleThreaded());
412 #endif 466 #endif
413 467
414 sandbox::SetuidSandboxClient* setuid_sandbox = 468 sandbox::SetuidSandboxClient* setuid_sandbox =
415 linux_sandbox->setuid_sandbox_client(); 469 linux_sandbox->setuid_sandbox_client();
416 470
417 if (is_suid_sandbox_child) { 471 if (is_suid_sandbox_child) {
418 CHECK(EnterSuidSandbox(setuid_sandbox)) << "Failed to enter setuid sandbox"; 472 CHECK(EnterSuidSandbox(setuid_sandbox)) << "Failed to enter setuid sandbox";
419 } 473 }
420 } 474 }
421 475
422 bool ZygoteMain(const MainFunctionParams& params, 476 bool ZygoteMain(const MainFunctionParams& params,
423 ScopedVector<ZygoteForkDelegate> fork_delegates) { 477 ScopedVector<ZygoteForkDelegate> fork_delegates) {
424 g_am_zygote_or_renderer = true; 478 g_am_zygote_or_renderer = true;
425 sandbox::InitLibcUrandomOverrides(); 479 sandbox::InitLibcUrandomOverrides();
426 480
427 LinuxSandbox* linux_sandbox = LinuxSandbox::GetInstance(); 481 LinuxSandbox* linux_sandbox = LinuxSandbox::GetInstance();
482
483 #if defined(ADDRESS_SANITIZER)
484 base::ScopedFD sancov_file_fd(__sanitizer_maybe_open_cov_file("zygote"));
485 int sancov_socket_fds[2] = {-1, -1};
486 CreateSanitizerCoverageSocketPair(sancov_socket_fds);
487 linux_sandbox->sanitizer_args()->coverage_sandboxed = 1;
488 linux_sandbox->sanitizer_args()->coverage_fd = sancov_socket_fds[1];
489 linux_sandbox->sanitizer_args()->coverage_max_block_size =
490 kSanitizerMaxMessageLength;
491 #endif
jln (very slow on Chromium) 2014/05/21 01:07:37 // defined(ADDRESS_SANITIZER)
492
428 // This will pre-initialize the various sandboxes that need it. 493 // This will pre-initialize the various sandboxes that need it.
429 linux_sandbox->PreinitializeSandbox(); 494 linux_sandbox->PreinitializeSandbox();
430 495
431 const bool must_enable_setuid_sandbox = 496 const bool must_enable_setuid_sandbox =
432 linux_sandbox->setuid_sandbox_client()->IsSuidSandboxChild(); 497 linux_sandbox->setuid_sandbox_client()->IsSuidSandboxChild();
433 if (must_enable_setuid_sandbox) { 498 if (must_enable_setuid_sandbox) {
434 linux_sandbox->setuid_sandbox_client()->CloseDummyFile(); 499 linux_sandbox->setuid_sandbox_client()->CloseDummyFile();
435 500
436 // Let the ZygoteHost know we're booting up. 501 // Let the ZygoteHost know we're booting up.
437 CHECK(UnixDomainSocket::SendMsg(kZygoteSocketPairFd, 502 CHECK(UnixDomainSocket::SendMsg(kZygoteSocketPairFd,
438 kZygoteBootMessage, 503 kZygoteBootMessage,
439 sizeof(kZygoteBootMessage), 504 sizeof(kZygoteBootMessage),
440 std::vector<int>())); 505 std::vector<int>()));
441 } 506 }
442 507
443 VLOG(1) << "ZygoteMain: initializing " << fork_delegates.size() 508 VLOG(1) << "ZygoteMain: initializing " << fork_delegates.size()
444 << " fork delegates"; 509 << " fork delegates";
445 for (ScopedVector<ZygoteForkDelegate>::iterator i = fork_delegates.begin(); 510 for (ScopedVector<ZygoteForkDelegate>::iterator i = fork_delegates.begin();
446 i != fork_delegates.end(); 511 i != fork_delegates.end();
447 ++i) { 512 ++i) {
448 (*i)->Init(GetSandboxFD(), must_enable_setuid_sandbox); 513 (*i)->Init(GetSandboxFD(), must_enable_setuid_sandbox);
449 } 514 }
450 515
451 // Turn on the first layer of the sandbox if the configuration warrants it. 516 // Turn on the first layer of the sandbox if the configuration warrants it.
452 EnterLayerOneSandbox(linux_sandbox, must_enable_setuid_sandbox); 517 EnterLayerOneSandbox(linux_sandbox, must_enable_setuid_sandbox);
453 518
519 #if defined(ADDRESS_SANITIZER)
520 ForkSanitizerCoverageHelper(sancov_socket_fds[0], sancov_socket_fds[1],
521 sancov_file_fd.Pass());
522 #endif
523
454 int sandbox_flags = linux_sandbox->GetStatus(); 524 int sandbox_flags = linux_sandbox->GetStatus();
455 bool setuid_sandbox_engaged = sandbox_flags & kSandboxLinuxSUID; 525 bool setuid_sandbox_engaged = sandbox_flags & kSandboxLinuxSUID;
456 CHECK_EQ(must_enable_setuid_sandbox, setuid_sandbox_engaged); 526 CHECK_EQ(must_enable_setuid_sandbox, setuid_sandbox_engaged);
457 527
458 Zygote zygote(sandbox_flags, fork_delegates.Pass()); 528 Zygote zygote(sandbox_flags, fork_delegates.Pass());
459 // This function call can return multiple times, once per fork(). 529 // This function call can return multiple times, once per fork().
460 return zygote.ProcessRequests(); 530 return zygote.ProcessRequests();
461 } 531 }
462 532
463 } // namespace content 533 } // namespace content
OLDNEW
« content/common/sandbox_linux/sandbox_linux.cc ('K') | « content/gpu/gpu_main.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698