mirror of
https://github.com/intel/llvm.git
synced 2026-02-05 21:24:55 +08:00
[sanitizer] Add syscall handlers for sigaction and rt_sigaction.
llvm-svn: 273746
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
40
compiler-rt/test/msan/Linux/syscalls_sigaction.cc
Normal file
40
compiler-rt/test/msan/Linux/syscalls_sigaction.cc
Normal file
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user