sanitizer_common_interceptors.inc revision 33b1485c3f1ea5a8089473ab1bb962d7bfb41d72
1//===-- sanitizer_common_interceptors.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 function interceptors 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_INTERCEPTOR_ENTER
16//   COMMON_INTERCEPTOR_READ_RANGE
17//   COMMON_INTERCEPTOR_WRITE_RANGE
18//   COMMON_INTERCEPTOR_FD_ACQUIRE
19//   COMMON_INTERCEPTOR_FD_RELEASE
20//   COMMON_INTERCEPTOR_SET_THREAD_NAME
21//===----------------------------------------------------------------------===//
22#include "interception/interception.h"
23#include "sanitizer_platform_interceptors.h"
24
25#include <stdarg.h>
26
27#if SANITIZER_WINDOWS
28#define va_copy(dst, src) ((dst) = (src))
29#endif // _WIN32
30
31#if SANITIZER_INTERCEPT_STRCASECMP
32static inline int CharCaseCmp(unsigned char c1, unsigned char c2) {
33  int c1_low = ToLower(c1);
34  int c2_low = ToLower(c2);
35  return c1_low - c2_low;
36}
37
38INTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) {
39  void *ctx;
40  COMMON_INTERCEPTOR_ENTER(ctx, strcasecmp, s1, s2);
41  unsigned char c1 = 0, c2 = 0;
42  uptr i;
43  for (i = 0; ; i++) {
44    c1 = (unsigned char)s1[i];
45    c2 = (unsigned char)s2[i];
46    if (CharCaseCmp(c1, c2) != 0 || c1 == '\0')
47      break;
48  }
49  COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, i + 1);
50  COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, i + 1);
51  return CharCaseCmp(c1, c2);
52}
53
54INTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, SIZE_T n) {
55  void *ctx;
56  COMMON_INTERCEPTOR_ENTER(ctx, strncasecmp, s1, s2, n);
57  unsigned char c1 = 0, c2 = 0;
58  uptr i;
59  for (i = 0; i < n; i++) {
60    c1 = (unsigned char)s1[i];
61    c2 = (unsigned char)s2[i];
62    if (CharCaseCmp(c1, c2) != 0 || c1 == '\0')
63      break;
64  }
65  COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, n));
66  COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, n));
67  return CharCaseCmp(c1, c2);
68}
69
70#define INIT_STRCASECMP INTERCEPT_FUNCTION(strcasecmp)
71#define INIT_STRNCASECMP INTERCEPT_FUNCTION(strncasecmp)
72#else
73#define INIT_STRCASECMP
74#define INIT_STRNCASECMP
75#endif
76
77#if SANITIZER_INTERCEPT_FREXP
78INTERCEPTOR(double, frexp, double x, int *exp) {
79  void *ctx;
80  COMMON_INTERCEPTOR_ENTER(ctx, frexp, x, exp);
81  double res = REAL(frexp)(x, exp);
82  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
83  return res;
84}
85
86#define INIT_FREXP INTERCEPT_FUNCTION(frexp);
87#else
88#define INIT_FREXP
89#endif // SANITIZER_INTERCEPT_FREXP
90
91#if SANITIZER_INTERCEPT_FREXPF_FREXPL
92INTERCEPTOR(float, frexpf, float x, int *exp) {
93  void *ctx;
94  COMMON_INTERCEPTOR_ENTER(ctx, frexpf, x, exp);
95  float res = REAL(frexpf)(x, exp);
96  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
97  return res;
98}
99
100INTERCEPTOR(long double, frexpl, long double x, int *exp) {
101  void *ctx;
102  COMMON_INTERCEPTOR_ENTER(ctx, frexpl, x, exp);
103  long double res = REAL(frexpl)(x, exp);
104  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
105  return res;
106}
107
108#define INIT_FREXPF_FREXPL                       \
109  INTERCEPT_FUNCTION(frexpf);                    \
110  INTERCEPT_FUNCTION(frexpl)
111#else
112#define INIT_FREXPF_FREXPL
113#endif // SANITIZER_INTERCEPT_FREXPF_FREXPL
114
115#if SANITIZER_INTERCEPT_READ
116INTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) {
117  void *ctx;
118  COMMON_INTERCEPTOR_ENTER(ctx, read, fd, ptr, count);
119  SSIZE_T res = REAL(read)(fd, ptr, count);
120  if (res > 0)
121    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
122  if (res >= 0 && fd >= 0)
123    COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
124  return res;
125}
126#define INIT_READ INTERCEPT_FUNCTION(read)
127#else
128#define INIT_READ
129#endif
130
131#if SANITIZER_INTERCEPT_PREAD
132INTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) {
133  void *ctx;
134  COMMON_INTERCEPTOR_ENTER(ctx, pread, fd, ptr, count, offset);
135  SSIZE_T res = REAL(pread)(fd, ptr, count, offset);
136  if (res > 0)
137    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
138  if (res >= 0 && fd >= 0)
139    COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
140  return res;
141}
142#define INIT_PREAD INTERCEPT_FUNCTION(pread)
143#else
144#define INIT_PREAD
145#endif
146
147#if SANITIZER_INTERCEPT_PREAD64
148INTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) {
149  void *ctx;
150  COMMON_INTERCEPTOR_ENTER(ctx, pread64, fd, ptr, count, offset);
151  SSIZE_T res = REAL(pread64)(fd, ptr, count, offset);
152  if (res > 0)
153    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
154  if (res >= 0 && fd >= 0)
155    COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
156  return res;
157}
158#define INIT_PREAD64 INTERCEPT_FUNCTION(pread64)
159#else
160#define INIT_PREAD64
161#endif
162
163#if SANITIZER_INTERCEPT_WRITE
164INTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) {
165  void *ctx;
166  COMMON_INTERCEPTOR_ENTER(ctx, write, fd, ptr, count);
167  if (fd >= 0)
168    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
169  SSIZE_T res = REAL(write)(fd, ptr, count);
170  if (res > 0)
171    COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
172  return res;
173}
174#define INIT_WRITE INTERCEPT_FUNCTION(write)
175#else
176#define INIT_WRITE
177#endif
178
179#if SANITIZER_INTERCEPT_PWRITE
180INTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) {
181  void *ctx;
182  COMMON_INTERCEPTOR_ENTER(ctx, pwrite, fd, ptr, count, offset);
183  if (fd >= 0)
184    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
185  SSIZE_T res = REAL(pwrite)(fd, ptr, count, offset);
186  if (res > 0)
187    COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
188  return res;
189}
190#define INIT_PWRITE INTERCEPT_FUNCTION(pwrite)
191#else
192#define INIT_PWRITE
193#endif
194
195#if SANITIZER_INTERCEPT_PWRITE64
196INTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count,
197            OFF64_T offset) {
198  void *ctx;
199  COMMON_INTERCEPTOR_ENTER(ctx, pwrite64, fd, ptr, count, offset);
200  if (fd >= 0)
201    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
202  SSIZE_T res = REAL(pwrite64)(fd, ptr, count, offset);
203  if (res > 0)
204    COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
205  return res;
206}
207#define INIT_PWRITE64 INTERCEPT_FUNCTION(pwrite64)
208#else
209#define INIT_PWRITE64
210#endif
211
212#if SANITIZER_INTERCEPT_PRCTL
213INTERCEPTOR(int, prctl, int option,
214            unsigned long arg2, unsigned long arg3,   // NOLINT
215            unsigned long arg4, unsigned long arg5) { // NOLINT
216  void *ctx;
217  COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5);
218  static const int PR_SET_NAME = 15;
219  int res = REAL(prctl(option, arg2, arg3, arg4, arg5));
220  if (option == PR_SET_NAME) {
221    char buff[16];
222    internal_strncpy(buff, (char *)arg2, 15);
223    buff[15] = 0;
224    COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff);
225  }
226  return res;
227}
228#define INIT_PRCTL INTERCEPT_FUNCTION(prctl)
229#else
230#define INIT_PRCTL
231#endif // SANITIZER_INTERCEPT_PRCTL
232
233
234#if SANITIZER_INTERCEPT_TIME
235INTERCEPTOR(unsigned long, time, unsigned long *t) {
236  void *ctx;
237  COMMON_INTERCEPTOR_ENTER(ctx, time, t);
238  unsigned long res = REAL(time)(t);
239  if (t && res != (unsigned long)-1) {
240    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, t, sizeof(*t));
241  }
242  return res;
243}
244#define INIT_TIME                                \
245  INTERCEPT_FUNCTION(time);
246#else
247#define INIT_TIME
248#endif // SANITIZER_INTERCEPT_TIME
249
250
251#if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
252INTERCEPTOR(void *, localtime, unsigned long *timep) {
253  void *ctx;
254  COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep);
255  void *res = REAL(localtime)(timep);
256  if (res) {
257    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
258    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz);
259  }
260  return res;
261}
262INTERCEPTOR(void *, localtime_r, unsigned long *timep, void *result) {
263  void *ctx;
264  COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result);
265  void *res = REAL(localtime_r)(timep, result);
266  if (res) {
267    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
268    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz);
269  }
270  return res;
271}
272INTERCEPTOR(void *, gmtime, unsigned long *timep) {
273  void *ctx;
274  COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep);
275  void *res = REAL(gmtime)(timep);
276  if (res) {
277    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
278    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz);
279  }
280  return res;
281}
282INTERCEPTOR(void *, gmtime_r, unsigned long *timep, void *result) {
283  void *ctx;
284  COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result);
285  void *res = REAL(gmtime_r)(timep, result);
286  if (res) {
287    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
288    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz);
289  }
290  return res;
291}
292INTERCEPTOR(char *, ctime, unsigned long *timep) {
293  void *ctx;
294  COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep);
295  char *res = REAL(ctime)(timep);
296  if (res) {
297    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
298    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
299  }
300  return res;
301}
302INTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) {
303  void *ctx;
304  COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result);
305  char *res = REAL(ctime_r)(timep, result);
306  if (res) {
307    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
308    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
309  }
310  return res;
311}
312INTERCEPTOR(char *, asctime, void *tm) {
313  void *ctx;
314  COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm);
315  char *res = REAL(asctime)(tm);
316  if (res) {
317    COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, struct_tm_sz);
318    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
319  }
320  return res;
321}
322INTERCEPTOR(char *, asctime_r, void *tm, char *result) {
323  void *ctx;
324  COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result);
325  char *res = REAL(asctime_r)(tm, result);
326  if (res) {
327    COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, struct_tm_sz);
328    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
329  }
330  return res;
331}
332#define INIT_LOCALTIME_AND_FRIENDS               \
333  INTERCEPT_FUNCTION(localtime);                 \
334  INTERCEPT_FUNCTION(localtime_r);               \
335  INTERCEPT_FUNCTION(gmtime);                    \
336  INTERCEPT_FUNCTION(gmtime_r);                  \
337  INTERCEPT_FUNCTION(ctime);                     \
338  INTERCEPT_FUNCTION(ctime_r);                   \
339  INTERCEPT_FUNCTION(asctime);                   \
340  INTERCEPT_FUNCTION(asctime_r);
341#else
342#define INIT_LOCALTIME_AND_FRIENDS
343#endif // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
344
345#if SANITIZER_INTERCEPT_SCANF
346
347#include "sanitizer_common_interceptors_scanf.inc"
348
349#define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...)                    \
350  {                                                                            \
351    void *ctx;                                                                 \
352    COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__);                         \
353    va_list aq;                                                                \
354    va_copy(aq, ap);                                                           \
355    int res = REAL(vname)(__VA_ARGS__);                                        \
356    if (res > 0)                                                               \
357      scanf_common(ctx, res, allowGnuMalloc, format, aq);                      \
358    va_end(aq);                                                                \
359    return res;                                                                \
360  }
361
362INTERCEPTOR(int, vscanf, const char *format, va_list ap)
363VSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap)
364
365INTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap)
366VSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap)
367
368INTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap)
369VSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap)
370
371#if SANITIZER_INTERCEPT_ISOC99_SCANF
372INTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap)
373VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap)
374
375INTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format,
376            va_list ap)
377VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap)
378
379INTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap)
380VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap)
381#endif  // SANITIZER_INTERCEPT_ISOC99_SCANF
382
383#define SCANF_INTERCEPTOR_IMPL(name, vname, ...)                               \
384  {                                                                            \
385    void *ctx;                                                                 \
386    COMMON_INTERCEPTOR_ENTER(ctx, name, __VA_ARGS__);                          \
387    va_list ap;                                                                \
388    va_start(ap, format);                                                      \
389    int res = vname(__VA_ARGS__, ap);                                          \
390    va_end(ap);                                                                \
391    return res;                                                                \
392  }
393
394INTERCEPTOR(int, scanf, const char *format, ...)
395SCANF_INTERCEPTOR_IMPL(scanf, vscanf, format)
396
397INTERCEPTOR(int, fscanf, void *stream, const char *format, ...)
398SCANF_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format)
399
400INTERCEPTOR(int, sscanf, const char *str, const char *format, ...)
401SCANF_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format)
402
403#if SANITIZER_INTERCEPT_ISOC99_SCANF
404INTERCEPTOR(int, __isoc99_scanf, const char *format, ...)
405SCANF_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format)
406
407INTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...)
408SCANF_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format)
409
410INTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...)
411SCANF_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format)
412#endif
413
414#define INIT_SCANF                                                             \
415  INTERCEPT_FUNCTION(scanf);                                                   \
416  INTERCEPT_FUNCTION(sscanf);                                                  \
417  INTERCEPT_FUNCTION(fscanf);                                                  \
418  INTERCEPT_FUNCTION(vscanf);                                                  \
419  INTERCEPT_FUNCTION(vsscanf);                                                 \
420  INTERCEPT_FUNCTION(vfscanf);                                                 \
421  INTERCEPT_FUNCTION(__isoc99_scanf);                                          \
422  INTERCEPT_FUNCTION(__isoc99_sscanf);                                         \
423  INTERCEPT_FUNCTION(__isoc99_fscanf);                                         \
424  INTERCEPT_FUNCTION(__isoc99_vscanf);                                         \
425  INTERCEPT_FUNCTION(__isoc99_vsscanf);                                        \
426  INTERCEPT_FUNCTION(__isoc99_vfscanf);
427
428#else
429#define INIT_SCANF
430#endif
431
432#if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS
433INTERCEPTOR(void *, getpwnam, const char *name) {
434  void *ctx;
435  COMMON_INTERCEPTOR_ENTER(ctx, getpwnam, name);
436  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
437  void *res = REAL(getpwnam)(name);
438  if (res != 0)
439    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_passwd_sz);
440  return res;
441}
442INTERCEPTOR(void *, getpwuid, u32 uid) {
443  void *ctx;
444  COMMON_INTERCEPTOR_ENTER(ctx, getpwuid, uid);
445  void *res = REAL(getpwuid)(uid);
446  if (res != 0)
447    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_passwd_sz);
448  return res;
449}
450INTERCEPTOR(void *, getgrnam, const char *name) {
451  void *ctx;
452  COMMON_INTERCEPTOR_ENTER(ctx, getgrnam, name);
453  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
454  void *res = REAL(getgrnam)(name);
455  if (res != 0)
456    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_group_sz);
457  return res;
458}
459INTERCEPTOR(void *, getgrgid, u32 gid) {
460  void *ctx;
461  COMMON_INTERCEPTOR_ENTER(ctx, getgrgid, gid);
462  void *res = REAL(getgrgid)(gid);
463  if (res != 0)
464    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_group_sz);
465  return res;
466}
467#define INIT_GETPWNAM_AND_FRIENDS                  \
468  INTERCEPT_FUNCTION(getpwnam);                    \
469  INTERCEPT_FUNCTION(getpwuid);                    \
470  INTERCEPT_FUNCTION(getgrnam);                    \
471  INTERCEPT_FUNCTION(getgrgid);
472#else
473#define INIT_GETPWNAM_AND_FRIENDS
474#endif
475
476
477#if SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS
478INTERCEPTOR(int, getpwnam_r, const char *name, void *pwd,
479    char *buf, SIZE_T buflen, void **result) {
480  void *ctx;
481  COMMON_INTERCEPTOR_ENTER(ctx, getpwnam_r, name, pwd, buf, buflen, result);
482  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
483  int res = REAL(getpwnam_r)(name, pwd, buf, buflen, result);
484  if (!res) {
485    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, struct_passwd_sz);
486    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
487  }
488  return res;
489}
490INTERCEPTOR(int, getpwuid_r, u32 uid, void *pwd,
491    char *buf, SIZE_T buflen, void **result) {
492  void *ctx;
493  COMMON_INTERCEPTOR_ENTER(ctx, getpwuid_r, uid, pwd, buf, buflen, result);
494  int res = REAL(getpwuid_r)(uid, pwd, buf, buflen, result);
495  if (!res) {
496    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, struct_passwd_sz);
497    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
498  }
499  return res;
500}
501INTERCEPTOR(int, getgrnam_r, const char *name, void *grp,
502    char *buf, SIZE_T buflen, void **result) {
503  void *ctx;
504  COMMON_INTERCEPTOR_ENTER(ctx, getgrnam_r, name, grp, buf, buflen, result);
505  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
506  int res = REAL(getgrnam_r)(name, grp, buf, buflen, result);
507  if (!res) {
508    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, struct_group_sz);
509    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
510  }
511  return res;
512}
513INTERCEPTOR(int, getgrgid_r, u32 gid, void *grp,
514    char *buf, SIZE_T buflen, void **result) {
515  void *ctx;
516  COMMON_INTERCEPTOR_ENTER(ctx, getgrgid_r, gid, grp, buf, buflen, result);
517  int res = REAL(getgrgid_r)(gid, grp, buf, buflen, result);
518  if (!res) {
519    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, struct_group_sz);
520    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
521  }
522  return res;
523}
524#define INIT_GETPWNAM_R_AND_FRIENDS                \
525  INTERCEPT_FUNCTION(getpwnam_r);                  \
526  INTERCEPT_FUNCTION(getpwuid_r);                  \
527  INTERCEPT_FUNCTION(getgrnam_r);                  \
528  INTERCEPT_FUNCTION(getgrgid_r);
529#else
530#define INIT_GETPWNAM_R_AND_FRIENDS
531#endif
532
533
534#if SANITIZER_INTERCEPT_CLOCK_GETTIME
535INTERCEPTOR(int, clock_getres, u32 clk_id, void *tp) {
536  void *ctx;
537  COMMON_INTERCEPTOR_ENTER(ctx, clock_getres, clk_id, tp);
538  int res = REAL(clock_getres)(clk_id, tp);
539  if (!res && tp) {
540    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);
541  }
542  return res;
543}
544INTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) {
545  void *ctx;
546  COMMON_INTERCEPTOR_ENTER(ctx, clock_gettime, clk_id, tp);
547  int res = REAL(clock_gettime)(clk_id, tp);
548  if (!res) {
549    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);
550  }
551  return res;
552}
553INTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) {
554  void *ctx;
555  COMMON_INTERCEPTOR_ENTER(ctx, clock_settime, clk_id, tp);
556  COMMON_INTERCEPTOR_READ_RANGE(ctx, tp, struct_timespec_sz);
557  return REAL(clock_settime)(clk_id, tp);
558}
559#define INIT_CLOCK_GETTIME                         \
560  INTERCEPT_FUNCTION(clock_getres);                \
561  INTERCEPT_FUNCTION(clock_gettime);               \
562  INTERCEPT_FUNCTION(clock_settime);
563#else
564#define INIT_CLOCK_GETTIME
565#endif
566
567
568#if SANITIZER_INTERCEPT_GETITIMER
569INTERCEPTOR(int, getitimer, int which, void *curr_value) {
570  void *ctx;
571  COMMON_INTERCEPTOR_ENTER(ctx, getitimer, which, curr_value);
572  int res = REAL(getitimer)(which, curr_value);
573  if (!res) {
574    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerval_sz);
575  }
576  return res;
577}
578INTERCEPTOR(int, setitimer, int which, const void *new_value, void *old_value) {
579  void *ctx;
580  COMMON_INTERCEPTOR_ENTER(ctx, setitimer, which, new_value, old_value);
581  COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerval_sz);
582  int res = REAL(setitimer)(which, new_value, old_value);
583  if (!res && old_value) {
584    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerval_sz);
585  }
586  return res;
587}
588#define INIT_GETITIMER                             \
589  INTERCEPT_FUNCTION(getitimer);                   \
590  INTERCEPT_FUNCTION(setitimer);
591#else
592#define INIT_GETITIMER
593#endif
594
595
596#if SANITIZER_INTERCEPT_GLOB
597struct sanitizer_glob_t {
598  SIZE_T gl_pathc;
599  char **gl_pathv;
600};
601
602static void unpoison_glob_t(void *ctx, sanitizer_glob_t *pglob) {
603  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob));
604  // +1 for NULL pointer at the end.
605  COMMON_INTERCEPTOR_WRITE_RANGE(
606      ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv));
607  for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) {
608    char *p = pglob->gl_pathv[i];
609    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, REAL(strlen)(p) + 1);
610  }
611}
612
613INTERCEPTOR(int, glob, const char *pattern, int flags,
614            int (*errfunc)(const char *epath, int eerrno),
615            sanitizer_glob_t *pglob) {
616  void *ctx;
617  COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob);
618  int res = REAL(glob)(pattern, flags, errfunc, pglob);
619  if (res == 0)
620    unpoison_glob_t(ctx, pglob);
621  return res;
622}
623
624INTERCEPTOR(int, glob64, const char *pattern, int flags,
625            int (*errfunc)(const char *epath, int eerrno),
626            sanitizer_glob_t *pglob) {
627  void *ctx;
628  COMMON_INTERCEPTOR_ENTER(ctx, glob64, pattern, flags, errfunc, pglob);
629  int res = REAL(glob64)(pattern, flags, errfunc, pglob);
630  if (res == 0)
631    unpoison_glob_t(ctx, pglob);
632  return res;
633}
634#define INIT_GLOB                               \
635  INTERCEPT_FUNCTION(glob);                     \
636  INTERCEPT_FUNCTION(glob64);
637#else // SANITIZER_INTERCEPT_GLOB
638#define INIT_GLOB
639#endif // SANITIZER_INTERCEPT_GLOB
640
641
642#if SANITIZER_INTERCEPT_WAIT
643// According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version
644// suffixes on Darwin. See the declaration of INTERCEPTOR_WITH_SUFFIX for
645// details.
646INTERCEPTOR_WITH_SUFFIX(int, wait, int *status) {
647  void *ctx;
648  COMMON_INTERCEPTOR_ENTER(ctx, wait, status);
649  int res = REAL(wait)(status);
650  if (res != -1 && status)
651    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
652  return res;
653}
654INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, int id, void *infop,
655  int options) {
656  void *ctx;
657  COMMON_INTERCEPTOR_ENTER(ctx, waitid, idtype, id, infop, options);
658  int res = REAL(waitid)(idtype, id, infop, options);
659  if (res != -1 && infop)
660    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, infop, siginfo_t_sz);
661  return res;
662}
663INTERCEPTOR_WITH_SUFFIX(int, waitpid, int pid, int *status, int options) {
664  void *ctx;
665  COMMON_INTERCEPTOR_ENTER(ctx, waitpid, pid, status, options);
666  int res = REAL(waitpid)(pid, status, options);
667  if (res != -1 && status)
668    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
669  return res;
670}
671INTERCEPTOR(int, wait3, int *status, int options, void *rusage) {
672  void *ctx;
673  COMMON_INTERCEPTOR_ENTER(ctx, wait3, status, options, rusage);
674  int res = REAL(wait3)(status, options, rusage);
675  if (res != -1) {
676    if (status)
677      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
678    if (rusage)
679      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
680  }
681  return res;
682}
683INTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) {
684  void *ctx;
685  COMMON_INTERCEPTOR_ENTER(ctx, wait4, pid, status, options, rusage);
686  int res = REAL(wait4)(pid, status, options, rusage);
687  if (res != -1) {
688    if (status)
689      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
690    if (rusage)
691      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
692  }
693  return res;
694}
695#define INIT_WAIT                                \
696  INTERCEPT_FUNCTION(wait);                      \
697  INTERCEPT_FUNCTION(waitid);                    \
698  INTERCEPT_FUNCTION(waitpid);                   \
699  INTERCEPT_FUNCTION(wait3);                     \
700  INTERCEPT_FUNCTION(wait4);
701#else
702#define INIT_WAIT
703#endif
704
705#if SANITIZER_INTERCEPT_INET
706INTERCEPTOR(char *, inet_ntop, int af, const void *src, char *dst, u32 size) {
707  void *ctx;
708  COMMON_INTERCEPTOR_ENTER(ctx, inet_ntop, af, src, dst, size);
709  uptr sz = __sanitizer_in_addr_sz(af);
710  if (sz) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sz);
711  // FIXME: figure out read size based on the address family.
712  char *res = REAL(inet_ntop)(af, src, dst, size);
713  if (res)
714    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
715  return res;
716}
717INTERCEPTOR(int, inet_pton, int af, const char *src, void *dst) {
718  void *ctx;
719  COMMON_INTERCEPTOR_ENTER(ctx, inet_pton, af, src, dst);
720  // FIXME: figure out read size based on the address family.
721  int res = REAL(inet_pton)(af, src, dst);
722  if (res == 1) {
723    uptr sz = __sanitizer_in_addr_sz(af);
724    if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);
725  }
726  return res;
727}
728#define INIT_INET                                \
729  INTERCEPT_FUNCTION(inet_ntop);                 \
730  INTERCEPT_FUNCTION(inet_pton);
731#else
732#define INIT_INET
733#endif
734
735#if SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM
736INTERCEPTOR(int, pthread_getschedparam, uptr thread, int *policy, int *param) {
737  void *ctx;
738  COMMON_INTERCEPTOR_ENTER(ctx, pthread_getschedparam, thread, policy, param);
739  int res = REAL(pthread_getschedparam)(thread, policy, param);
740  if (res == 0) {
741    if (policy) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, policy, sizeof(*policy));
742    if (param) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, sizeof(*param));
743  }
744  return res;
745}
746#define INIT_PTHREAD_GETSCHEDPARAM INTERCEPT_FUNCTION(pthread_getschedparam);
747#else
748#define INIT_PTHREAD_GETSCHEDPARAM
749#endif
750
751#if SANITIZER_INTERCEPT_GETADDRINFO
752INTERCEPTOR(int, getaddrinfo, char *node, char *service,
753            struct __sanitizer_addrinfo *hints,
754            struct __sanitizer_addrinfo **out) {
755  void *ctx;
756  COMMON_INTERCEPTOR_ENTER(ctx, getaddrinfo, node, service, hints, out);
757  if (node) COMMON_INTERCEPTOR_READ_RANGE(ctx, node, REAL(strlen)(node) + 1);
758  if (service)
759    COMMON_INTERCEPTOR_READ_RANGE(ctx, service, REAL(strlen)(service) + 1);
760  if (hints)
761    COMMON_INTERCEPTOR_READ_RANGE(ctx, hints, sizeof(__sanitizer_addrinfo));
762  int res = REAL(getaddrinfo)(node, service, hints, out);
763  if (res == 0) {
764    struct __sanitizer_addrinfo *p = *out;
765    while (p) {
766      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(__sanitizer_addrinfo));
767      if (p->ai_addr)
768        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_addr, struct_sockaddr_sz);
769      if (p->ai_canonname)
770        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_canonname,
771                                       REAL(strlen)(p->ai_canonname) + 1);
772      p = p->ai_next;
773    }
774  }
775  return res;
776}
777#define INIT_GETADDRINFO INTERCEPT_FUNCTION(getaddrinfo);
778#else
779#define INIT_GETADDRINFO
780#endif
781
782#if SANITIZER_INTERCEPT_GETSOCKNAME
783INTERCEPTOR(int, getsockname, int sock_fd, void *addr, int *addrlen) {
784  void *ctx;
785  COMMON_INTERCEPTOR_ENTER(ctx, getsockname, sock_fd, addr, addrlen);
786  COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
787  int addrlen_in = *addrlen;
788  int res = REAL(getsockname)(sock_fd, addr, addrlen);
789  if (res == 0) {
790    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addrlen_in, *addrlen));
791  }
792  return res;
793}
794#define INIT_GETSOCKNAME INTERCEPT_FUNCTION(getsockname);
795#else
796#define INIT_GETSOCKNAME
797#endif
798
799#if SANITIZER_INTERCEPT_GETHOSTBYNAME || SANITIZER_INTERCEPT_GETHOSTBYNAME_R
800static void write_hostent(void *ctx, struct __sanitizer_hostent *h) {
801  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h, sizeof(__sanitizer_hostent));
802  if (h->h_name)
803    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h->h_name, REAL(strlen)(h->h_name) + 1);
804  char **p = h->h_aliases;
805  while (*p) {
806    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1);
807    ++p;
808  }
809  COMMON_INTERCEPTOR_WRITE_RANGE(
810      ctx, h->h_aliases, (p - h->h_aliases + 1) * sizeof(*h->h_aliases));
811  p = h->h_addr_list;
812  while (*p) {
813    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, h->h_length);
814    ++p;
815  }
816  COMMON_INTERCEPTOR_WRITE_RANGE(
817      ctx, h->h_addr_list, (p - h->h_addr_list + 1) * sizeof(*h->h_addr_list));
818}
819#endif
820
821#if SANITIZER_INTERCEPT_GETHOSTBYNAME
822INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname, char *name) {
823  void *ctx;
824  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname, name);
825  struct __sanitizer_hostent *res = REAL(gethostbyname)(name);
826  if (res) write_hostent(ctx, res);
827  return res;
828}
829
830INTERCEPTOR(struct __sanitizer_hostent *, gethostbyaddr, void *addr, int len,
831            int type) {
832  void *ctx;
833  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr, addr, len, type);
834  COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);
835  struct __sanitizer_hostent *res = REAL(gethostbyaddr)(addr, len, type);
836  if (res) write_hostent(ctx, res);
837  return res;
838}
839
840INTERCEPTOR(struct __sanitizer_hostent *, gethostent) {
841  void *ctx;
842  COMMON_INTERCEPTOR_ENTER(ctx, gethostent);
843  struct __sanitizer_hostent *res = REAL(gethostent)();
844  if (res) write_hostent(ctx, res);
845  return res;
846}
847
848INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname2, char *name, int af) {
849  void *ctx;
850  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2, name, af);
851  struct __sanitizer_hostent *res = REAL(gethostbyname2)(name, af);
852  if (res) write_hostent(ctx, res);
853  return res;
854}
855#define INIT_GETHOSTBYNAME           \
856  INTERCEPT_FUNCTION(gethostent);    \
857  INTERCEPT_FUNCTION(gethostbyaddr); \
858  INTERCEPT_FUNCTION(gethostbyname); \
859  INTERCEPT_FUNCTION(gethostbyname2);
860#else
861#define INIT_GETHOSTBYNAME
862#endif
863
864#if SANITIZER_INTERCEPT_GETHOSTBYNAME_R
865INTERCEPTOR(int, gethostent_r, struct __sanitizer_hostent *ret, char *buf,
866            SIZE_T buflen, __sanitizer_hostent **result, int *h_errnop) {
867  void *ctx;
868  COMMON_INTERCEPTOR_ENTER(ctx, gethostent_r, ret, buf, buflen, result,
869                           h_errnop);
870  int res = REAL(gethostent_r)(ret, buf, buflen, result, h_errnop);
871  if (res == 0) {
872    if (result) {
873      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
874      if (*result) write_hostent(ctx, *result);
875    }
876    if (h_errnop)
877      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
878  }
879  return res;
880}
881
882INTERCEPTOR(int, gethostbyaddr_r, void *addr, int len, int type,
883            struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,
884            __sanitizer_hostent **result, int *h_errnop) {
885  void *ctx;
886  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr_r, addr, len, type, ret, buf,
887                           buflen, result, h_errnop);
888  COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);
889  int res = REAL(gethostbyaddr_r)(addr, len, type, ret, buf, buflen, result,
890                                  h_errnop);
891  if (res == 0) {
892    if (result) {
893      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
894      if (*result) write_hostent(ctx, *result);
895    }
896    if (h_errnop)
897      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
898  }
899  return res;
900}
901
902INTERCEPTOR(int, gethostbyname_r, char *name, struct __sanitizer_hostent *ret,
903            char *buf, SIZE_T buflen, __sanitizer_hostent **result,
904            int *h_errnop) {
905  void *ctx;
906  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname_r, name, ret, buf, buflen, result,
907                           h_errnop);
908  int res = REAL(gethostbyname_r)(name, ret, buf, buflen, result, h_errnop);
909  if (res == 0) {
910    if (result) {
911      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
912      if (*result) write_hostent(ctx, *result);
913    }
914    if (h_errnop)
915      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
916  }
917  return res;
918}
919
920INTERCEPTOR(int, gethostbyname2_r, char *name, int af,
921            struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,
922            __sanitizer_hostent **result, int *h_errnop) {
923  void *ctx;
924  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2_r, name, af, ret, buf, buflen,
925                           result, h_errnop);
926  int res =
927      REAL(gethostbyname2_r)(name, af, ret, buf, buflen, result, h_errnop);
928  if (res == 0) {
929    if (result) {
930      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
931      if (*result) write_hostent(ctx, *result);
932    }
933    if (h_errnop)
934      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
935  }
936  return res;
937}
938#define INIT_GETHOSTBYNAME_R           \
939  INTERCEPT_FUNCTION(gethostent_r);    \
940  INTERCEPT_FUNCTION(gethostbyaddr_r); \
941  INTERCEPT_FUNCTION(gethostbyname_r); \
942  INTERCEPT_FUNCTION(gethostbyname2_r);
943#else
944#define INIT_GETHOSTBYNAME_R
945#endif
946
947#if SANITIZER_INTERCEPT_GETSOCKOPT
948INTERCEPTOR(int, getsockopt, int sockfd, int level, int optname, void *optval,
949            int *optlen) {
950  void *ctx;
951  COMMON_INTERCEPTOR_ENTER(ctx, getsockopt, sockfd, level, optname, optval,
952                           optlen);
953  if (optlen) COMMON_INTERCEPTOR_READ_RANGE(ctx, optlen, sizeof(*optlen));
954  int res = REAL(getsockopt)(sockfd, level, optname, optval, optlen);
955  if (res == 0)
956    if (optval && optlen) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, optval, *optlen);
957  return res;
958}
959#define INIT_GETSOCKOPT INTERCEPT_FUNCTION(getsockopt);
960#else
961#define INIT_GETSOCKOPT
962#endif
963
964#define SANITIZER_COMMON_INTERCEPTORS_INIT \
965  INIT_STRCASECMP;                         \
966  INIT_STRNCASECMP;                        \
967  INIT_READ;                               \
968  INIT_PREAD;                              \
969  INIT_PREAD64;                            \
970  INIT_PRCTL;                              \
971  INIT_WRITE;                              \
972  INIT_PWRITE;                             \
973  INIT_PWRITE64;                           \
974  INIT_LOCALTIME_AND_FRIENDS;              \
975  INIT_SCANF;                              \
976  INIT_FREXP;                              \
977  INIT_FREXPF_FREXPL;                      \
978  INIT_GETPWNAM_AND_FRIENDS;               \
979  INIT_GETPWNAM_R_AND_FRIENDS;             \
980  INIT_CLOCK_GETTIME;                      \
981  INIT_GETITIMER;                          \
982  INIT_TIME;                               \
983  INIT_GLOB;                               \
984  INIT_WAIT;                               \
985  INIT_INET;                               \
986  INIT_PTHREAD_GETSCHEDPARAM;              \
987  INIT_GETADDRINFO;                        \
988  INIT_GETSOCKNAME;                        \
989  INIT_GETHOSTBYNAME;                      \
990  INIT_GETHOSTBYNAME_R;                    \
991  INIT_GETSOCKOPT;
992