forked from OSchip/llvm-project
[sanitizer] Syscall hooks.
Pre- and post- hooks for linux syscalls. Not wired into anything, but exposed through public interface. llvm-svn: 179288
This commit is contained in:
parent
6728fc11bc
commit
f5523116e9
|
@ -0,0 +1,275 @@
|
|||
//===-- linux_syscall_hooks.h ---------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file is a part of public sanitizer interface.
|
||||
//
|
||||
// System call handlers.
|
||||
//
|
||||
// Interface methods declared in this header implement pre- and post- syscall
|
||||
// actions for the active sanitizer.
|
||||
// Usage:
|
||||
// __sanitizer_syscall_pre_getfoo(...args...);
|
||||
// int res = syscall(__NR_getfoo, ...args...);
|
||||
// __sanitizer_syscall_post_getfoo(res, ...args...);
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef SANITIZER_LINUX_SYSCALL_HOOKS_H
|
||||
#define SANITIZER_LINUX_SYSCALL_HOOKS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void __sanitizer_syscall_pre_rt_sigpending(void *p, size_t s);
|
||||
void __sanitizer_syscall_pre_getdents(int fd, void *dirp, int count);
|
||||
void __sanitizer_syscall_pre_getdents64(int fd, void *dirp, int count);
|
||||
void __sanitizer_syscall_pre_recvmsg(int sockfd, void *msg, int flags);
|
||||
|
||||
void __sanitizer_syscall_post_rt_sigpending(int res, void *p, size_t s);
|
||||
void __sanitizer_syscall_post_getdents(int res, int fd, void *dirp, int count);
|
||||
void __sanitizer_syscall_post_getdents64(int res, int fd, void *dirp, int count);
|
||||
void __sanitizer_syscall_post_recvmsg(int res, int sockfd, void *msg, int flags);
|
||||
|
||||
// And now a few syscalls we don't handle yet.
|
||||
|
||||
#define __sanitizer_syscall_pre__gettid()
|
||||
#define __sanitizer_syscall_pre_fork()
|
||||
#define __sanitizer_syscall_pre_getegid()
|
||||
#define __sanitizer_syscall_pre_geteuid()
|
||||
#define __sanitizer_syscall_pre_getpgrp()
|
||||
#define __sanitizer_syscall_pre_getpid()
|
||||
#define __sanitizer_syscall_pre_getppid()
|
||||
#define __sanitizer_syscall_pre_sched_yield()
|
||||
#define __sanitizer_syscall_pre_setsid()
|
||||
|
||||
#define __sanitizer_syscall_pre__exit(a)
|
||||
#define __sanitizer_syscall_pre_brk(a)
|
||||
#define __sanitizer_syscall_pre_chdir(a)
|
||||
#define __sanitizer_syscall_pre_chroot(a)
|
||||
#define __sanitizer_syscall_pre_close(a)
|
||||
#define __sanitizer_syscall_pre_dup(a)
|
||||
#define __sanitizer_syscall_pre_exit_group(a)
|
||||
#define __sanitizer_syscall_pre_getsid(a)
|
||||
#define __sanitizer_syscall_pre_io_destroy(a)
|
||||
#define __sanitizer_syscall_pre_pipe(a)
|
||||
#define __sanitizer_syscall_pre_rt_sigreturn(a)
|
||||
#define __sanitizer_syscall_pre_set_tid_address(a)
|
||||
#define __sanitizer_syscall_pre_setfsgid(a)
|
||||
#define __sanitizer_syscall_pre_setfsuid(a)
|
||||
#define __sanitizer_syscall_pre_setgid(a)
|
||||
#define __sanitizer_syscall_pre_setuid(a)
|
||||
#define __sanitizer_syscall_pre_umask(a)
|
||||
#define __sanitizer_syscall_pre_unlink(a)
|
||||
#define __sanitizer_syscall_pre_unshare(a)
|
||||
|
||||
#define __sanitizer_syscall_pre_arch_prctl(a, b)
|
||||
#define __sanitizer_syscall_pre_capset(a, b)
|
||||
#define __sanitizer_syscall_pre_clock_getres(a, b)
|
||||
#define __sanitizer_syscall_pre_clock_gettime(a, b)
|
||||
#define __sanitizer_syscall_pre_dup2(a, b)
|
||||
#define __sanitizer_syscall_pre_fstat(a, b)
|
||||
#define __sanitizer_syscall_pre_fstatfs(a, b)
|
||||
#define __sanitizer_syscall_pre_ftruncate(a, b)
|
||||
#define __sanitizer_syscall_pre_getpriority(a, b)
|
||||
#define __sanitizer_syscall_pre_getrlimit(a, b)
|
||||
#define __sanitizer_syscall_pre_gettimeofday(a, b)
|
||||
#define __sanitizer_syscall_pre_io_setup(a, b)
|
||||
#define __sanitizer_syscall_pre_ioprio_get(a, b)
|
||||
#define __sanitizer_syscall_pre_kill(a, b)
|
||||
#define __sanitizer_syscall_pre_munmap(a, b)
|
||||
#define __sanitizer_syscall_pre_prctl(a, b)
|
||||
#define __sanitizer_syscall_pre_rt_sigsuspend(a, b)
|
||||
#define __sanitizer_syscall_pre_setgroups(a, b)
|
||||
#define __sanitizer_syscall_pre_setns(a, b)
|
||||
#define __sanitizer_syscall_pre_setpgid(a, b)
|
||||
#define __sanitizer_syscall_pre_setrlimit(a, b)
|
||||
#define __sanitizer_syscall_pre_shutdown(a, b)
|
||||
#define __sanitizer_syscall_pre_sigaltstack(a, b)
|
||||
#define __sanitizer_syscall_pre_stat(a, b)
|
||||
#define __sanitizer_syscall_pre_statfs(a, b)
|
||||
#define __sanitizer_syscall_pre_tkill(a, b)
|
||||
|
||||
#define __sanitizer_syscall_pre_execve(a, b, c)
|
||||
#define __sanitizer_syscall_pre_fcntl(a, b, c)
|
||||
#define __sanitizer_syscall_pre_getcpu(a, b, c)
|
||||
#define __sanitizer_syscall_pre_getresgid(a, b, c)
|
||||
#define __sanitizer_syscall_pre_getresuid(a, b, c)
|
||||
#define __sanitizer_syscall_pre_io_cancel(a, b, c)
|
||||
#define __sanitizer_syscall_pre_io_submit(a, b, c)
|
||||
#define __sanitizer_syscall_pre_ioctl(a, b, c)
|
||||
#define __sanitizer_syscall_pre_ioprio_set(a, b, c)
|
||||
#define __sanitizer_syscall_pre_listxattr(a, b, c)
|
||||
#define __sanitizer_syscall_pre_llistxattr(a, b, c)
|
||||
#define __sanitizer_syscall_pre_lseek(a, b, c)
|
||||
#define __sanitizer_syscall_pre_mprotect(a, b, c)
|
||||
#define __sanitizer_syscall_pre_open(a, b, c)
|
||||
#define __sanitizer_syscall_pre_poll(a, b, c)
|
||||
#define __sanitizer_syscall_pre_read(a, b, c)
|
||||
#define __sanitizer_syscall_pre_readahead(a, b, c)
|
||||
#define __sanitizer_syscall_pre_readlink(a, b, c)
|
||||
#define __sanitizer_syscall_pre_sched_getaffinity(a, b, c)
|
||||
#define __sanitizer_syscall_pre_sched_setaffinity(a, b, c)
|
||||
#define __sanitizer_syscall_pre_sendmsg(a, b, c)
|
||||
#define __sanitizer_syscall_pre_setpriority(a, b, c)
|
||||
#define __sanitizer_syscall_pre_setresgid(a, b, c)
|
||||
#define __sanitizer_syscall_pre_setresuid(a, b, c)
|
||||
#define __sanitizer_syscall_pre_socket(a, b, c)
|
||||
#define __sanitizer_syscall_pre_tgkill(a, b, c)
|
||||
#define __sanitizer_syscall_pre_unlinkat(a, b, c)
|
||||
#define __sanitizer_syscall_pre_write(a, b, c)
|
||||
#define __sanitizer_syscall_pre_writev(a, b, c)
|
||||
|
||||
#define __sanitizer_syscall_pre_fadvise64(a, b, c, d)
|
||||
#define __sanitizer_syscall_pre_fallocate(a, b, c, d)
|
||||
#define __sanitizer_syscall_pre_futex(a, b, c, d)
|
||||
#define __sanitizer_syscall_pre_getxattr(a, b, c, d)
|
||||
#define __sanitizer_syscall_pre_lgetxattr(a, b, c, d)
|
||||
#define __sanitizer_syscall_pre_newfstatat(a, b, c, d)
|
||||
#define __sanitizer_syscall_pre_openat(a, b, c, d)
|
||||
#define __sanitizer_syscall_pre_pread64(a, b, c, d)
|
||||
#define __sanitizer_syscall_pre_ptrace(a, b, c, d)
|
||||
#define __sanitizer_syscall_pre_pwrite64(a, b, c, d)
|
||||
#define __sanitizer_syscall_pre_quotactl(a, b, c, d)
|
||||
#define __sanitizer_syscall_pre_rt_sigaction(a, b, c, d)
|
||||
#define __sanitizer_syscall_pre_rt_sigprocmask(a, b, c, d)
|
||||
#define __sanitizer_syscall_pre_socketpair(a, b, c, d)
|
||||
#define __sanitizer_syscall_pre_wait4(a, b, c, d)
|
||||
|
||||
#define __sanitizer_syscall_pre__mremap(a, b, c, d, e)
|
||||
#define __sanitizer_syscall_pre_io_getevents(a, b, c, d, e)
|
||||
#define __sanitizer_syscall_pre_lsetxattr(a, b, c, d, e)
|
||||
#define __sanitizer_syscall_pre_mount(a, b, c, d, e)
|
||||
#define __sanitizer_syscall_pre_preadv(a, b, c, d, e)
|
||||
#define __sanitizer_syscall_pre_pwritev(a, b, c, d, e)
|
||||
#define __sanitizer_syscall_pre_setxattr(a, b, c, d, e)
|
||||
|
||||
#define __sanitizer_syscall_pre_mmap(a, b, c, d, e, f)
|
||||
#define __sanitizer_syscall_pre_move_pages(a, b, c, d, e, f)
|
||||
#define __sanitizer_syscall_pre_sendto(a, b, c, d, e, f)
|
||||
|
||||
|
||||
#define __sanitizer_syscall_post__gettid(res)
|
||||
#define __sanitizer_syscall_post_fork(res)
|
||||
#define __sanitizer_syscall_post_getegid(res)
|
||||
#define __sanitizer_syscall_post_geteuid(res)
|
||||
#define __sanitizer_syscall_post_getpgrp(res)
|
||||
#define __sanitizer_syscall_post_getpid(res)
|
||||
#define __sanitizer_syscall_post_getppid(res)
|
||||
#define __sanitizer_syscall_post_sched_yield(res)
|
||||
#define __sanitizer_syscall_post_setsid(res)
|
||||
|
||||
#define __sanitizer_syscall_post__exit(res, a)
|
||||
#define __sanitizer_syscall_post_brk(res, a)
|
||||
#define __sanitizer_syscall_post_chdir(res, a)
|
||||
#define __sanitizer_syscall_post_chroot(res, a)
|
||||
#define __sanitizer_syscall_post_close(res, a)
|
||||
#define __sanitizer_syscall_post_dup(res, a)
|
||||
#define __sanitizer_syscall_post_exit_group(res, a)
|
||||
#define __sanitizer_syscall_post_getsid(res, a)
|
||||
#define __sanitizer_syscall_post_io_destroy(res, a)
|
||||
#define __sanitizer_syscall_post_pipe(res, a)
|
||||
#define __sanitizer_syscall_post_rt_sigreturn(res, a)
|
||||
#define __sanitizer_syscall_post_set_tid_address(res, a)
|
||||
#define __sanitizer_syscall_post_setfsgid(res, a)
|
||||
#define __sanitizer_syscall_post_setfsuid(res, a)
|
||||
#define __sanitizer_syscall_post_setgid(res, a)
|
||||
#define __sanitizer_syscall_post_setuid(res, a)
|
||||
#define __sanitizer_syscall_post_umask(res, a)
|
||||
#define __sanitizer_syscall_post_unlink(res, a)
|
||||
#define __sanitizer_syscall_post_unshare(res, a)
|
||||
|
||||
#define __sanitizer_syscall_post_arch_prctl(res, a, b)
|
||||
#define __sanitizer_syscall_post_capset(res, a, b)
|
||||
#define __sanitizer_syscall_post_clock_getres(res, a, b)
|
||||
#define __sanitizer_syscall_post_clock_gettime(res, a, b)
|
||||
#define __sanitizer_syscall_post_dup2(res, a, b)
|
||||
#define __sanitizer_syscall_post_fstat(res, a, b)
|
||||
#define __sanitizer_syscall_post_fstatfs(res, a, b)
|
||||
#define __sanitizer_syscall_post_ftruncate(res, a, b)
|
||||
#define __sanitizer_syscall_post_getpriority(res, a, b)
|
||||
#define __sanitizer_syscall_post_getrlimit(res, a, b)
|
||||
#define __sanitizer_syscall_post_gettimeofday(res, a, b)
|
||||
#define __sanitizer_syscall_post_io_setup(res, a, b)
|
||||
#define __sanitizer_syscall_post_ioprio_get(res, a, b)
|
||||
#define __sanitizer_syscall_post_kill(res, a, b)
|
||||
#define __sanitizer_syscall_post_munmap(res, a, b)
|
||||
#define __sanitizer_syscall_post_prctl(res, a, b)
|
||||
#define __sanitizer_syscall_post_rt_sigsuspend(res, a, b)
|
||||
#define __sanitizer_syscall_post_setgroups(res, a, b)
|
||||
#define __sanitizer_syscall_post_setns(res, a, b)
|
||||
#define __sanitizer_syscall_post_setpgid(res, a, b)
|
||||
#define __sanitizer_syscall_post_setrlimit(res, a, b)
|
||||
#define __sanitizer_syscall_post_shutdown(res, a, b)
|
||||
#define __sanitizer_syscall_post_sigaltstack(res, a, b)
|
||||
#define __sanitizer_syscall_post_stat(res, a, b)
|
||||
#define __sanitizer_syscall_post_statfs(res, a, b)
|
||||
#define __sanitizer_syscall_post_tkill(res, a, b)
|
||||
|
||||
#define __sanitizer_syscall_post_execve(res, a, b, c)
|
||||
#define __sanitizer_syscall_post_fcntl(res, a, b, c)
|
||||
#define __sanitizer_syscall_post_getcpu(res, a, b, c)
|
||||
#define __sanitizer_syscall_post_getresgid(res, a, b, c)
|
||||
#define __sanitizer_syscall_post_getresuid(res, a, b, c)
|
||||
#define __sanitizer_syscall_post_io_cancel(res, a, b, c)
|
||||
#define __sanitizer_syscall_post_io_submit(res, a, b, c)
|
||||
#define __sanitizer_syscall_post_ioctl(res, a, b, c)
|
||||
#define __sanitizer_syscall_post_ioprio_set(res, a, b, c)
|
||||
#define __sanitizer_syscall_post_listxattr(res, a, b, c)
|
||||
#define __sanitizer_syscall_post_llistxattr(res, a, b, c)
|
||||
#define __sanitizer_syscall_post_lseek(res, a, b, c)
|
||||
#define __sanitizer_syscall_post_mprotect(res, a, b, c)
|
||||
#define __sanitizer_syscall_post_open(res, a, b, c)
|
||||
#define __sanitizer_syscall_post_poll(res, a, b, c)
|
||||
#define __sanitizer_syscall_post_read(res, a, b, c)
|
||||
#define __sanitizer_syscall_post_readahead(res, a, b, c)
|
||||
#define __sanitizer_syscall_post_readlink(res, a, b, c)
|
||||
#define __sanitizer_syscall_post_sched_getaffinity(res, a, b, c)
|
||||
#define __sanitizer_syscall_post_sched_setaffinity(res, a, b, c)
|
||||
#define __sanitizer_syscall_post_sendmsg(res, a, b, c)
|
||||
#define __sanitizer_syscall_post_setpriority(res, a, b, c)
|
||||
#define __sanitizer_syscall_post_setresgid(res, a, b, c)
|
||||
#define __sanitizer_syscall_post_setresuid(res, a, b, c)
|
||||
#define __sanitizer_syscall_post_socket(res, a, b, c)
|
||||
#define __sanitizer_syscall_post_tgkill(res, a, b, c)
|
||||
#define __sanitizer_syscall_post_unlinkat(res, a, b, c)
|
||||
#define __sanitizer_syscall_post_write(res, a, b, c)
|
||||
#define __sanitizer_syscall_post_writev(res, a, b, c)
|
||||
|
||||
#define __sanitizer_syscall_post_fadvise64(res, a, b, c, d)
|
||||
#define __sanitizer_syscall_post_fallocate(res, a, b, c, d)
|
||||
#define __sanitizer_syscall_post_futex(res, a, b, c, d)
|
||||
#define __sanitizer_syscall_post_getxattr(res, a, b, c, d)
|
||||
#define __sanitizer_syscall_post_lgetxattr(res, a, b, c, d)
|
||||
#define __sanitizer_syscall_post_newfstatat(res, a, b, c, d)
|
||||
#define __sanitizer_syscall_post_openat(res, a, b, c, d)
|
||||
#define __sanitizer_syscall_post_pread64(res, a, b, c, d)
|
||||
#define __sanitizer_syscall_post_ptrace(res, a, b, c, d)
|
||||
#define __sanitizer_syscall_post_pwrite64(res, a, b, c, d)
|
||||
#define __sanitizer_syscall_post_quotactl(res, a, b, c, d)
|
||||
#define __sanitizer_syscall_post_rt_sigaction(res, a, b, c, d)
|
||||
#define __sanitizer_syscall_post_rt_sigprocmask(res, a, b, c, d)
|
||||
#define __sanitizer_syscall_post_socketpair(res, a, b, c, d)
|
||||
#define __sanitizer_syscall_post_wait4(res, a, b, c, d)
|
||||
|
||||
#define __sanitizer_syscall_post__mremap(res, a, b, c, d, e)
|
||||
#define __sanitizer_syscall_post_io_getevents(res, a, b, c, d, e)
|
||||
#define __sanitizer_syscall_post_lsetxattr(res, a, b, c, d, e)
|
||||
#define __sanitizer_syscall_post_mount(res, a, b, c, d, e)
|
||||
#define __sanitizer_syscall_post_preadv(res, a, b, c, d, e)
|
||||
#define __sanitizer_syscall_post_pwritev(res, a, b, c, d, e)
|
||||
#define __sanitizer_syscall_post_setxattr(res, a, b, c, d, e)
|
||||
|
||||
#define __sanitizer_syscall_post_mmap(res, a, b, c, d, e, f)
|
||||
#define __sanitizer_syscall_post_move_pages(res, a, b, c, d, e, f)
|
||||
#define __sanitizer_syscall_post_sendto(res, a, b, c, d, e, f)
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // SANITIZER_LINUX_SYSCALL_HOOKS_H
|
|
@ -0,0 +1,50 @@
|
|||
// RUN: %clangxx_msan -m64 -O0 %s -o %t && %t 2>&1
|
||||
// RUN: %clangxx_msan -m64 -O3 %s -o %t && %t 2>&1
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <glob.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sanitizer/linux_syscall_hooks.h>
|
||||
#include <sanitizer/msan_interface.h>
|
||||
|
||||
/* Test the presence of __sanitizer_syscall_ in the tool runtime, and general
|
||||
sanity of their behaviour. */
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
char buf[1000];
|
||||
const int kTen = 10;
|
||||
memset(buf, 0, sizeof(buf));
|
||||
__msan_unpoison(buf, sizeof(buf));
|
||||
__sanitizer_syscall_pre_recvmsg(0, buf, 0);
|
||||
__sanitizer_syscall_pre_rt_sigpending(buf, kTen);
|
||||
__sanitizer_syscall_pre_getdents(0, buf, kTen);
|
||||
__sanitizer_syscall_pre_getdents64(0, buf, kTen);
|
||||
|
||||
__msan_unpoison(buf, sizeof(buf));
|
||||
__sanitizer_syscall_post_recvmsg(0, 0, buf, 0);
|
||||
__sanitizer_syscall_post_rt_sigpending(-1, buf, kTen);
|
||||
__sanitizer_syscall_post_getdents(0, 0, buf, kTen);
|
||||
__sanitizer_syscall_post_getdents64(0, 0, buf, kTen);
|
||||
assert(__msan_test_shadow(buf, sizeof(buf)) == -1);
|
||||
|
||||
__msan_unpoison(buf, sizeof(buf));
|
||||
__sanitizer_syscall_post_recvmsg(kTen, 0, buf, 0);
|
||||
|
||||
// Tell the kernel that the output struct size is 10 bytes, verify that those
|
||||
// bytes are unpoisoned, and the next byte is not.
|
||||
__msan_poison(buf, kTen + 1);
|
||||
__sanitizer_syscall_post_rt_sigpending(0, buf, kTen);
|
||||
assert(__msan_test_shadow(buf, sizeof(buf)) == kTen);
|
||||
|
||||
__msan_poison(buf, kTen + 1);
|
||||
__sanitizer_syscall_post_getdents(kTen, 0, buf, kTen);
|
||||
assert(__msan_test_shadow(buf, sizeof(buf)) == kTen);
|
||||
|
||||
__msan_poison(buf, kTen + 1);
|
||||
__sanitizer_syscall_post_getdents64(kTen, 0, buf, kTen);
|
||||
assert(__msan_test_shadow(buf, sizeof(buf)) == kTen);
|
||||
return 0;
|
||||
}
|
|
@ -43,7 +43,7 @@ using namespace __msan;
|
|||
do { \
|
||||
sptr offset = __msan_test_shadow(x, n); \
|
||||
if (__msan::IsInSymbolizer()) break; \
|
||||
if (offset >= 0 && flags()->report_umrs) { \
|
||||
if (offset >= 0 && __msan::flags()->report_umrs) { \
|
||||
GET_CALLER_PC_BP_SP; \
|
||||
(void)sp; \
|
||||
Printf("UMR in %s at offset %d inside [%p, +%d) \n", \
|
||||
|
@ -938,6 +938,12 @@ INTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void*),
|
|||
do { } while (false) // FIXME
|
||||
#include "sanitizer_common/sanitizer_common_interceptors.inc"
|
||||
|
||||
#define COMMON_SYSCALL_PRE_READ_RANGE(p, s) CHECK_UNPOISONED(p, s)
|
||||
#define COMMON_SYSCALL_PRE_WRITE_RANGE(p, s)
|
||||
#define COMMON_SYSCALL_POST_READ_RANGE(p, s)
|
||||
#define COMMON_SYSCALL_POST_WRITE_RANGE(p, s) __msan_unpoison(p, s)
|
||||
#include "sanitizer_common/sanitizer_common_syscalls.inc"
|
||||
|
||||
// static
|
||||
void *fast_memset(void *ptr, int c, SIZE_T n) {
|
||||
// hack until we have a really fast internal_memset
|
||||
|
|
|
@ -34,6 +34,7 @@ set(SANITIZER_HEADERS
|
|||
sanitizer_common.h
|
||||
sanitizer_common_interceptors.inc
|
||||
sanitizer_common_interceptors_scanf.inc
|
||||
sanitizer_common_syscalls.inc
|
||||
sanitizer_flags.h
|
||||
sanitizer_internal_defs.h
|
||||
sanitizer_lfstack.h
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
//===-- sanitizer_common_syscalls.inc ---------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Common syscalls handlers for tools like AddressSanitizer,
|
||||
// ThreadSanitizer, MemorySanitizer, etc.
|
||||
//
|
||||
// This file should be included into the tool's interceptor file,
|
||||
// which has to define it's own macros:
|
||||
// COMMON_SYSCALL_PRE_READ_RANGE
|
||||
// Called in prehook for regions that will be read by the kernel and
|
||||
// must be initialized.
|
||||
// COMMON_SYSCALL_PRE_WRITE_RANGE
|
||||
// Called in prehook for regions that will be written to by the kernel
|
||||
// and must be addressable. The actual write range may be smaller than
|
||||
// reported in the prehook. See POST_WRITE_RANGE.
|
||||
// COMMON_SYSCALL_POST_READ_RANGE
|
||||
// Called in posthook for regions that were read by the kernel. Does
|
||||
// not make much sense.
|
||||
// COMMON_SYSCALL_POST_WRITE_RANGE
|
||||
// Called in posthook for regions that were written to by the kernel
|
||||
// and are now initialized.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define PRE_SYSCALL(name) \
|
||||
SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_syscall_pre_##name
|
||||
#define PRE_READ(p, s) COMMON_SYSCALL_PRE_READ_RANGE(p, s)
|
||||
#define PRE_WRITE(p, s) COMMON_SYSCALL_PRE_WRITE_RANGE(p, s)
|
||||
|
||||
#define POST_SYSCALL(name) \
|
||||
SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_syscall_post_##name
|
||||
#define POST_READ(p, s) COMMON_SYSCALL_POST_READ_RANGE(p, s)
|
||||
#define POST_WRITE(p, s) COMMON_SYSCALL_POST_WRITE_RANGE(p, s)
|
||||
|
||||
// FIXME: do some kind of PRE_READ for all syscall arguments (int(s) and such).
|
||||
|
||||
extern "C" {
|
||||
|
||||
struct sanitizer_kernel_iovec {
|
||||
void *iov_base;
|
||||
unsigned long iov_len;
|
||||
};
|
||||
|
||||
struct sanitizer_kernel_msghdr {
|
||||
void *msg_name;
|
||||
int msg_namelen;
|
||||
struct sanitizer_kernel_iovec *msg_iov;
|
||||
unsigned long msg_iovlen;
|
||||
void *msg_control;
|
||||
unsigned long msg_controllen;
|
||||
unsigned msg_flags;
|
||||
};
|
||||
|
||||
PRE_SYSCALL(recvmsg)(int sockfd, struct sanitizer_kernel_msghdr *msg,
|
||||
int flags) {
|
||||
PRE_READ(msg, sizeof(*msg));
|
||||
}
|
||||
|
||||
POST_SYSCALL(recvmsg)(int res, int sockfd, struct sanitizer_kernel_msghdr *msg,
|
||||
int flags) {
|
||||
if (res > 0)
|
||||
for (unsigned long i = 0; i < msg->msg_iovlen; ++i)
|
||||
POST_WRITE(msg->msg_iov[i].iov_base, msg->msg_iov[i].iov_len);
|
||||
POST_WRITE(msg->msg_control, msg->msg_controllen);
|
||||
}
|
||||
|
||||
PRE_SYSCALL(rt_sigpending)(void *p, unsigned long s) { PRE_WRITE(p, s); }
|
||||
|
||||
POST_SYSCALL(rt_sigpending)(int res, void *p, unsigned long s) {
|
||||
if (res == 0)
|
||||
POST_WRITE(p, s);
|
||||
}
|
||||
|
||||
PRE_SYSCALL(getdents)(int fd, void *dirp, int count) { PRE_WRITE(dirp, count); }
|
||||
|
||||
POST_SYSCALL(getdents)(int res, int fd, void *dirp, int count) {
|
||||
if (res > 0)
|
||||
POST_WRITE(dirp, res);
|
||||
}
|
||||
|
||||
PRE_SYSCALL(getdents64)(int fd, void *dirp, int count) {
|
||||
PRE_WRITE(dirp, count);
|
||||
}
|
||||
|
||||
POST_SYSCALL(getdents64)(int res, int fd, void *dirp, int count) {
|
||||
if (res > 0)
|
||||
POST_WRITE(dirp, res);
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
#undef PRE_SYSCALL
|
||||
#undef PRE_READ
|
||||
#undef PRE_WRITE
|
||||
#undef POST_SYSCALL
|
||||
#undef POST_READ
|
||||
#undef POST_WRITE
|
Loading…
Reference in New Issue