[compiler-rt] r179288 - [sanitizer] Syscall hooks.

Evgeniy Stepanov eugeni.stepanov at gmail.com
Thu Apr 11 07:37:05 PDT 2013


Author: eugenis
Date: Thu Apr 11 09:37:04 2013
New Revision: 179288

URL: http://llvm.org/viewvc/llvm-project?rev=179288&view=rev
Log:
[sanitizer] Syscall hooks.

Pre- and post- hooks for linux syscalls. Not wired into anything, but exposed
through public interface.

Added:
    compiler-rt/trunk/include/sanitizer/linux_syscall_hooks.h   (with props)
    compiler-rt/trunk/lib/msan/lit_tests/Linux/syscalls.cc   (with props)
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_syscalls.inc
Modified:
    compiler-rt/trunk/lib/msan/msan_interceptors.cc
    compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt

Added: compiler-rt/trunk/include/sanitizer/linux_syscall_hooks.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/include/sanitizer/linux_syscall_hooks.h?rev=179288&view=auto
==============================================================================
--- compiler-rt/trunk/include/sanitizer/linux_syscall_hooks.h (added)
+++ compiler-rt/trunk/include/sanitizer/linux_syscall_hooks.h Thu Apr 11 09:37:04 2013
@@ -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

Propchange: compiler-rt/trunk/include/sanitizer/linux_syscall_hooks.h
------------------------------------------------------------------------------
    svn:eol-style = LF

Added: compiler-rt/trunk/lib/msan/lit_tests/Linux/syscalls.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/lit_tests/Linux/syscalls.cc?rev=179288&view=auto
==============================================================================
--- compiler-rt/trunk/lib/msan/lit_tests/Linux/syscalls.cc (added)
+++ compiler-rt/trunk/lib/msan/lit_tests/Linux/syscalls.cc Thu Apr 11 09:37:04 2013
@@ -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;
+}

Propchange: compiler-rt/trunk/lib/msan/lit_tests/Linux/syscalls.cc
------------------------------------------------------------------------------
    svn:eol-style = LF

Modified: compiler-rt/trunk/lib/msan/msan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan_interceptors.cc?rev=179288&r1=179287&r2=179288&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/msan/msan_interceptors.cc Thu Apr 11 09:37:04 2013
@@ -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 *t
   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

Modified: compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt?rev=179288&r1=179287&r2=179288&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt (original)
+++ compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt Thu Apr 11 09:37:04 2013
@@ -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

Added: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_syscalls.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_syscalls.inc?rev=179288&view=auto
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_syscalls.inc (added)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_syscalls.inc Thu Apr 11 09:37:04 2013
@@ -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





More information about the llvm-commits mailing list