[compiler-rt] 780528d - sanitizers: Implement sig{and, or}set interceptors

Gui Andrade via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 17 20:12:46 PDT 2020


Author: Gui Andrade
Date: 2020-07-18T03:09:39Z
New Revision: 780528d9da707b15849d6c9711cc3ab19f6c7f00

URL: https://github.com/llvm/llvm-project/commit/780528d9da707b15849d6c9711cc3ab19f6c7f00
DIFF: https://github.com/llvm/llvm-project/commit/780528d9da707b15849d6c9711cc3ab19f6c7f00.diff

LOG: sanitizers: Implement sig{and,or}set interceptors

Also adds a sanitizers-wide test, and a msan test, for these functions.

Added: 
    compiler-rt/test/msan/Linux/sigandorset.cpp
    compiler-rt/test/sanitizer_common/TestCases/Linux/signal_send.cpp

Modified: 
    compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
    compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
index d7e0bba76294..0fdaf00e67c1 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -4085,6 +4085,33 @@ INTERCEPTOR(int, sigfillset, __sanitizer_sigset_t *set) {
 #define INIT_SIGSETOPS
 #endif
 
+#if SANITIZER_INTERCEPT_SIGSET_LOGICOPS
+INTERCEPTOR(int, sigandset, __sanitizer_sigset_t *dst, __sanitizer_sigset_t *src1, __sanitizer_sigset_t *src2) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, sigandset, dst, src1, src2);
+  if (src1) COMMON_INTERCEPTOR_READ_RANGE(ctx, src1, sizeof(*src1));
+  if (src2) COMMON_INTERCEPTOR_READ_RANGE(ctx, src2, sizeof(*src2));
+  int res = REAL(sigandset)(dst, src1, src2);
+  if (!res && dst) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(*dst));
+  return res;
+}
+
+INTERCEPTOR(int, sigorset, __sanitizer_sigset_t *dst, __sanitizer_sigset_t *src1, __sanitizer_sigset_t *src2) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, sigorset, dst, src1, src2);
+  if (src1) COMMON_INTERCEPTOR_READ_RANGE(ctx, src1, sizeof(*src1));
+  if (src2) COMMON_INTERCEPTOR_READ_RANGE(ctx, src2, sizeof(*src2));
+  int res = REAL(sigorset)(dst, src1, src2);
+  if (!res && dst) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(*dst));
+  return res;
+}
+#define INIT_SIGSET_LOGICOPS                    \
+  COMMON_INTERCEPT_FUNCTION(sigandset);   \
+  COMMON_INTERCEPT_FUNCTION(sigorset);
+#else
+#define INIT_SIGSET_LOGICOPS
+#endif
+
 #if SANITIZER_INTERCEPT_SIGPENDING
 INTERCEPTOR(int, sigpending, __sanitizer_sigset_t *set) {
   void *ctx;
@@ -9996,6 +10023,7 @@ static void InitializeCommonInterceptors() {
   INIT_SIGWAITINFO;
   INIT_SIGTIMEDWAIT;
   INIT_SIGSETOPS;
+  INIT_SIGSET_LOGICOPS;
   INIT_SIGPENDING;
   INIT_SIGPROCMASK;
   INIT_PTHREAD_SIGMASK;

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
index e28bb937ae83..04b61d6daae7 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
@@ -333,6 +333,7 @@
 #define SANITIZER_INTERCEPT_SIGTIMEDWAIT SI_LINUX_NOT_ANDROID || SI_SOLARIS
 #define SANITIZER_INTERCEPT_SIGSETOPS \
   (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
+#define SANITIZER_INTERCEPT_SIGSET_LOGICOPS SI_LINUX_NOT_ANDROID
 #define SANITIZER_INTERCEPT_SIGPENDING SI_POSIX
 #define SANITIZER_INTERCEPT_SIGPROCMASK SI_POSIX
 #define SANITIZER_INTERCEPT_PTHREAD_SIGMASK SI_POSIX

diff  --git a/compiler-rt/test/msan/Linux/sigandorset.cpp b/compiler-rt/test/msan/Linux/sigandorset.cpp
new file mode 100644
index 000000000000..d0e552fcfa01
--- /dev/null
+++ b/compiler-rt/test/msan/Linux/sigandorset.cpp
@@ -0,0 +1,27 @@
+// RUN: %clangxx_msan -std=c++11 -O0 -g %s -o %t && not %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_msan -DLEFT_OK -std=c++11 -O0 -g %s -o %t && not %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_msan -DRIGHT_OK -std=c++11 -O0 -g %s -o %t && not %run %t 2<&1 | FileCheck %s
+// RUN: %clangxx_msan -DLEFT_OK -DRIGHT_OK -std=c++11 -O0 -g %s -o %t && %run %t
+
+#include <assert.h>
+#include <sanitizer/msan_interface.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+int main(void) {
+  sigset_t s, t, u;
+#ifdef LEFT_OK
+  sigemptyset(&t);
+#endif
+#ifdef RIGHT_OK
+  sigemptyset(&u);
+#endif
+
+  // CHECK:  MemorySanitizer: use-of-uninitialized-value
+  // CHECK-NEXT: in main {{.*}}sigandorset.cpp:[[@LINE+1]]
+  sigandset(&s, &t, &u);
+  sigorset(&s, &t, &u);
+  __msan_check_mem_is_initialized(&s, sizeof s);
+  return 0;
+}

diff  --git a/compiler-rt/test/sanitizer_common/TestCases/Linux/signal_send.cpp b/compiler-rt/test/sanitizer_common/TestCases/Linux/signal_send.cpp
new file mode 100644
index 000000000000..54014da8b532
--- /dev/null
+++ b/compiler-rt/test/sanitizer_common/TestCases/Linux/signal_send.cpp
@@ -0,0 +1,75 @@
+// RUN: %clangxx -std=c++11 -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s
+
+#include <assert.h>
+#include <signal.h>
+#include <stdio.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+sigset_t mkset(int n, ...) {
+  sigset_t s;
+  int res = 0;
+  res |= sigemptyset(&s);
+  va_list va;
+  va_start(va, n);
+  while (n--) {
+    res |= sigaddset(&s, va_arg(va, int));
+  }
+  va_end(va);
+  assert(!res);
+  return s;
+}
+
+sigset_t sigset_or(sigset_t first, sigset_t second) {
+  sigset_t out;
+  int res = sigorset(&out, &first, &second);
+  assert(!res);
+  return out;
+}
+
+sigset_t sigset_and(sigset_t first, sigset_t second) {
+  sigset_t out;
+  int res = sigandset(&out, &first, &second);
+  assert(!res);
+  return out;
+}
+
+int fork_and_signal(sigset_t s) {
+  if (pid_t pid = fork()) {
+    kill(pid, SIGUSR1);
+    kill(pid, SIGUSR2);
+    int child_stat;
+    wait(&child_stat);
+    return !WIFEXITED(child_stat);
+  } else {
+    int sig;
+    int res = sigwait(&s, &sig);
+    assert(!res);
+    fprintf(stderr, "died with sig %d\n", sig);
+    _exit(0);
+  }
+}
+
+void test_sigwait() {
+  // test sigorset... s should now contain SIGUSR1 | SIGUSR2
+  sigset_t s = sigset_or(mkset(1, SIGUSR1), mkset(1, SIGUSR2));
+  sigprocmask(SIG_BLOCK, &s, 0);
+  int res;
+  res = fork_and_signal(s);
+  fprintf(stderr, "fork_and_signal with SIGUSR1,2: %d\n", res);
+  // CHECK: died with sig 10
+  // CHECK: fork_and_signal with SIGUSR1,2: 0
+
+  // test sigandset... s should only have SIGUSR2 now
+  s = sigset_and(s, mkset(1, SIGUSR2));
+  res = fork_and_signal(s);
+  fprintf(stderr, "fork_and_signal with SIGUSR2: %d\n", res);
+  // CHECK: died with sig 12
+  // CHECK: fork_and_signal with SIGUSR2: 0
+}
+
+int main(void) {
+  test_sigwait();
+  return 0;
+}


        


More information about the llvm-commits mailing list