[compiler-rt] r191374 - [sanitizer] A bunch of libc interceptors.

Evgeniy Stepanov eugeni.stepanov at gmail.com
Wed Sep 25 07:47:43 PDT 2013


Author: eugenis
Date: Wed Sep 25 09:47:43 2013
New Revision: 191374

URL: http://llvm.org/viewvc/llvm-project?rev=191374&view=rev
Log:
[sanitizer] A bunch of libc interceptors.

sigwait
sigwaitinfo
sigtimedwait
sigemptyset
sigfillset
sigpending
sigprocmask

Added:
    compiler-rt/trunk/lib/msan/lit_tests/sigwait.cc   (with props)
    compiler-rt/trunk/lib/msan/lit_tests/sigwaitinfo.cc   (with props)
Modified:
    compiler-rt/trunk/lib/msan/tests/msan_test.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h
    compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_stat.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h

Added: compiler-rt/trunk/lib/msan/lit_tests/sigwait.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/lit_tests/sigwait.cc?rev=191374&view=auto
==============================================================================
--- compiler-rt/trunk/lib/msan/lit_tests/sigwait.cc (added)
+++ compiler-rt/trunk/lib/msan/lit_tests/sigwait.cc Wed Sep 25 09:47:43 2013
@@ -0,0 +1,30 @@
+// RUN: %clangxx_msan -std=c++11 -O0 -g %s -o %t && %t
+
+#include <assert.h>
+#include <sanitizer/msan_interface.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+void test_sigwait() {
+  sigset_t s;
+  sigemptyset(&s);
+  sigaddset(&s, SIGUSR1);
+  sigprocmask(SIG_BLOCK, &s, 0);
+
+  if (pid_t pid = fork()) {
+    kill(pid, SIGUSR1);
+    _exit(0);
+  } else {
+    int sig;
+    int res = sigwait(&s, &sig);
+    assert(!res);
+    // The following checks that sig is initialized.
+    assert(sig == SIGUSR1);
+  }
+}
+
+int main(void) {
+  test_sigwait();
+  return 0;
+}

Propchange: compiler-rt/trunk/lib/msan/lit_tests/sigwait.cc
------------------------------------------------------------------------------
    svn:eol-style = LF

Added: compiler-rt/trunk/lib/msan/lit_tests/sigwaitinfo.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/lit_tests/sigwaitinfo.cc?rev=191374&view=auto
==============================================================================
--- compiler-rt/trunk/lib/msan/lit_tests/sigwaitinfo.cc (added)
+++ compiler-rt/trunk/lib/msan/lit_tests/sigwaitinfo.cc Wed Sep 25 09:47:43 2013
@@ -0,0 +1,31 @@
+// RUN: %clangxx_msan -std=c++11 -O0 -g %s -o %t && %t
+
+#include <assert.h>
+#include <sanitizer/msan_interface.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+void test_sigwaitinfo() {
+  sigset_t s;
+  sigemptyset(&s);
+  sigaddset(&s, SIGUSR1);
+  sigprocmask(SIG_BLOCK, &s, 0);
+
+  if (pid_t pid = fork()) {
+    kill(pid, SIGUSR1);
+    _exit(0);
+  } else {
+    siginfo_t info;
+    int res = sigwaitinfo(&s, &info);
+    assert(!res);
+    // The following checks that sig is initialized.
+    assert(info.si_signo == SIGUSR1);
+    assert(-1 == __msan_test_shadow(&info, sizeof(info)));
+  }
+}
+
+int main(void) {
+  test_sigwaitinfo();
+  return 0;
+}

Propchange: compiler-rt/trunk/lib/msan/lit_tests/sigwaitinfo.cc
------------------------------------------------------------------------------
    svn:eol-style = LF

Modified: compiler-rt/trunk/lib/msan/tests/msan_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/tests/msan_test.cc?rev=191374&r1=191373&r2=191374&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/tests/msan_test.cc (original)
+++ compiler-rt/trunk/lib/msan/tests/msan_test.cc Wed Sep 25 09:47:43 2013
@@ -1642,6 +1642,39 @@ TEST(MemorySanitizer, sigaction) {
 
 } // namespace
 
+
+TEST(MemorySanitizer, sigemptyset) {
+  sigset_t s;
+  EXPECT_POISONED(s);
+  int res = sigemptyset(&s);
+  ASSERT_EQ(0, res);
+  EXPECT_NOT_POISONED(s);
+}
+
+TEST(MemorySanitizer, sigfillset) {
+  sigset_t s;
+  EXPECT_POISONED(s);
+  int res = sigfillset(&s);
+  ASSERT_EQ(0, res);
+  EXPECT_NOT_POISONED(s);
+}
+
+TEST(MemorySanitizer, sigpending) {
+  sigset_t s;
+  EXPECT_POISONED(s);
+  int res = sigpending(&s);
+  ASSERT_EQ(0, res);
+  EXPECT_NOT_POISONED(s);
+}
+
+TEST(MemorySanitizer, sigprocmask) {
+  sigset_t s;
+  EXPECT_POISONED(s);
+  int res = sigprocmask(SIG_BLOCK, 0, &s);
+  ASSERT_EQ(0, res);
+  EXPECT_NOT_POISONED(s);
+}
+
 struct StructWithDtor {
   ~StructWithDtor();
 };

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc?rev=191374&r1=191373&r2=191374&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc Wed Sep 25 09:47:43 2013
@@ -2018,6 +2018,102 @@ INTERCEPTOR(int, wordexp, char *s, __san
 #define INIT_WORDEXP
 #endif
 
+#if SANITIZER_INTERCEPT_SIGWAIT
+INTERCEPTOR(int, sigwait, __sanitizer_sigset_t *set, int *sig) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, sigwait, set, sig);
+  // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
+  int res = REAL(sigwait)(set, sig);
+  if (!res && sig) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sig, sizeof(*sig));
+  return res;
+}
+#define INIT_SIGWAIT INTERCEPT_FUNCTION(sigwait);
+#else
+#define INIT_SIGWAIT
+#endif
+
+#if SANITIZER_INTERCEPT_SIGWAITINFO
+INTERCEPTOR(int, sigwaitinfo, __sanitizer_sigset_t *set, void *info) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, sigwaitinfo, set, info);
+  // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
+  int res = REAL(sigwaitinfo)(set, info);
+  if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz);
+  return res;
+}
+#define INIT_SIGWAITINFO INTERCEPT_FUNCTION(sigwaitinfo);
+#else
+#define INIT_SIGWAITINFO
+#endif
+
+#if SANITIZER_INTERCEPT_SIGTIMEDWAIT
+INTERCEPTOR(int, sigtimedwait, __sanitizer_sigset_t *set, void *info,
+            void *timeout) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, sigtimedwait, set, info, timeout);
+  if (timeout) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout, struct_timespec_sz);
+  // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
+  int res = REAL(sigtimedwait)(set, info, timeout);
+  if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz);
+  return res;
+}
+#define INIT_SIGTIMEDWAIT INTERCEPT_FUNCTION(sigtimedwait);
+#else
+#define INIT_SIGTIMEDWAIT
+#endif
+
+#if SANITIZER_INTERCEPT_SIGSETOPS
+INTERCEPTOR(int, sigemptyset, __sanitizer_sigset_t *set) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, sigemptyset, set);
+  int res = REAL(sigemptyset)(set);
+  if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
+  return res;
+}
+
+INTERCEPTOR(int, sigfillset, __sanitizer_sigset_t *set) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, sigfillset, set);
+  int res = REAL(sigfillset)(set);
+  if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
+  return res;
+}
+#define INIT_SIGSETOPS             \
+  INTERCEPT_FUNCTION(sigemptyset); \
+  INTERCEPT_FUNCTION(sigfillset);
+#else
+#define INIT_SIGSETOPS
+#endif
+
+#if SANITIZER_INTERCEPT_SIGPENDING
+INTERCEPTOR(int, sigpending, __sanitizer_sigset_t *set) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, sigpending, set);
+  int res = REAL(sigpending)(set);
+  if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
+  return res;
+}
+#define INIT_SIGPENDING INTERCEPT_FUNCTION(sigpending);
+#else
+#define INIT_SIGPENDING
+#endif
+
+#if SANITIZER_INTERCEPT_SIGPROCMASK
+INTERCEPTOR(int, sigprocmask, int how, __sanitizer_sigset_t *set,
+            __sanitizer_sigset_t *oldset) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, sigprocmask, how, set, oldset);
+  // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
+  int res = REAL(sigprocmask)(how, set, oldset);
+  if (!res && oldset)
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset));
+  return res;
+}
+#define INIT_SIGPROCMASK INTERCEPT_FUNCTION(sigprocmask);
+#else
+#define INIT_SIGPROCMASK
+#endif
+
 #define SANITIZER_COMMON_INTERCEPTORS_INIT \
   INIT_STRCMP;                             \
   INIT_STRNCMP;                            \
@@ -2087,4 +2183,10 @@ INTERCEPTOR(int, wordexp, char *s, __san
   INIT_GETGROUPS;                          \
   INIT_POLL;                               \
   INIT_PPOLL;                              \
-  INIT_WORDEXP;
+  INIT_WORDEXP;                            \
+  INIT_SIGWAIT;                            \
+  INIT_SIGWAITINFO;                        \
+  INIT_SIGTIMEDWAIT;                       \
+  INIT_SIGSETOPS;                          \
+  INIT_SIGPENDING;                         \
+  INIT_SIGPROCMASK;

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h?rev=191374&r1=191373&r2=191374&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h Wed Sep 25 09:47:43 2013
@@ -119,5 +119,11 @@
 # define SANITIZER_INTERCEPT_POLL SI_NOT_WINDOWS
 # define SANITIZER_INTERCEPT_PPOLL SI_LINUX_NOT_ANDROID
 # define SANITIZER_INTERCEPT_WORDEXP SI_MAC || SI_LINUX_NOT_ANDROID
+# define SANITIZER_INTERCEPT_SIGWAIT SI_NOT_WINDOWS
+# define SANITIZER_INTERCEPT_SIGWAITINFO SI_LINUX_NOT_ANDROID
+# define SANITIZER_INTERCEPT_SIGTIMEDWAIT SI_LINUX_NOT_ANDROID
+# define SANITIZER_INTERCEPT_SIGSETOPS SI_NOT_WINDOWS
+# define SANITIZER_INTERCEPT_SIGPENDING SI_NOT_WINDOWS
+# define SANITIZER_INTERCEPT_SIGPROCMASK SI_NOT_WINDOWS
 
 #endif  // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc?rev=191374&r1=191373&r2=191374&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc Wed Sep 25 09:47:43 2013
@@ -35,11 +35,6 @@ struct my_siginfo_t {
   u64 opaque[128 / sizeof(u64)];
 };
 
-struct sigset_t {
-  // The size is determined by looking at sizeof of real sigset_t on linux.
-  u64 val[128 / sizeof(u64)];
-};
-
 struct ucontext_t {
   // The size is determined by looking at sizeof of real ucontext_t on linux.
   u64 opaque[936 / sizeof(u64) + 1];
@@ -54,8 +49,10 @@ extern "C" int pthread_key_create(unsign
 extern "C" int pthread_setspecific(unsigned key, const void *v);
 extern "C" int pthread_mutexattr_gettype(void *a, int *type);
 extern "C" int pthread_yield();
-extern "C" int pthread_sigmask(int how, const sigset_t *set, sigset_t *oldset);
-extern "C" int sigfillset(sigset_t *set);
+extern "C" int pthread_sigmask(int how, const __sanitizer_sigset_t *set,
+                               __sanitizer_sigset_t *oldset);
+// REAL(sigfillset) defined in common interceptors.
+DECLARE_REAL(int, sigfillset, __sanitizer_sigset_t *set)
 extern "C" void *pthread_self();
 extern "C" void _exit(int status);
 extern "C" int *__errno_location();
@@ -97,7 +94,7 @@ struct sigaction_t {
     sighandler_t sa_handler;
     void (*sa_sigaction)(int sig, my_siginfo_t *siginfo, void *uctx);
   };
-  sigset_t sa_mask;
+  __sanitizer_sigset_t sa_mask;
   int sa_flags;
   void (*sa_restorer)();
 };
@@ -1698,7 +1695,7 @@ TSAN_INTERCEPTOR(int, sigaction, int sig
   internal_memcpy(&sigactions[sig], act, sizeof(*act));
   sigaction_t newact;
   internal_memcpy(&newact, act, sizeof(newact));
-  sigfillset(&newact.sa_mask);
+  REAL(sigfillset)(&newact.sa_mask);
   if (act->sa_handler != SIG_IGN && act->sa_handler != SIG_DFL) {
     if (newact.sa_flags & SA_SIGINFO)
       newact.sa_sigaction = rtl_sigaction;
@@ -1721,7 +1718,7 @@ TSAN_INTERCEPTOR(sighandler_t, signal, i
   return old.sa_handler;
 }
 
-TSAN_INTERCEPTOR(int, sigsuspend, const sigset_t *mask) {
+TSAN_INTERCEPTOR(int, sigsuspend, const __sanitizer_sigset_t *mask) {
   SCOPED_TSAN_INTERCEPTOR(sigsuspend, mask);
   return REAL(sigsuspend)(mask);
 }
@@ -1951,8 +1948,8 @@ void ProcessPendingSignals(ThreadState *
   thr->in_signal_handler = true;
   sctx->pending_signal_count = 0;
   // These are too big for stack.
-  static THREADLOCAL sigset_t emptyset, oldset;
-  sigfillset(&emptyset);
+  static THREADLOCAL __sanitizer_sigset_t emptyset, oldset;
+  REAL(sigfillset)(&emptyset);
   pthread_sigmask(SIG_SETMASK, &emptyset, &oldset);
   for (int sig = 0; sig < kSigCount; sig++) {
     SignalDesc *signal = &sctx->pending_signals[sig];

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_stat.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_stat.cc?rev=191374&r1=191373&r2=191374&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_stat.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_stat.cc Wed Sep 25 09:47:43 2013
@@ -362,6 +362,13 @@ void StatOutput(u64 *stat) {
   name[StatInt_scandir64]                = "  scandir64                       ";
   name[StatInt_getgroups]                = "  getgroups                       ";
   name[StatInt_wordexp]                  = "  wordexp                         ";
+  name[StatInt_sigwait]                  = "  sigwait                         ";
+  name[StatInt_sigwaitinfo]              = "  sigwaitinfo                     ";
+  name[StatInt_sigtimedwait]             = "  sigtimedwait                    ";
+  name[StatInt_sigemptyset]              = "  sigemptyset                     ";
+  name[StatInt_sigfillset]               = "  sigfillset                      ";
+  name[StatInt_sigpending]               = "  sigpending                      ";
+  name[StatInt_sigprocmask]              = "  sigprocmask                     ";
 
   name[StatAnnotation]                   = "Dynamic annotations               ";
   name[StatAnnotateHappensBefore]        = "  HappensBefore                   ";

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h?rev=191374&r1=191373&r2=191374&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h Wed Sep 25 09:47:43 2013
@@ -357,6 +357,13 @@ enum StatType {
   StatInt_scandir64,
   StatInt_getgroups,
   StatInt_wordexp,
+  StatInt_sigwait,
+  StatInt_sigwaitinfo,
+  StatInt_sigtimedwait,
+  StatInt_sigemptyset,
+  StatInt_sigfillset,
+  StatInt_sigpending,
+  StatInt_sigprocmask,
 
   // Dynamic annotations.
   StatAnnotation,





More information about the llvm-commits mailing list