sanitizer_common_interceptors.inc revision 1.2
1//===-- sanitizer_common_interceptors.inc -----------------------*- C++ -*-===//
2//
3// This file is distributed under the University of Illinois Open Source
4// License. See LICENSE.TXT for details.
5//
6//===----------------------------------------------------------------------===//
7//
8// Common function interceptors for tools like AddressSanitizer,
9// ThreadSanitizer, MemorySanitizer, etc.
10//
11// This file should be included into the tool's interceptor file,
12// which has to define it's own macros:
13//   COMMON_INTERCEPTOR_ENTER
14//   COMMON_INTERCEPTOR_READ_RANGE
15//   COMMON_INTERCEPTOR_WRITE_RANGE
16//   COMMON_INTERCEPTOR_FD_ACQUIRE
17//   COMMON_INTERCEPTOR_FD_RELEASE
18//   COMMON_INTERCEPTOR_SET_THREAD_NAME
19//===----------------------------------------------------------------------===//
20#include "interception/interception.h"
21#include "sanitizer_platform_interceptors.h"
22
23#include <stdarg.h>
24
25#ifdef _WIN32
26#define va_copy(dst, src) ((dst) = (src))
27#endif // _WIN32
28
29#if SANITIZER_INTERCEPT_READ
30INTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) {
31  void *ctx;
32  COMMON_INTERCEPTOR_ENTER(ctx, read, fd, ptr, count);
33  SSIZE_T res = REAL(read)(fd, ptr, count);
34  if (res > 0)
35    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
36  if (res >= 0 && fd >= 0)
37    COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
38  return res;
39}
40#define INIT_READ INTERCEPT_FUNCTION(read)
41#else
42#define INIT_READ
43#endif
44
45#if SANITIZER_INTERCEPT_PREAD
46INTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) {
47  void *ctx;
48  COMMON_INTERCEPTOR_ENTER(ctx, pread, fd, ptr, count, offset);
49  SSIZE_T res = REAL(pread)(fd, ptr, count, offset);
50  if (res > 0)
51    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
52  if (res >= 0 && fd >= 0)
53    COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
54  return res;
55}
56#define INIT_PREAD INTERCEPT_FUNCTION(pread)
57#else
58#define INIT_PREAD
59#endif
60
61#if SANITIZER_INTERCEPT_PREAD64
62INTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) {
63  void *ctx;
64  COMMON_INTERCEPTOR_ENTER(ctx, pread64, fd, ptr, count, offset);
65  SSIZE_T res = REAL(pread64)(fd, ptr, count, offset);
66  if (res > 0)
67    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
68  if (res >= 0 && fd >= 0)
69    COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
70  return res;
71}
72#define INIT_PREAD64 INTERCEPT_FUNCTION(pread64)
73#else
74#define INIT_PREAD64
75#endif
76
77#if SANITIZER_INTERCEPT_WRITE
78INTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) {
79  void *ctx;
80  COMMON_INTERCEPTOR_ENTER(ctx, write, fd, ptr, count);
81  if (fd >= 0)
82    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
83  SSIZE_T res = REAL(write)(fd, ptr, count);
84  if (res > 0)
85    COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
86  return res;
87}
88#define INIT_WRITE INTERCEPT_FUNCTION(write)
89#else
90#define INIT_WRITE
91#endif
92
93#if SANITIZER_INTERCEPT_PWRITE
94INTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) {
95  void *ctx;
96  COMMON_INTERCEPTOR_ENTER(ctx, pwrite, fd, ptr, count, offset);
97  if (fd >= 0)
98    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
99  SSIZE_T res = REAL(pwrite)(fd, ptr, count, offset);
100  if (res > 0)
101    COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
102  return res;
103}
104#define INIT_PWRITE INTERCEPT_FUNCTION(pwrite)
105#else
106#define INIT_PWRITE
107#endif
108
109#if SANITIZER_INTERCEPT_PWRITE64
110INTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count,
111            OFF64_T offset) {
112  void *ctx;
113  COMMON_INTERCEPTOR_ENTER(ctx, pwrite64, fd, ptr, count, offset);
114  if (fd >= 0)
115    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
116  SSIZE_T res = REAL(pwrite64)(fd, ptr, count, offset);
117  if (res > 0)
118    COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
119  return res;
120}
121#define INIT_PWRITE64 INTERCEPT_FUNCTION(pwrite64)
122#else
123#define INIT_PWRITE64
124#endif
125
126#if SANITIZER_INTERCEPT_PRCTL
127INTERCEPTOR(int, prctl, int option,
128            unsigned long arg2, unsigned long arg3,   // NOLINT
129            unsigned long arg4, unsigned long arg5) { // NOLINT
130  void *ctx;
131  COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5);
132  static const int PR_SET_NAME = 15;
133  int res = REAL(prctl(option, arg2, arg3, arg4, arg5));
134  if (option == PR_SET_NAME) {
135    char buff[16];
136    internal_strncpy(buff, (char *)arg2, 15);
137    buff[15] = 0;
138    COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff);
139  }
140  return res;
141}
142#define INIT_PRCTL INTERCEPT_FUNCTION(prctl)
143#else
144#define INIT_PRCTL
145#endif // SANITIZER_INTERCEPT_PRCTL
146
147#if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
148INTERCEPTOR(void *, localtime, unsigned long *timep) {
149  void *ctx;
150  COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep);
151  void *res = REAL(localtime)(timep);
152  if (res) {
153    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
154    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz);
155  }
156  return res;
157}
158INTERCEPTOR(void *, localtime_r, unsigned long *timep, void *result) {
159  void *ctx;
160  COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result);
161  void *res = REAL(localtime_r)(timep, result);
162  if (res) {
163    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
164    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz);
165  }
166  return res;
167}
168INTERCEPTOR(void *, gmtime, unsigned long *timep) {
169  void *ctx;
170  COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep);
171  void *res = REAL(gmtime)(timep);
172  if (res) {
173    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
174    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz);
175  }
176  return res;
177}
178INTERCEPTOR(void *, gmtime_r, unsigned long *timep, void *result) {
179  void *ctx;
180  COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result);
181  void *res = REAL(gmtime_r)(timep, result);
182  if (res) {
183    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
184    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz);
185  }
186  return res;
187}
188INTERCEPTOR(char *, ctime, unsigned long *timep) {
189  void *ctx;
190  COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep);
191  char *res = REAL(ctime)(timep);
192  if (res) {
193    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
194    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
195  }
196  return res;
197}
198INTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) {
199  void *ctx;
200  COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result);
201  char *res = REAL(ctime_r)(timep, result);
202  if (res) {
203    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
204    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
205  }
206  return res;
207}
208INTERCEPTOR(char *, asctime, void *tm) {
209  void *ctx;
210  COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm);
211  char *res = REAL(asctime)(tm);
212  if (res) {
213    COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, struct_tm_sz);
214    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
215  }
216  return res;
217}
218INTERCEPTOR(char *, asctime_r, void *tm, char *result) {
219  void *ctx;
220  COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result);
221  char *res = REAL(asctime_r)(tm, result);
222  if (res) {
223    COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, struct_tm_sz);
224    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
225  }
226  return res;
227}
228#define INIT_LOCALTIME_AND_FRIENDS               \
229  INTERCEPT_FUNCTION(localtime);                 \
230  INTERCEPT_FUNCTION(localtime_r);               \
231  INTERCEPT_FUNCTION(gmtime);                    \
232  INTERCEPT_FUNCTION(gmtime_r);                  \
233  INTERCEPT_FUNCTION(ctime);                     \
234  INTERCEPT_FUNCTION(ctime_r);                   \
235  INTERCEPT_FUNCTION(asctime);                   \
236  INTERCEPT_FUNCTION(asctime_r);
237#else
238#define INIT_LOCALTIME_AND_FRIENDS
239#endif // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
240
241#if SANITIZER_INTERCEPT_SCANF
242
243#include "sanitizer_common_interceptors_scanf.inc"
244
245#define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...)                    \
246  {                                                                            \
247    void *ctx;                                                                 \
248    COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__);                         \
249    va_list aq;                                                                \
250    va_copy(aq, ap);                                                           \
251    int res = REAL(vname)(__VA_ARGS__);                                        \
252    if (res > 0)                                                               \
253      scanf_common(ctx, res, allowGnuMalloc, format, aq);                      \
254    va_end(aq);                                                                \
255    return res;                                                                \
256  }
257
258INTERCEPTOR(int, vscanf, const char *format, va_list ap)
259VSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap)
260
261INTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap)
262VSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap)
263
264INTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap)
265VSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap)
266
267#if SANITIZER_INTERCEPT_ISOC99_SCANF
268INTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap)
269VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap)
270
271INTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format,
272            va_list ap)
273VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap)
274
275INTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap)
276VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap)
277#endif  // SANITIZER_INTERCEPT_ISOC99_SCANF
278
279#define SCANF_INTERCEPTOR_IMPL(name, vname, ...)                               \
280  {                                                                            \
281    void *ctx;                                                                 \
282    COMMON_INTERCEPTOR_ENTER(ctx, name, __VA_ARGS__);                          \
283    va_list ap;                                                                \
284    va_start(ap, format);                                                      \
285    int res = vname(__VA_ARGS__, ap);                                          \
286    va_end(ap);                                                                \
287    return res;                                                                \
288  }
289
290INTERCEPTOR(int, scanf, const char *format, ...)
291SCANF_INTERCEPTOR_IMPL(scanf, vscanf, format)
292
293INTERCEPTOR(int, fscanf, void *stream, const char *format, ...)
294SCANF_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format)
295
296INTERCEPTOR(int, sscanf, const char *str, const char *format, ...)
297SCANF_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format)
298
299#define INIT_SCANF_NORMAL                                                      \
300  INTERCEPT_FUNCTION(scanf);                                                   \
301  INTERCEPT_FUNCTION(sscanf);                                                  \
302  INTERCEPT_FUNCTION(fscanf);                                                  \
303  INTERCEPT_FUNCTION(vscanf);                                                  \
304  INTERCEPT_FUNCTION(vsscanf);                                                 \
305  INTERCEPT_FUNCTION(vfscanf);                                                 \
306
307#if SANITIZER_INTERCEPT_ISOC99_SCANF
308INTERCEPTOR(int, __isoc99_scanf, const char *format, ...)
309SCANF_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format)
310
311INTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...)
312SCANF_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format)
313
314INTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...)
315SCANF_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format)
316
317
318#define INIT_SCANF_ISOC99						       \
319  INTERCEPT_FUNCTION(__isoc99_scanf);                                          \
320  INTERCEPT_FUNCTION(__isoc99_sscanf);                                         \
321  INTERCEPT_FUNCTION(__isoc99_fscanf);                                         \
322  INTERCEPT_FUNCTION(__isoc99_vscanf);                                         \
323  INTERCEPT_FUNCTION(__isoc99_vsscanf);                                        \
324  INTERCEPT_FUNCTION(__isoc99_vfscanf);
325#else
326#define INIT_SCANF_ISOC99
327#endif
328
329#define INIT_SCANF							       \
330  INIT_SCANF_NORMAL							       \
331  INIT_SCANF_ISOC99
332
333#else
334#define INIT_SCANF
335#endif
336
337#define SANITIZER_COMMON_INTERCEPTORS_INIT                                     \
338  INIT_READ;                                                                   \
339  INIT_PREAD;                                                                  \
340  INIT_PREAD64;                                                                \
341  INIT_PRCTL;                                                                  \
342  INIT_WRITE;                                                                  \
343  INIT_PWRITE;                                                                 \
344  INIT_PWRITE64;                                                               \
345  INIT_LOCALTIME_AND_FRIENDS;                                                  \
346  INIT_SCANF;
347