[compiler-rt] implement sigaltstack interception
authorEvgenii Stepanov <eugenis@google.com>
Tue, 4 Feb 2020 00:20:07 +0000 (16:20 -0800)
committerEvgenii Stepanov <eugenis@google.com>
Tue, 4 Feb 2020 00:28:47 +0000 (16:28 -0800)
Summary:
An implementation for `sigaltstack` to make its side effect be visible to MSAN.

```
ninja check-msan
```

Reviewers: vitalybuka, eugenis

Reviewed By: eugenis

Subscribers: dberris, #sanitizers, llvm-commits

Tags: #sanitizers, #llvm

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

Patch by Igor Sugak.

compiler-rt/include/sanitizer/linux_syscall_hooks.h
compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc
compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp
compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h
compiler-rt/test/msan/sigaltstack.cpp [new file with mode: 0644]

index a1794b7..2733da8 100644 (file)
 #define __sanitizer_syscall_post_rt_sigaction(res, signum, act, oldact, sz)    \
   __sanitizer_syscall_post_impl_rt_sigaction(res, (long)signum, (long)act,     \
                                              (long)oldact, (long)sz)
+#define __sanitizer_syscall_pre_sigaltstack(ss, oss)                           \
+  __sanitizer_syscall_pre_impl_sigaltstack((long)ss, (long)oss)
+#define __sanitizer_syscall_post_sigaltstack(res, ss, oss)                     \
+  __sanitizer_syscall_post_impl_sigaltstack(res, (long)ss, (long)oss)
 
 // And now a few syscalls we don't handle yet.
 #define __sanitizer_syscall_pre_afs_syscall(...)
 #define __sanitizer_syscall_pre_setreuid32(...)
 #define __sanitizer_syscall_pre_set_thread_area(...)
 #define __sanitizer_syscall_pre_setuid32(...)
-#define __sanitizer_syscall_pre_sigaltstack(...)
 #define __sanitizer_syscall_pre_sigreturn(...)
 #define __sanitizer_syscall_pre_sigsuspend(...)
 #define __sanitizer_syscall_pre_stty(...)
 #define __sanitizer_syscall_post_setreuid32(res, ...)
 #define __sanitizer_syscall_post_set_thread_area(res, ...)
 #define __sanitizer_syscall_post_setuid32(res, ...)
-#define __sanitizer_syscall_post_sigaltstack(res, ...)
 #define __sanitizer_syscall_post_sigreturn(res, ...)
 #define __sanitizer_syscall_post_sigsuspend(res, ...)
 #define __sanitizer_syscall_post_stty(res, ...)
index 2a4ab7e..7696251 100644 (file)
@@ -9731,6 +9731,24 @@ INTERCEPTOR(void, qsort_r, void *base, SIZE_T nmemb, SIZE_T size,
 #define INIT_QSORT_R
 #endif
 
+#if SANITIZER_INTERCEPT_SIGALTSTACK
+INTERCEPTOR(int, sigaltstack, void *ss, void *oss) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, sigaltstack, ss, oss);
+  if (ss != nullptr) {
+    COMMON_INTERCEPTOR_READ_RANGE(ctx, ss, struct_stack_t_sz);
+  }
+  int r = REAL(sigaltstack)(ss, oss);
+  if (r == 0 && oss != nullptr) {
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oss, struct_stack_t_sz);
+  }
+  return r;
+}
+#define INIT_SIGALTSTACK COMMON_INTERCEPT_FUNCTION(sigaltstack)
+#else
+#define INIT_SIGALTSTACK
+#endif
+
 #include "sanitizer_common_interceptors_netbsd_compat.inc"
 
 static void InitializeCommonInterceptors() {
@@ -10036,6 +10054,7 @@ static void InitializeCommonInterceptors() {
   INIT_GETENTROPY;
   INIT_QSORT;
   INIT_QSORT_R;
+  INIT_SIGALTSTACK;
 
   INIT___PRINTF_CHK;
 }
index 31ff48c..532ac9e 100644 (file)
@@ -2885,6 +2885,23 @@ POST_SYSCALL(getrandom)(long res, void *buf, uptr count, long flags) {
     POST_WRITE(buf, res);
   }
 }
+
+PRE_SYSCALL(sigaltstack)(const void *ss, void *oss) {
+  if (ss != nullptr) {
+    PRE_READ(ss, struct_stack_t_sz);
+  }
+  if (oss != nullptr) {
+    PRE_WRITE(oss, struct_stack_t_sz);
+  }
+}
+
+POST_SYSCALL(sigaltstack)(long res, void *ss, void *oss) {
+  if (res == 0) {
+    if (oss != nullptr) {
+      POST_WRITE(oss, struct_stack_t_sz);
+    }
+  }
+}
 }  // extern "C"
 
 #undef PRE_SYSCALL
index 4cc69af..1bc128f 100644 (file)
 #define SANITIZER_INTERCEPT_QSORT \
   (SI_POSIX && !SI_IOSSIM && !SI_WATCHOS && !SI_TVOS)
 #define SANITIZER_INTERCEPT_QSORT_R (SI_LINUX && !SI_ANDROID)
+#define SANITIZER_INTERCEPT_SIGALTSTACK SI_POSIX
 
 #endif  // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H
index aa845df..e71515f 100644 (file)
@@ -179,6 +179,7 @@ namespace __sanitizer {
   unsigned struct_group_sz = sizeof(struct group);
   unsigned siginfo_t_sz = sizeof(siginfo_t);
   unsigned struct_sigaction_sz = sizeof(struct sigaction);
+  unsigned struct_stack_t_sz = sizeof(stack_t);
   unsigned struct_itimerval_sz = sizeof(struct itimerval);
   unsigned pthread_t_sz = sizeof(pthread_t);
   unsigned pthread_mutex_t_sz = sizeof(pthread_mutex_t);
index 5337b26..f6c8a14 100644 (file)
@@ -47,6 +47,7 @@ extern unsigned struct_timezone_sz;
 extern unsigned struct_tms_sz;
 extern unsigned struct_itimerspec_sz;
 extern unsigned struct_sigevent_sz;
+extern unsigned struct_stack_t_sz;
 extern unsigned struct_sched_param_sz;
 extern unsigned struct_statfs64_sz;
 extern unsigned struct_regex_sz;
diff --git a/compiler-rt/test/msan/sigaltstack.cpp b/compiler-rt/test/msan/sigaltstack.cpp
new file mode 100644 (file)
index 0000000..4b97bb4
--- /dev/null
@@ -0,0 +1,20 @@
+// RUN: %clangxx_msan -O0 -g %s -o %t && not %run %t
+//
+#include <signal.h>
+#include <assert.h>
+
+#include <sanitizer/msan_interface.h>
+
+int main(void) {
+  stack_t old_ss;
+
+  assert(sigaltstack(nullptr, &old_ss) == 0);
+  __msan_check_mem_is_initialized(&old_ss, sizeof(stack_t));
+
+  stack_t ss;
+  sigaltstack(&ss, nullptr);
+// CHECK: WARNING: MemorySanitizer: use-of-uninitialized-value
+// CHECK:    in main {{.*}}sigaltstack.cpp:15
+
+  return 0;
+}