[compiler-rt] 28c9121 - [compiler-rt] implement sigaltstack interception

Evgenii Stepanov via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 3 16:29:35 PST 2020


Author: Evgenii Stepanov
Date: 2020-02-03T16:28:47-08:00
New Revision: 28c91219c7e2180c3605ce403c05c4eccac6f615

URL: https://github.com/llvm/llvm-project/commit/28c91219c7e2180c3605ce403c05c4eccac6f615
DIFF: https://github.com/llvm/llvm-project/commit/28c91219c7e2180c3605ce403c05c4eccac6f615.diff

LOG: [compiler-rt] implement sigaltstack interception

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.

Added: 
    compiler-rt/test/msan/sigaltstack.cpp

Modified: 
    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

Removed: 
    


################################################################################
diff  --git a/compiler-rt/include/sanitizer/linux_syscall_hooks.h b/compiler-rt/include/sanitizer/linux_syscall_hooks.h
index a1794b71af50..2733da82b5f8 100644
--- a/compiler-rt/include/sanitizer/linux_syscall_hooks.h
+++ b/compiler-rt/include/sanitizer/linux_syscall_hooks.h
@@ -1845,6 +1845,10 @@
 #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(...)
@@ -1912,7 +1916,6 @@
 #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(...)
@@ -1992,7 +1995,6 @@
 #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, ...)

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
index 2a4ab7e67a5c..76962510e604 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -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;
 }

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc
index 31ff48cfd2cf..532ac9ead349 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc
@@ -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

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
index 4cc69af1241d..1bc128fb05f0 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
@@ -596,5 +596,6 @@
 #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

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp
index aa845df4dde4..e71515f12e94 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp
@@ -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);

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h
index 5337b26b29b8..f6c8a1450a93 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h
@@ -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
index 000000000000..4b97bb461d47
--- /dev/null
+++ b/compiler-rt/test/msan/sigaltstack.cpp
@@ -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;
+}


        


More information about the llvm-commits mailing list