Bug 1081242 - Make ASAN's error reporting work while sandboxed on Linux. r=kang
authorJed Davis <jld@mozilla.com>
Tue, 21 Oct 2014 11:18:00 +0200
changeset 212092 c2f036dd38b4adf30e260b2f91fbb6da4b551697
parent 212091 b3f7572fe0a62a2ead54c6b43892774cb4f81c7e
child 212093 b2ba88cd08c09e5f26951acc6e4ab1a9a58818bd
push id27697
push usercbook@mozilla.com
push dateFri, 24 Oct 2014 13:48:53 +0000
treeherdermozilla-central@de805196bbc4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskang
bugs1081242
milestone36.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1081242 - Make ASAN's error reporting work while sandboxed on Linux. r=kang
security/sandbox/linux/Sandbox.cpp
security/sandbox/linux/SandboxFilter.cpp
--- a/security/sandbox/linux/Sandbox.cpp
+++ b/security/sandbox/linux/Sandbox.cpp
@@ -32,16 +32,36 @@
 #endif
 
 #include "linux_seccomp.h"
 #include "SandboxFilter.h"
 
 // See definition of SandboxDie, below.
 #include "sandbox/linux/seccomp-bpf/die.h"
 
+#ifdef MOZ_ASAN
+// Copy libsanitizer declarations to avoid depending on ASAN headers.
+// See also bug 1081242 comment #4.
+extern "C" {
+namespace __sanitizer {
+// Win64 uses long long, but this is Linux.
+typedef signed long sptr;
+} // namespace __sanitizer
+
+typedef struct {
+  int coverage_sandboxed;
+  __sanitizer::sptr coverage_fd;
+  unsigned int coverage_max_block_size;
+} __sanitizer_sandbox_arguments;
+
+MOZ_IMPORT_API void
+__sanitizer_sandbox_on_notify(__sanitizer_sandbox_arguments *args);
+} // extern "C"
+#endif // MOZ_ASAN
+
 namespace mozilla {
 
 SandboxCrashFunc gSandboxCrashFunc;
 
 #ifdef MOZ_GMP_SANDBOX
 // For media plugins, we can start the sandbox before we dlopen the
 // module, so we have to pre-open the file and simulate the sandboxed
 // open().
@@ -410,16 +430,24 @@ static void
 SetCurrentProcessSandbox(SandboxType aType)
 {
   MOZ_ASSERT(gSandboxCrashFunc);
 
   if (InstallSyscallReporter()) {
     SANDBOX_LOG_ERROR("install_syscall_reporter() failed\n");
   }
 
+#ifdef MOZ_ASAN
+  __sanitizer_sandbox_arguments asanArgs;
+  asanArgs.coverage_sandboxed = 1;
+  asanArgs.coverage_fd = -1;
+  asanArgs.coverage_max_block_size = 0;
+  __sanitizer_sandbox_on_notify(&asanArgs);
+#endif
+
   BroadcastSetThreadSandbox(aType);
 }
 
 #ifdef MOZ_CONTENT_SANDBOX
 /**
  * Starts the seccomp sandbox for a content process.  Should be called
  * only once, and before any potentially harmful content is loaded.
  *
--- a/security/sandbox/linux/SandboxFilter.cpp
+++ b/security/sandbox/linux/SandboxFilter.cpp
@@ -391,16 +391,24 @@ void SandboxFilterImplGMP::Build() {
   Deny(EACCES, SYSCALL(setpriority));
 
   // Stack bounds are obtained via pthread_getattr_np, which calls
   // this but doesn't actually need it:
   Deny(ENOSYS, SYSCALL(sched_getaffinity));
 
 #ifdef MOZ_ASAN
   Allow(SYSCALL(sigaltstack));
+  // ASAN's error reporter wants to know if stderr is a tty.
+  Deny(ENOTTY, SYSCALL_WITH_ARG(ioctl, 0, STDERR_FILENO));
+  // ...and before compiler-rt r209773, it will call readlink and use
+  // the cached value only if that fails:
+  Deny(ENOENT, SYSCALL(readlink));
+  // ...and if it found an external symbolizer, it will try to run it:
+  // (See also bug 1081242 comment #7.)
+  Deny(ENOENT, SYSCALL_LARGEFILE(stat, stat64));
 #endif
 
   Allow(SYSCALL(mprotect));
   Allow(SYSCALL_WITH_ARG(madvise, 2, MADV_DONTNEED));
 
 #if SYSCALL_EXISTS(sigreturn)
   Allow(SYSCALL(sigreturn));
 #endif