[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