Chromium Code Reviews| Index: content/zygote/zygote_main_linux.cc |
| diff --git a/content/zygote/zygote_main_linux.cc b/content/zygote/zygote_main_linux.cc |
| index 123296907cef7d634ac3ca6f253323b0f01ef270..2a7a8d7ecf09698f05eb523bba1150edf29fcd28 100644 |
| --- a/content/zygote/zygote_main_linux.cc |
| +++ b/content/zygote/zygote_main_linux.cc |
| @@ -59,6 +59,10 @@ |
| #include "third_party/libjingle/overrides/init_webrtc.h" |
| #endif |
| +#if defined(ADDRESS_SANITIZER) |
| +#include <sanitizer/asan_interface.h> |
| +#endif |
| + |
| namespace content { |
| // See http://code.google.com/p/chromium/wiki/LinuxZygote |
| @@ -421,6 +425,59 @@ static bool EnterSuidSandbox(sandbox::SetuidSandboxClient* setuid_sandbox) { |
| return true; |
| } |
| +#if defined(ADDRESS_SANITIZER) |
| +const size_t kSanitizerMaxMessageLength = 1 * 1024 * 1024; |
| + |
| +static void SanitizerCoverageHelper(int socket_fd) { |
| + int file_fd = -1; |
| + char buffer[kSanitizerMaxMessageLength]; |
|
jln (very slow on Chromium)
2014/05/14 23:42:24
This is very large, let's get it off the stack.
earthdok
2014/05/20 16:53:57
Done.
|
| + while (true) { |
| + ssize_t received_size = |
| + HANDLE_EINTR(recv(socket_fd, buffer, kSanitizerMaxMessageLength, 0)); |
| + PCHECK(received_size >= 0) |
| + << "Sanitizer coverage helper: failed to read from socket"; |
| + if (received_size > 0) { |
| + if (file_fd < 0) { |
| + const char kZygoteSanCovFileName[] = "zygote.sancov.packed"; |
| + file_fd = |
| + HANDLE_EINTR(open(kZygoteSanCovFileName, O_WRONLY | O_CREAT, 0660)); |
| + PCHECK(file_fd >= 0) |
| + << "Sanitizer coverage helper: failed to open file"; |
| + } |
| + ssize_t written_size = |
| + HANDLE_EINTR(write(file_fd, buffer, received_size)); |
| + PCHECK(written_size == received_size) |
|
jln (very slow on Chromium)
2014/05/14 21:21:04
You may want to loop here. It can definitely happe
earthdok
2014/05/20 16:53:57
Done.
|
| + << "Sanitizer coverage helper: error writing to file"; |
| + PCHECK(0 == HANDLE_EINTR(fsync(file_fd))) |
|
jln (very slow on Chromium)
2014/05/14 17:49:41
I don't think fsync can EINTR.
earthdok
2014/05/14 19:21:47
The POSIX standard does mention it:
http://pubs.op
|
| + << "Sanitizer coverage helper: error syncing file"; |
| + } |
| + } |
| +} |
| + |
| +static int ForkSanitizerCoverageHelper() { |
| + int fds[2]; |
| + PCHECK(0 == socketpair(AF_UNIX, SOCK_SEQPACKET, 0, fds)) |
| + << "Sanitizer coverage helper: failed to create a socket pair"; |
| + // fds[0] is the read end, fds[1] is the write end. |
| + PCHECK((0 == shutdown(fds[0], SHUT_WR)) && (0 == shutdown(fds[1], SHUT_RD))) |
| + << "Sanitizer coverage helper: shutdown() failed"; |
| + pid_t pid = fork(); |
| + PCHECK(pid >= 0) << "Sanitizer coverage helper: failed to fork"; |
| + if (pid == 0) { |
| + // In the child. |
| + PCHECK(0 == IGNORE_EINTR(close(fds[1]))) |
| + << "Sanitizer coverage helper: child failed to close socket";; |
|
jln (very slow on Chromium)
2014/05/14 17:49:41
General remark for all the PCHECKs. Feel free to n
earthdok
2014/05/20 16:53:57
Done.
|
| + SanitizerCoverageHelper(fds[0]); |
| + _exit(0); |
| + } else { |
| + // In the parent. |
| + PCHECK(0 == IGNORE_EINTR(close(fds[0]))) |
| + << "Sanitizer coverage helper: parent failed to close socket";; |
| + return fds[1]; |
| + } |
| +} |
| +#endif |
| + |
| // If |is_suid_sandbox_child|, then make sure that the setuid sandbox is |
| // engaged. |
| static void EnterLayerOneSandbox(LinuxSandbox* linux_sandbox, |
| @@ -448,6 +505,15 @@ bool ZygoteMain(const MainFunctionParams& params, |
| sandbox::InitLibcUrandomOverrides(); |
| LinuxSandbox* linux_sandbox = LinuxSandbox::GetInstance(); |
| + |
| +#if defined(ADDRESS_SANITIZER) |
| + int sancov_helper_fd = ForkSanitizerCoverageHelper(); |
| + linux_sandbox->sanitizer_args()->coverage_sandboxed = 1; |
| + linux_sandbox->sanitizer_args()->coverage_fd = sancov_helper_fd; |
| + linux_sandbox->sanitizer_args()->coverage_max_block_size = |
| + kSanitizerMaxMessageLength; |
| +#endif |
| + |
| // This will pre-initialize the various sandboxes that need it. |
| linux_sandbox->PreinitializeSandbox(); |