sanitizer_common_syscalls.inc revision 9d34659cd3570423fb1fa49248887e2bd4b762f9
1//===-- 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" { 43struct 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 58struct sanitizer_kernel_timespec { 59 long tv_sec; 60 long tv_nsec; 61}; 62 63struct sanitizer_kernel_timeval { 64 long tv_sec; 65 long tv_usec; 66}; 67 68struct sanitizer_kernel_rusage { 69 struct sanitizer_kernel_timeval ru_timeval[2]; 70 long ru_long[14]; 71}; 72 73PRE_SYSCALL(recvmsg)(int sockfd, struct sanitizer_kernel_msghdr *msg, 74 int flags) { 75 PRE_READ(msg, sizeof(*msg)); 76} 77 78POST_SYSCALL(recvmsg)(long res, int sockfd, struct sanitizer_kernel_msghdr *msg, 79 int flags) { 80 if (res > 0) 81 for (unsigned long i = 0; i < msg->msg_iovlen; ++i) { 82 POST_WRITE(msg->msg_iov[i].iov_base, msg->msg_iov[i].iov_len); 83 } 84 POST_WRITE(msg->msg_control, msg->msg_controllen); 85} 86 87PRE_SYSCALL(rt_sigpending)(void *p, unsigned long s) { PRE_WRITE(p, s); } 88 89POST_SYSCALL(rt_sigpending)(long res, void *p, unsigned long s) { 90 if (res == 0) { 91 POST_WRITE(p, s); 92 } 93} 94 95PRE_SYSCALL(getdents)(int fd, void *dirp, int count) { PRE_WRITE(dirp, count); } 96 97POST_SYSCALL(getdents)(long res, int fd, void *dirp, int count) { 98 if (res > 0) { 99 POST_WRITE(dirp, res); 100 } 101} 102 103PRE_SYSCALL(getdents64)(int fd, void *dirp, int count) { 104 PRE_WRITE(dirp, count); 105} 106 107POST_SYSCALL(getdents64)(long res, int fd, void *dirp, int count) { 108 if (res > 0) { 109 POST_WRITE(dirp, res); 110 } 111} 112 113PRE_SYSCALL(wait4)(int pid, int *status, int options, 114 struct sanitizer_kernel_rusage *r) { 115 if (status) { 116 PRE_WRITE(status, sizeof(*status)); 117 } 118 if (r) { 119 PRE_WRITE(r, sizeof(*r)); 120 } 121} 122 123POST_SYSCALL(wait4)(long res, int pid, int *status, int options, 124 struct sanitizer_kernel_rusage *r) { 125 if (res > 0) { 126 if (status) { 127 POST_WRITE(status, sizeof(*status)); 128 } 129 if (r) { 130 POST_WRITE(r, sizeof(*r)); 131 } 132 } 133} 134 135PRE_SYSCALL(waitpid)(int pid, int *status, int options) { 136 if (status) { 137 PRE_WRITE(status, sizeof(*status)); 138 } 139} 140 141POST_SYSCALL(waitpid)(long res, int pid, int *status, int options) { 142 if (res > 0 && status) { 143 POST_WRITE(status, sizeof(*status)); 144 } 145} 146 147PRE_SYSCALL(clock_gettime)(int clk_id, struct sanitizer_kernel_timespec *tp) { 148 if (tp) PRE_WRITE(tp, sizeof(*tp)); 149} 150 151POST_SYSCALL(clock_gettime)(long res, int clk_id, 152 struct sanitizer_kernel_timespec *tp) { 153 if (res == 0 && tp) POST_WRITE(tp, sizeof(*tp)); 154} 155 156PRE_SYSCALL(clock_getres)(int clk_id, struct sanitizer_kernel_timespec *tp) { 157 if (tp) PRE_WRITE(tp, sizeof(*tp)); 158} 159 160POST_SYSCALL(clock_getres)(long res, int clk_id, 161 struct sanitizer_kernel_timespec *tp) { 162 if (res == 0 && tp) POST_WRITE(tp, sizeof(*tp)); 163} 164 165PRE_SYSCALL(read)(unsigned int fd, char *buf, uptr count) { 166 if (buf) PRE_WRITE(buf, count); 167} 168 169POST_SYSCALL(read)(long res, unsigned int fd, char *buf, uptr count) { 170 if (res > 0 && buf) POST_WRITE(buf, res); 171} 172 173} // extern "C" 174 175#undef PRE_SYSCALL 176#undef PRE_READ 177#undef PRE_WRITE 178#undef POST_SYSCALL 179#undef POST_READ 180#undef POST_WRITE 181