summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>2016-06-24 23:09:44 +0000
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>2016-06-24 23:09:44 +0000
commitc8679985edff033bfdd2b9285945d571fa7799c1 (patch)
tree554b93ab8964a25046ef5279d1b9ee271fe86c48
parentc66a06ad0ec57d4981f06e458292d739eed71475 (diff)
downloadbcm5719-llvm-c8679985edff033bfdd2b9285945d571fa7799c1.tar.gz
bcm5719-llvm-c8679985edff033bfdd2b9285945d571fa7799c1.zip
[sanitizer] Add syscall handlers for sigaction and rt_sigaction.
llvm-svn: 273746
-rw-r--r--compiler-rt/include/sanitizer/linux_syscall_hooks.h23
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc34
-rw-r--r--compiler-rt/test/msan/Linux/syscalls_sigaction.cc40
3 files changed, 92 insertions, 5 deletions
diff --git a/compiler-rt/include/sanitizer/linux_syscall_hooks.h b/compiler-rt/include/sanitizer/linux_syscall_hooks.h
index 89867c15190..09f261dd672 100644
--- a/compiler-rt/include/sanitizer/linux_syscall_hooks.h
+++ b/compiler-rt/include/sanitizer/linux_syscall_hooks.h
@@ -1835,6 +1835,17 @@
__sanitizer_syscall_pre_impl_vfork()
#define __sanitizer_syscall_post_vfork(res) \
__sanitizer_syscall_post_impl_vfork(res)
+#define __sanitizer_syscall_pre_sigaction(signum, act, oldact) \
+ __sanitizer_syscall_pre_impl_sigaction((long)signum, (long)act, (long)oldact)
+#define __sanitizer_syscall_post_sigaction(res, signum, act, oldact) \
+ __sanitizer_syscall_post_impl_sigaction(res, (long)signum, (long)act, \
+ (long)oldact)
+#define __sanitizer_syscall_pre_rt_sigaction(signum, act, oldact, sz) \
+ __sanitizer_syscall_pre_impl_rt_sigaction((long)signum, (long)act, \
+ (long)oldact, (long)sz)
+#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)
// And now a few syscalls we don't handle yet.
#define __sanitizer_syscall_pre_afs_syscall(...)
@@ -1889,7 +1900,6 @@
#define __sanitizer_syscall_pre_query_module(...)
#define __sanitizer_syscall_pre_readahead(...)
#define __sanitizer_syscall_pre_readdir(...)
-#define __sanitizer_syscall_pre_rt_sigaction(...)
#define __sanitizer_syscall_pre_rt_sigreturn(...)
#define __sanitizer_syscall_pre_rt_sigsuspend(...)
#define __sanitizer_syscall_pre_security(...)
@@ -1903,7 +1913,6 @@
#define __sanitizer_syscall_pre_setreuid32(...)
#define __sanitizer_syscall_pre_set_thread_area(...)
#define __sanitizer_syscall_pre_setuid32(...)
-#define __sanitizer_syscall_pre_sigaction(...)
#define __sanitizer_syscall_pre_sigaltstack(...)
#define __sanitizer_syscall_pre_sigreturn(...)
#define __sanitizer_syscall_pre_sigsuspend(...)
@@ -1971,7 +1980,6 @@
#define __sanitizer_syscall_post_query_module(res, ...)
#define __sanitizer_syscall_post_readahead(res, ...)
#define __sanitizer_syscall_post_readdir(res, ...)
-#define __sanitizer_syscall_post_rt_sigaction(res, ...)
#define __sanitizer_syscall_post_rt_sigreturn(res, ...)
#define __sanitizer_syscall_post_rt_sigsuspend(res, ...)
#define __sanitizer_syscall_post_security(res, ...)
@@ -1985,7 +1993,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_sigaction(res, ...)
#define __sanitizer_syscall_post_sigaltstack(res, ...)
#define __sanitizer_syscall_post_sigreturn(res, ...)
#define __sanitizer_syscall_post_sigsuspend(res, ...)
@@ -3062,7 +3069,13 @@ void __sanitizer_syscall_pre_impl_fork();
void __sanitizer_syscall_post_impl_fork(long res);
void __sanitizer_syscall_pre_impl_vfork();
void __sanitizer_syscall_post_impl_vfork(long res);
-
+void __sanitizer_syscall_pre_impl_sigaction(long signum, long act, long oldact);
+void __sanitizer_syscall_post_impl_sigaction(long res, long signum, long act,
+ long oldact);
+void __sanitizer_syscall_pre_impl_rt_sigaction(long signum, long act,
+ long oldact, long sz);
+void __sanitizer_syscall_post_impl_rt_sigaction(long res, long signum, long act,
+ long oldact, long sz);
#ifdef __cplusplus
} // extern "C"
#endif
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc
index 48016f218f3..469c8eb7e14 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc
@@ -2840,6 +2840,40 @@ PRE_SYSCALL(vfork)() {
POST_SYSCALL(vfork)(long res) {
COMMON_SYSCALL_POST_FORK(res);
}
+
+PRE_SYSCALL(sigaction)(long signum, const __sanitizer_kernel_sigaction_t *act,
+ __sanitizer_kernel_sigaction_t *oldact) {
+ if (act) {
+ PRE_READ(&act->sigaction, sizeof(act->sigaction));
+ PRE_READ(&act->sa_flags, sizeof(act->sa_flags));
+ PRE_READ(&act->sa_mask, sizeof(act->sa_mask));
+ }
+}
+
+POST_SYSCALL(sigaction)(long res, long signum,
+ const __sanitizer_kernel_sigaction_t *act,
+ __sanitizer_kernel_sigaction_t *oldact) {
+ if (res >= 0 && oldact) POST_WRITE(oldact, sizeof(*oldact));
+}
+
+PRE_SYSCALL(rt_sigaction)(long signum,
+ const __sanitizer_kernel_sigaction_t *act,
+ __sanitizer_kernel_sigaction_t *oldact, SIZE_T sz) {
+ if (act) {
+ PRE_READ(&act->sigaction, sizeof(act->sigaction));
+ PRE_READ(&act->sa_flags, sizeof(act->sa_flags));
+ PRE_READ(&act->sa_mask, sz);
+ }
+}
+
+POST_SYSCALL(rt_sigaction)(long res, long signum,
+ const __sanitizer_kernel_sigaction_t *act,
+ __sanitizer_kernel_sigaction_t *oldact, SIZE_T sz) {
+ if (res >= 0 && oldact) {
+ SIZE_T oldact_sz = ((char *)&oldact->sa_mask) - ((char *)oldact) + sz;
+ POST_WRITE(oldact, oldact_sz);
+ }
+}
} // extern "C"
#undef PRE_SYSCALL
diff --git a/compiler-rt/test/msan/Linux/syscalls_sigaction.cc b/compiler-rt/test/msan/Linux/syscalls_sigaction.cc
new file mode 100644
index 00000000000..1297fae13d1
--- /dev/null
+++ b/compiler-rt/test/msan/Linux/syscalls_sigaction.cc
@@ -0,0 +1,40 @@
+// RUN: %clangxx_msan -DPRE1 -O0 %s -o %t && not %run %t 2>&1
+// RUN: %clangxx_msan -DPRE2 -O0 %s -o %t && not %run %t 2>&1
+// RUN: %clangxx_msan -DPRE3 -O0 %s -o %t && not %run %t 2>&1
+// RUN: %clangxx_msan -O0 %s -o %t && %run %t 2>&1
+
+#include <assert.h>
+#include <signal.h>
+#include <string.h>
+
+#include <sanitizer/linux_syscall_hooks.h>
+#include <sanitizer/msan_interface.h>
+
+struct my_kernel_sigaction {
+ long handler, flags, restorer;
+ uint64_t mask[20]; // larger than any known platform
+};
+
+int main() {
+ my_kernel_sigaction act = {}, oldact = {};
+
+#if defined(PRE1)
+ __msan_poison(&act.handler, sizeof(act.handler));
+ __sanitizer_syscall_pre_rt_sigaction(SIGUSR1, &act, &oldact, 20 * 8);
+#elif defined(PRE2)
+ __msan_poison(&act.flags, sizeof(act.flags));
+ __sanitizer_syscall_pre_rt_sigaction(SIGUSR1, &act, &oldact, 20 * 8);
+#elif defined(PRE3)
+ __msan_poison(&act.mask, 1);
+ __sanitizer_syscall_pre_rt_sigaction(SIGUSR1, &act, &oldact, 20 * 8);
+#else
+ // Uninit past the end of the mask is ignored.
+ __msan_poison(((char *)&act.mask) + 5, 1);
+ __sanitizer_syscall_pre_rt_sigaction(SIGUSR1, &act, &oldact, 5);
+
+ memset(&act, 0, sizeof(act));
+ __msan_poison(&oldact, sizeof(oldact));
+ __sanitizer_syscall_post_rt_sigaction(0, SIGUSR1, &act, &oldact, 5);
+ assert(__msan_test_shadow(&oldact, sizeof(oldact)) == sizeof(long)*3 + 5);
+#endif
+}
OpenPOWER on IntegriCloud