sanitizer_common_syscalls.inc revision 8b40073a28ed435862e250ae01b8ff85d6a2063f
12887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov//===-- sanitizer_common_syscalls.inc ---------------------------*- C++ -*-===//
22887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov//
32887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov//                     The LLVM Compiler Infrastructure
42887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov//
52887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov// This file is distributed under the University of Illinois Open Source
62887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov// License. See LICENSE.TXT for details.
72887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov//
82887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov//===----------------------------------------------------------------------===//
92887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov//
102887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov// Common syscalls handlers for tools like AddressSanitizer,
112887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov// ThreadSanitizer, MemorySanitizer, etc.
122887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov//
132887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov// This file should be included into the tool's interceptor file,
142887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov// which has to define it's own macros:
152887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov//   COMMON_SYSCALL_PRE_READ_RANGE
162887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov//          Called in prehook for regions that will be read by the kernel and
172887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov//          must be initialized.
182887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov//   COMMON_SYSCALL_PRE_WRITE_RANGE
192887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov//          Called in prehook for regions that will be written to by the kernel
202887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov//          and must be addressable. The actual write range may be smaller than
212887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov//          reported in the prehook. See POST_WRITE_RANGE.
222887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov//   COMMON_SYSCALL_POST_READ_RANGE
232887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov//          Called in posthook for regions that were read by the kernel. Does
242887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov//          not make much sense.
252887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov//   COMMON_SYSCALL_POST_WRITE_RANGE
262887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov//          Called in posthook for regions that were written to by the kernel
272887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov//          and are now initialized.
282887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov//===----------------------------------------------------------------------===//
292887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov
302887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov#define PRE_SYSCALL(name)                                                      \
312887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov  SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_syscall_pre_##name
322887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov#define PRE_READ(p, s) COMMON_SYSCALL_PRE_READ_RANGE(p, s)
332887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov#define PRE_WRITE(p, s) COMMON_SYSCALL_PRE_WRITE_RANGE(p, s)
342887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov
352887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov#define POST_SYSCALL(name)                                                     \
362887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov  SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_syscall_post_##name
372887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov#define POST_READ(p, s) COMMON_SYSCALL_POST_READ_RANGE(p, s)
382887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov#define POST_WRITE(p, s) COMMON_SYSCALL_POST_WRITE_RANGE(p, s)
392887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov
402887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov// FIXME: do some kind of PRE_READ for all syscall arguments (int(s) and such).
412887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov
422887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanovextern "C" {
432887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanovstruct sanitizer_kernel_iovec {
442887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov  void *iov_base;
452887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov  unsigned long iov_len;
462887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov};
472887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov
482887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanovstruct sanitizer_kernel_msghdr {
492887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov  void *msg_name;
502887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov  int msg_namelen;
512887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov  struct sanitizer_kernel_iovec *msg_iov;
522887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov  unsigned long msg_iovlen;
532887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov  void *msg_control;
542887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov  unsigned long msg_controllen;
552887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov  unsigned msg_flags;
562887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov};
572887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov
588b40073a28ed435862e250ae01b8ff85d6a2063fEvgeniy Stepanovstruct sanitizer_kernel_timespec {
598b40073a28ed435862e250ae01b8ff85d6a2063fEvgeniy Stepanov  long tv_sec;
608b40073a28ed435862e250ae01b8ff85d6a2063fEvgeniy Stepanov  long tv_nsec;
618b40073a28ed435862e250ae01b8ff85d6a2063fEvgeniy Stepanov};
628b40073a28ed435862e250ae01b8ff85d6a2063fEvgeniy Stepanov
63fa568969fea365a04591d029974b5c93e2cc9867Evgeniy Stepanovstruct sanitizer_kernel_timeval {
64fa568969fea365a04591d029974b5c93e2cc9867Evgeniy Stepanov  long tv_sec;
65fa568969fea365a04591d029974b5c93e2cc9867Evgeniy Stepanov  long tv_usec;
66fa568969fea365a04591d029974b5c93e2cc9867Evgeniy Stepanov};
67fa568969fea365a04591d029974b5c93e2cc9867Evgeniy Stepanov
68fa568969fea365a04591d029974b5c93e2cc9867Evgeniy Stepanovstruct sanitizer_kernel_rusage {
69fa568969fea365a04591d029974b5c93e2cc9867Evgeniy Stepanov  struct sanitizer_kernel_timeval ru_timeval[2];
70fa568969fea365a04591d029974b5c93e2cc9867Evgeniy Stepanov  long ru_long[14];
71fa568969fea365a04591d029974b5c93e2cc9867Evgeniy Stepanov};
72fa568969fea365a04591d029974b5c93e2cc9867Evgeniy Stepanov
732887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy StepanovPRE_SYSCALL(recvmsg)(int sockfd, struct sanitizer_kernel_msghdr *msg,
742887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov                     int flags) {
752887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov  PRE_READ(msg, sizeof(*msg));
762887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov}
772887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov
783ba4b90e89366e537b875cf9f54f370e0ece7007Evgeniy StepanovPOST_SYSCALL(recvmsg)(long res, int sockfd, struct sanitizer_kernel_msghdr *msg,
792887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov                      int flags) {
802887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov  if (res > 0)
81102c04325b454957c322f61c5a8033b720bc9238Andy Gibbs    for (unsigned long i = 0; i < msg->msg_iovlen; ++i) {
822887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov      POST_WRITE(msg->msg_iov[i].iov_base, msg->msg_iov[i].iov_len);
83102c04325b454957c322f61c5a8033b720bc9238Andy Gibbs    }
842887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov  POST_WRITE(msg->msg_control, msg->msg_controllen);
852887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov}
862887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov
872887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy StepanovPRE_SYSCALL(rt_sigpending)(void *p, unsigned long s) { PRE_WRITE(p, s); }
882887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov
893ba4b90e89366e537b875cf9f54f370e0ece7007Evgeniy StepanovPOST_SYSCALL(rt_sigpending)(long res, void *p, unsigned long s) {
90102c04325b454957c322f61c5a8033b720bc9238Andy Gibbs  if (res == 0) {
912887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov    POST_WRITE(p, s);
92102c04325b454957c322f61c5a8033b720bc9238Andy Gibbs  }
932887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov}
942887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov
952887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy StepanovPRE_SYSCALL(getdents)(int fd, void *dirp, int count) { PRE_WRITE(dirp, count); }
962887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov
973ba4b90e89366e537b875cf9f54f370e0ece7007Evgeniy StepanovPOST_SYSCALL(getdents)(long res, int fd, void *dirp, int count) {
98102c04325b454957c322f61c5a8033b720bc9238Andy Gibbs  if (res > 0) {
992887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov    POST_WRITE(dirp, res);
100102c04325b454957c322f61c5a8033b720bc9238Andy Gibbs  }
1012887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov}
1022887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov
1032887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy StepanovPRE_SYSCALL(getdents64)(int fd, void *dirp, int count) {
1042887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov  PRE_WRITE(dirp, count);
1052887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov}
1062887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov
1073ba4b90e89366e537b875cf9f54f370e0ece7007Evgeniy StepanovPOST_SYSCALL(getdents64)(long res, int fd, void *dirp, int count) {
108102c04325b454957c322f61c5a8033b720bc9238Andy Gibbs  if (res > 0) {
1092887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov    POST_WRITE(dirp, res);
110102c04325b454957c322f61c5a8033b720bc9238Andy Gibbs  }
1112887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov}
1122887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov
113fa568969fea365a04591d029974b5c93e2cc9867Evgeniy StepanovPRE_SYSCALL(wait4)(int pid, int *status, int options,
114fa568969fea365a04591d029974b5c93e2cc9867Evgeniy Stepanov                   struct sanitizer_kernel_rusage *r) {
115102c04325b454957c322f61c5a8033b720bc9238Andy Gibbs  if (status) {
116fa568969fea365a04591d029974b5c93e2cc9867Evgeniy Stepanov    PRE_WRITE(status, sizeof(*status));
117102c04325b454957c322f61c5a8033b720bc9238Andy Gibbs  }
118102c04325b454957c322f61c5a8033b720bc9238Andy Gibbs  if (r) {
119fa568969fea365a04591d029974b5c93e2cc9867Evgeniy Stepanov    PRE_WRITE(r, sizeof(*r));
120102c04325b454957c322f61c5a8033b720bc9238Andy Gibbs  }
121fa568969fea365a04591d029974b5c93e2cc9867Evgeniy Stepanov}
122fa568969fea365a04591d029974b5c93e2cc9867Evgeniy Stepanov
123fa568969fea365a04591d029974b5c93e2cc9867Evgeniy StepanovPOST_SYSCALL(wait4)(long res, int pid, int *status, int options,
124fa568969fea365a04591d029974b5c93e2cc9867Evgeniy Stepanov                    struct sanitizer_kernel_rusage *r) {
125fa568969fea365a04591d029974b5c93e2cc9867Evgeniy Stepanov  if (res > 0) {
126102c04325b454957c322f61c5a8033b720bc9238Andy Gibbs    if (status) {
127fa568969fea365a04591d029974b5c93e2cc9867Evgeniy Stepanov      POST_WRITE(status, sizeof(*status));
128102c04325b454957c322f61c5a8033b720bc9238Andy Gibbs    }
129102c04325b454957c322f61c5a8033b720bc9238Andy Gibbs    if (r) {
130fa568969fea365a04591d029974b5c93e2cc9867Evgeniy Stepanov      POST_WRITE(r, sizeof(*r));
131102c04325b454957c322f61c5a8033b720bc9238Andy Gibbs    }
132fa568969fea365a04591d029974b5c93e2cc9867Evgeniy Stepanov  }
133fa568969fea365a04591d029974b5c93e2cc9867Evgeniy Stepanov}
134fa568969fea365a04591d029974b5c93e2cc9867Evgeniy Stepanov
135fa568969fea365a04591d029974b5c93e2cc9867Evgeniy StepanovPRE_SYSCALL(waitpid)(int pid, int *status, int options) {
136102c04325b454957c322f61c5a8033b720bc9238Andy Gibbs  if (status) {
137fa568969fea365a04591d029974b5c93e2cc9867Evgeniy Stepanov    PRE_WRITE(status, sizeof(*status));
138102c04325b454957c322f61c5a8033b720bc9238Andy Gibbs  }
139fa568969fea365a04591d029974b5c93e2cc9867Evgeniy Stepanov}
140fa568969fea365a04591d029974b5c93e2cc9867Evgeniy Stepanov
141fa568969fea365a04591d029974b5c93e2cc9867Evgeniy StepanovPOST_SYSCALL(waitpid)(long res, int pid, int *status, int options) {
142102c04325b454957c322f61c5a8033b720bc9238Andy Gibbs  if (res > 0 && status) {
143fa568969fea365a04591d029974b5c93e2cc9867Evgeniy Stepanov    POST_WRITE(status, sizeof(*status));
144102c04325b454957c322f61c5a8033b720bc9238Andy Gibbs  }
145fa568969fea365a04591d029974b5c93e2cc9867Evgeniy Stepanov}
1468b40073a28ed435862e250ae01b8ff85d6a2063fEvgeniy Stepanov
1478b40073a28ed435862e250ae01b8ff85d6a2063fEvgeniy StepanovPRE_SYSCALL(clock_gettime)(int clk_id, struct sanitizer_kernel_timespec *tp) {
1488b40073a28ed435862e250ae01b8ff85d6a2063fEvgeniy Stepanov  if (tp) PRE_WRITE(tp, sizeof(*tp));
1498b40073a28ed435862e250ae01b8ff85d6a2063fEvgeniy Stepanov}
1508b40073a28ed435862e250ae01b8ff85d6a2063fEvgeniy Stepanov
1518b40073a28ed435862e250ae01b8ff85d6a2063fEvgeniy StepanovPOST_SYSCALL(clock_gettime)(long res, int clk_id, struct sanitizer_kernel_timespec *tp) {
1528b40073a28ed435862e250ae01b8ff85d6a2063fEvgeniy Stepanov  if (res == 0 && tp) POST_WRITE(tp, sizeof(*tp));
1538b40073a28ed435862e250ae01b8ff85d6a2063fEvgeniy Stepanov}
1548b40073a28ed435862e250ae01b8ff85d6a2063fEvgeniy Stepanov
1558b40073a28ed435862e250ae01b8ff85d6a2063fEvgeniy StepanovPRE_SYSCALL(clock_getres)(int clk_id, struct sanitizer_kernel_timespec *tp) {
1568b40073a28ed435862e250ae01b8ff85d6a2063fEvgeniy Stepanov  if (tp) PRE_WRITE(tp, sizeof(*tp));
1578b40073a28ed435862e250ae01b8ff85d6a2063fEvgeniy Stepanov}
1588b40073a28ed435862e250ae01b8ff85d6a2063fEvgeniy Stepanov
1598b40073a28ed435862e250ae01b8ff85d6a2063fEvgeniy StepanovPOST_SYSCALL(clock_getres)(long res, int clk_id, struct sanitizer_kernel_timespec *tp) {
1608b40073a28ed435862e250ae01b8ff85d6a2063fEvgeniy Stepanov  if (res == 0 && tp) POST_WRITE(tp, sizeof(*tp));
1618b40073a28ed435862e250ae01b8ff85d6a2063fEvgeniy Stepanov}
1628b40073a28ed435862e250ae01b8ff85d6a2063fEvgeniy Stepanov
1632887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov}  // extern "C"
1642887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov
1652887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov#undef PRE_SYSCALL
1662887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov#undef PRE_READ
1672887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov#undef PRE_WRITE
1682887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov#undef POST_SYSCALL
1692887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov#undef POST_READ
1702887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov#undef POST_WRITE
171