[PATCH] D58382: [Sanitizer] Add interceptor for pthread_sigmask

Pavel Labath via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 19 06:06:04 PST 2019


labath created this revision.
labath added reviewers: eugenis, vitalybuka.
Herald added subscribers: llvm-commits, jdoerfert, jfb, delcypher, kubamracek.
Herald added projects: LLVM, Sanitizers.

pthread_sigmask is just like sigprocmask, except that its behavior in
multithreaded programs is explicitly specified. Sanitizers were lacking
a common interceptor for pthread_sigmask (although some specific
sanitizers defined custom version), which lead to false positives
(at least in msan) when using this function.

The interceptor implementation, and its test are based on the equivalent
code for sigprocmask.


Repository:
  rCRT Compiler Runtime

https://reviews.llvm.org/D58382

Files:
  lib/esan/esan_interceptors.cpp
  lib/msan/tests/msan_test.cc
  lib/sanitizer_common/sanitizer_common_interceptors.inc
  lib/sanitizer_common/sanitizer_platform_interceptors.h
  lib/tsan/rtl/tsan_interceptors.cc


Index: lib/tsan/rtl/tsan_interceptors.cc
===================================================================
--- lib/tsan/rtl/tsan_interceptors.cc
+++ lib/tsan/rtl/tsan_interceptors.cc
@@ -2221,6 +2221,7 @@
 #define NEED_TLS_GET_ADDR
 #endif
 #undef SANITIZER_INTERCEPT_TLS_GET_ADDR
+#undef SANITIZER_INTERCEPT_PTHREAD_SIGMASK
 
 #define COMMON_INTERCEPT_FUNCTION(name) INTERCEPT_FUNCTION(name)
 #define COMMON_INTERCEPT_FUNCTION_VER(name, ver)                          \
Index: lib/sanitizer_common/sanitizer_platform_interceptors.h
===================================================================
--- lib/sanitizer_common/sanitizer_platform_interceptors.h
+++ lib/sanitizer_common/sanitizer_platform_interceptors.h
@@ -308,6 +308,7 @@
   (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
 #define SANITIZER_INTERCEPT_SIGPENDING SI_POSIX
 #define SANITIZER_INTERCEPT_SIGPROCMASK SI_POSIX
+#define SANITIZER_INTERCEPT_PTHREAD_SIGMASK SI_POSIX
 #define SANITIZER_INTERCEPT_BACKTRACE \
   (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
 #define SANITIZER_INTERCEPT_GETMNTENT SI_LINUX
Index: lib/sanitizer_common/sanitizer_common_interceptors.inc
===================================================================
--- lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -4016,6 +4016,25 @@
 #define INIT_SIGPROCMASK
 #endif
 
+#if SANITIZER_INTERCEPT_PTHREAD_SIGMASK
+INTERCEPTOR(int, pthread_sigmask, int how, __sanitizer_sigset_t *set,
+            __sanitizer_sigset_t *oldset) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, pthread_sigmask, how, set, oldset);
+  if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));
+  // FIXME: under ASan the call below may write to freed memory and corrupt
+  // its metadata. See
+  // https://github.com/google/sanitizers/issues/321.
+  int res = REAL(pthread_sigmask)(how, set, oldset);
+  if (!res && oldset)
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset));
+  return res;
+}
+#define INIT_PTHREAD_SIGMASK COMMON_INTERCEPT_FUNCTION(pthread_sigmask);
+#else
+#define INIT_PTHREAD_SIGMASK
+#endif
+
 #if SANITIZER_INTERCEPT_BACKTRACE
 INTERCEPTOR(int, backtrace, void **buffer, int size) {
   void *ctx;
@@ -9574,6 +9593,7 @@
   INIT_SIGSETOPS;
   INIT_SIGPENDING;
   INIT_SIGPROCMASK;
+  INIT_PTHREAD_SIGMASK;
   INIT_BACKTRACE;
   INIT__EXIT;
   INIT_PTHREAD_MUTEX_LOCK;
Index: lib/msan/tests/msan_test.cc
===================================================================
--- lib/msan/tests/msan_test.cc
+++ lib/msan/tests/msan_test.cc
@@ -2579,6 +2579,14 @@
   EXPECT_NOT_POISONED(s);
 }
 
+TEST(MemorySanitizer, pthread_sigmask) {
+  sigset_t s;
+  EXPECT_POISONED(s);
+  int res = pthread_sigmask(SIG_BLOCK, 0, &s);
+  ASSERT_EQ(0, res);
+  EXPECT_NOT_POISONED(s);
+}
+
 struct StructWithDtor {
   ~StructWithDtor();
 };
Index: lib/esan/esan_interceptors.cpp
===================================================================
--- lib/esan/esan_interceptors.cpp
+++ lib/esan/esan_interceptors.cpp
@@ -45,6 +45,7 @@
 
 // We provide our own version:
 #undef SANITIZER_INTERCEPT_SIGPROCMASK
+#undef SANITIZER_INTERCEPT_PTHREAD_SIGMASK
 
 #define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (!EsanIsInitialized)
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D58382.187355.patch
Type: text/x-patch
Size: 3310 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190219/1e329673/attachment.bin>


More information about the llvm-commits mailing list