blob: da25e6b6ad2c8660ba90d02ec104742c44c2bba8 [file] [log] [blame]
Evgeniy Stepanov2887a642013-04-11 14:37:04 +00001//===-- sanitizer_common_syscalls.inc ---------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// Common syscalls handlers for tools like AddressSanitizer,
11// ThreadSanitizer, MemorySanitizer, etc.
12//
13// This file should be included into the tool's interceptor file,
14// which has to define it's own macros:
15// COMMON_SYSCALL_PRE_READ_RANGE
16// Called in prehook for regions that will be read by the kernel and
17// must be initialized.
18// COMMON_SYSCALL_PRE_WRITE_RANGE
19// Called in prehook for regions that will be written to by the kernel
20// and must be addressable. The actual write range may be smaller than
21// reported in the prehook. See POST_WRITE_RANGE.
22// COMMON_SYSCALL_POST_READ_RANGE
23// Called in posthook for regions that were read by the kernel. Does
24// not make much sense.
25// COMMON_SYSCALL_POST_WRITE_RANGE
26// Called in posthook for regions that were written to by the kernel
27// and are now initialized.
28//===----------------------------------------------------------------------===//
29
30#define PRE_SYSCALL(name) \
31 SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_syscall_pre_##name
32#define PRE_READ(p, s) COMMON_SYSCALL_PRE_READ_RANGE(p, s)
33#define PRE_WRITE(p, s) COMMON_SYSCALL_PRE_WRITE_RANGE(p, s)
34
35#define POST_SYSCALL(name) \
36 SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_syscall_post_##name
37#define POST_READ(p, s) COMMON_SYSCALL_POST_READ_RANGE(p, s)
38#define POST_WRITE(p, s) COMMON_SYSCALL_POST_WRITE_RANGE(p, s)
39
40// FIXME: do some kind of PRE_READ for all syscall arguments (int(s) and such).
41
42extern "C" {
Evgeniy Stepanov2887a642013-04-11 14:37:04 +000043struct sanitizer_kernel_iovec {
44 void *iov_base;
45 unsigned long iov_len;
46};
47
48struct sanitizer_kernel_msghdr {
49 void *msg_name;
50 int msg_namelen;
51 struct sanitizer_kernel_iovec *msg_iov;
52 unsigned long msg_iovlen;
53 void *msg_control;
54 unsigned long msg_controllen;
55 unsigned msg_flags;
56};
57
Evgeniy Stepanovfa568962013-04-16 13:06:20 +000058struct sanitizer_kernel_timeval {
59 long tv_sec;
60 long tv_usec;
61};
62
63struct sanitizer_kernel_rusage {
64 struct sanitizer_kernel_timeval ru_timeval[2];
65 long ru_long[14];
66};
67
Evgeniy Stepanov2887a642013-04-11 14:37:04 +000068PRE_SYSCALL(recvmsg)(int sockfd, struct sanitizer_kernel_msghdr *msg,
69 int flags) {
70 PRE_READ(msg, sizeof(*msg));
71}
72
Evgeniy Stepanov3ba4b902013-04-12 14:06:40 +000073POST_SYSCALL(recvmsg)(long res, int sockfd, struct sanitizer_kernel_msghdr *msg,
Evgeniy Stepanov2887a642013-04-11 14:37:04 +000074 int flags) {
75 if (res > 0)
Andy Gibbs102c0432013-04-16 15:18:55 +000076 for (unsigned long i = 0; i < msg->msg_iovlen; ++i) {
Evgeniy Stepanov2887a642013-04-11 14:37:04 +000077 POST_WRITE(msg->msg_iov[i].iov_base, msg->msg_iov[i].iov_len);
Andy Gibbs102c0432013-04-16 15:18:55 +000078 }
Evgeniy Stepanov2887a642013-04-11 14:37:04 +000079 POST_WRITE(msg->msg_control, msg->msg_controllen);
80}
81
82PRE_SYSCALL(rt_sigpending)(void *p, unsigned long s) { PRE_WRITE(p, s); }
83
Evgeniy Stepanov3ba4b902013-04-12 14:06:40 +000084POST_SYSCALL(rt_sigpending)(long res, void *p, unsigned long s) {
Andy Gibbs102c0432013-04-16 15:18:55 +000085 if (res == 0) {
Evgeniy Stepanov2887a642013-04-11 14:37:04 +000086 POST_WRITE(p, s);
Andy Gibbs102c0432013-04-16 15:18:55 +000087 }
Evgeniy Stepanov2887a642013-04-11 14:37:04 +000088}
89
90PRE_SYSCALL(getdents)(int fd, void *dirp, int count) { PRE_WRITE(dirp, count); }
91
Evgeniy Stepanov3ba4b902013-04-12 14:06:40 +000092POST_SYSCALL(getdents)(long res, int fd, void *dirp, int count) {
Andy Gibbs102c0432013-04-16 15:18:55 +000093 if (res > 0) {
Evgeniy Stepanov2887a642013-04-11 14:37:04 +000094 POST_WRITE(dirp, res);
Andy Gibbs102c0432013-04-16 15:18:55 +000095 }
Evgeniy Stepanov2887a642013-04-11 14:37:04 +000096}
97
98PRE_SYSCALL(getdents64)(int fd, void *dirp, int count) {
99 PRE_WRITE(dirp, count);
100}
101
Evgeniy Stepanov3ba4b902013-04-12 14:06:40 +0000102POST_SYSCALL(getdents64)(long res, int fd, void *dirp, int count) {
Andy Gibbs102c0432013-04-16 15:18:55 +0000103 if (res > 0) {
Evgeniy Stepanov2887a642013-04-11 14:37:04 +0000104 POST_WRITE(dirp, res);
Andy Gibbs102c0432013-04-16 15:18:55 +0000105 }
Evgeniy Stepanov2887a642013-04-11 14:37:04 +0000106}
107
Evgeniy Stepanovfa568962013-04-16 13:06:20 +0000108PRE_SYSCALL(wait4)(int pid, int *status, int options,
109 struct sanitizer_kernel_rusage *r) {
Andy Gibbs102c0432013-04-16 15:18:55 +0000110 if (status) {
Evgeniy Stepanovfa568962013-04-16 13:06:20 +0000111 PRE_WRITE(status, sizeof(*status));
Andy Gibbs102c0432013-04-16 15:18:55 +0000112 }
113 if (r) {
Evgeniy Stepanovfa568962013-04-16 13:06:20 +0000114 PRE_WRITE(r, sizeof(*r));
Andy Gibbs102c0432013-04-16 15:18:55 +0000115 }
Evgeniy Stepanovfa568962013-04-16 13:06:20 +0000116}
117
118POST_SYSCALL(wait4)(long res, int pid, int *status, int options,
119 struct sanitizer_kernel_rusage *r) {
120 if (res > 0) {
Andy Gibbs102c0432013-04-16 15:18:55 +0000121 if (status) {
Evgeniy Stepanovfa568962013-04-16 13:06:20 +0000122 POST_WRITE(status, sizeof(*status));
Andy Gibbs102c0432013-04-16 15:18:55 +0000123 }
124 if (r) {
Evgeniy Stepanovfa568962013-04-16 13:06:20 +0000125 POST_WRITE(r, sizeof(*r));
Andy Gibbs102c0432013-04-16 15:18:55 +0000126 }
Evgeniy Stepanovfa568962013-04-16 13:06:20 +0000127 }
128}
129
130PRE_SYSCALL(waitpid)(int pid, int *status, int options) {
Andy Gibbs102c0432013-04-16 15:18:55 +0000131 if (status) {
Evgeniy Stepanovfa568962013-04-16 13:06:20 +0000132 PRE_WRITE(status, sizeof(*status));
Andy Gibbs102c0432013-04-16 15:18:55 +0000133 }
Evgeniy Stepanovfa568962013-04-16 13:06:20 +0000134}
135
136POST_SYSCALL(waitpid)(long res, int pid, int *status, int options) {
Andy Gibbs102c0432013-04-16 15:18:55 +0000137 if (res > 0 && status) {
Evgeniy Stepanovfa568962013-04-16 13:06:20 +0000138 POST_WRITE(status, sizeof(*status));
Andy Gibbs102c0432013-04-16 15:18:55 +0000139 }
Evgeniy Stepanovfa568962013-04-16 13:06:20 +0000140}
Evgeniy Stepanov2887a642013-04-11 14:37:04 +0000141} // extern "C"
142
143#undef PRE_SYSCALL
144#undef PRE_READ
145#undef PRE_WRITE
146#undef POST_SYSCALL
147#undef POST_READ
148#undef POST_WRITE