Introduce CheckASLR() in sanitizers
authorKamil Rytarowski <n54@gmx.com>
Tue, 5 Jun 2018 07:29:23 +0000 (07:29 +0000)
committerKamil Rytarowski <n54@gmx.com>
Tue, 5 Jun 2018 07:29:23 +0000 (07:29 +0000)
Summary:
At least the ASan, MSan, TSan sanitizers require disabled ASLR on a NetBSD.

Introduce a generic CheckASLR() routine, that implements a check for the
current process. This flag depends on the global or per-process settings.

There is no simple way to disable ASLR in the build process from the
level of a sanitizer or during the runtime execution.

With ASLR enabled sanitizers that operate over the process virtual address
space can misbehave usually breaking with cryptic messages.

This check is dummy for !NetBSD.

Sponsored by <The NetBSD Foundation>

Reviewers: vitalybuka, joerg

Reviewed By: vitalybuka

Subscribers: cryptoad, kubamracek, llvm-commits, #sanitizers

Tags: #sanitizers

Differential Revision: https://reviews.llvm.org/D47442

llvm-svn: 333985

compiler-rt/lib/asan/asan_rtl.cc
compiler-rt/lib/msan/msan.cc
compiler-rt/lib/sanitizer_common/sanitizer_common.h
compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cc
compiler-rt/lib/sanitizer_common/sanitizer_linux.cc
compiler-rt/lib/sanitizer_common/sanitizer_mac.cc
compiler-rt/lib/sanitizer_common/sanitizer_win.cc
compiler-rt/lib/tsan/rtl/tsan_rtl.cc

index 5a28e77..15b5035 100644 (file)
@@ -384,6 +384,7 @@ static void AsanInitInternal() {
   asan_init_is_running = true;
 
   CacheBinaryName();
+  CheckASLR();
 
   // Initialize flags. This must be done early, because most of the
   // initialization steps look at flags().
index 227f35a..c4e6a67 100644 (file)
@@ -397,6 +397,7 @@ void __msan_init() {
   InitTlsSize();
 
   CacheBinaryName();
+  CheckASLR();
   InitializeFlags();
 
   // Install tool-specific callbacks in sanitizer_common.
index 150c97e..4246d2e 100644 (file)
@@ -221,6 +221,7 @@ bool SetEnv(const char *name, const char *value);
 
 u32 GetUid();
 void ReExec();
+void CheckASLR();
 char **GetArgv();
 void PrintCmdline();
 bool StackSizeIsUnlimited();
index 85191d9..fa5c82a 100644 (file)
@@ -87,6 +87,7 @@ void GetThreadStackTopAndBottom(bool, uptr *stack_top, uptr *stack_bottom) {
 }
 
 void MaybeReexec() {}
+void CheckASLR() {}
 void PlatformPrepareForSandboxing(__sanitizer_sandbox_arguments *args) {}
 void DisableCoreDumperIfNecessary() {}
 void InstallDeadlySignalHandlers(SignalHandlerType handler) {}
index 5adacc5..a5b9dd0 100644 (file)
@@ -1954,6 +1954,30 @@ void MaybeReexec() {
   // No need to re-exec on Linux.
 }
 
+void CheckASLR() {
+#if SANITIZER_NETBSD
+  int mib[3];
+  int paxflags;
+  size_t len = sizeof(paxflags);
+
+  mib[0] = CTL_PROC;
+  mib[1] = internal_getpid();
+  mib[2] = PROC_PID_PAXFLAGS;
+
+  if (UNLIKELY(sysctl(mib, 3, &paxflags, &len, NULL, 0) == -1)) {
+    Printf("sysctl failed\n");
+    Die();
+  }
+
+  if (UNLIKELY(paxflags & CTL_PROC_PAXFLAGS_ASLR)) {
+    Printf("This sanitizer is not compatible with enabled ASLR\n");
+    Die();
+  }
+#else
+  // Do nothing
+#endif
+}
+
 void PrintModuleMap() { }
 
 void CheckNoDeepBind(const char *filename, int flag) {
index b0376a4..c613a6a 100644 (file)
@@ -340,6 +340,10 @@ void ReExec() {
   UNIMPLEMENTED();
 }
 
+void CheckASLR() {
+  // Do nothing
+}
+
 uptr GetPageSize() {
   return sysconf(_SC_PAGESIZE);
 }
index f59420c..47fad3f 100644 (file)
@@ -1025,6 +1025,10 @@ void MaybeReexec() {
   // No need to re-exec on Windows.
 }
 
+void CheckASLR() {
+  // Do nothing
+}
+
 char **GetArgv() {
   // FIXME: Actually implement this function.
   return 0;
index ee8433a..14a3e3c 100644 (file)
@@ -354,6 +354,7 @@ void Initialize(ThreadState *thr) {
   ctx = new(ctx_placeholder) Context;
   const char *options = GetEnv(SANITIZER_GO ? "GORACE" : "TSAN_OPTIONS");
   CacheBinaryName();
+  CheckASLR();
   InitializeFlags(&ctx->flags, options);
   AvoidCVE_2016_2143();
   InitializePlatformEarly();