]> git.proxmox.com Git - rustc.git/blame - src/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
Imported Upstream version 1.6.0+dfsg1
[rustc.git] / src / compiler-rt / lib / sanitizer_common / sanitizer_common_interceptors.inc
CommitLineData
1a4d82fc
JJ
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
92a42be0 16// COMMON_INTERCEPTOR_ENTER_NOIGNORE
1a4d82fc
JJ
17// COMMON_INTERCEPTOR_READ_RANGE
18// COMMON_INTERCEPTOR_WRITE_RANGE
19// COMMON_INTERCEPTOR_INITIALIZE_RANGE
92a42be0 20// COMMON_INTERCEPTOR_DIR_ACQUIRE
1a4d82fc
JJ
21// COMMON_INTERCEPTOR_FD_ACQUIRE
22// COMMON_INTERCEPTOR_FD_RELEASE
23// COMMON_INTERCEPTOR_FD_ACCESS
24// COMMON_INTERCEPTOR_SET_THREAD_NAME
92a42be0 25// COMMON_INTERCEPTOR_ON_DLOPEN
1a4d82fc
JJ
26// COMMON_INTERCEPTOR_ON_EXIT
27// COMMON_INTERCEPTOR_MUTEX_LOCK
28// COMMON_INTERCEPTOR_MUTEX_UNLOCK
29// COMMON_INTERCEPTOR_MUTEX_REPAIR
30// COMMON_INTERCEPTOR_SET_PTHREAD_NAME
31// COMMON_INTERCEPTOR_HANDLE_RECVMSG
92a42be0 32// COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED
1a4d82fc 33//===----------------------------------------------------------------------===//
92a42be0 34
1a4d82fc 35#include "interception/interception.h"
92a42be0
SL
36#include "sanitizer_addrhashmap.h"
37#include "sanitizer_placement_new.h"
1a4d82fc
JJ
38#include "sanitizer_platform_interceptors.h"
39#include "sanitizer_tls_get_addr.h"
40
41#include <stdarg.h>
42
92a42be0
SL
43#if SANITIZER_INTERCEPTOR_HOOKS
44#define CALL_WEAK_INTERCEPTOR_HOOK(f, ...) \
45 do { \
46 if (f) \
47 f(__VA_ARGS__); \
48 } while (false);
49#define DECLARE_WEAK_INTERCEPTOR_HOOK(f, ...) \
50 extern "C" { \
51 SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void f(__VA_ARGS__); \
52 } // extern "C"
53#else
54#define DECLARE_WEAK_INTERCEPTOR_HOOK(f, ...)
55#define CALL_WEAK_INTERCEPTOR_HOOK(f, ...)
56
57#endif // SANITIZER_INTERCEPTOR_HOOKS
58
1a4d82fc
JJ
59#if SANITIZER_WINDOWS && !defined(va_copy)
60#define va_copy(dst, src) ((dst) = (src))
61#endif // _WIN32
62
92a42be0
SL
63#if SANITIZER_FREEBSD
64#define pthread_setname_np pthread_set_name_np
65#define inet_aton __inet_aton
66#define inet_pton __inet_pton
67#define iconv __bsd_iconv
68#endif
69
1a4d82fc
JJ
70#ifndef COMMON_INTERCEPTOR_INITIALIZE_RANGE
71#define COMMON_INTERCEPTOR_INITIALIZE_RANGE(p, size) {}
72#endif
73
74#ifndef COMMON_INTERCEPTOR_UNPOISON_PARAM
75#define COMMON_INTERCEPTOR_UNPOISON_PARAM(count) {}
76#endif
77
78#ifndef COMMON_INTERCEPTOR_FD_ACCESS
79#define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd) {}
80#endif
81
82#ifndef COMMON_INTERCEPTOR_MUTEX_LOCK
83#define COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m) {}
84#endif
85
86#ifndef COMMON_INTERCEPTOR_MUTEX_UNLOCK
87#define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m) {}
88#endif
89
90#ifndef COMMON_INTERCEPTOR_MUTEX_REPAIR
91#define COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m) {}
92#endif
93
94#ifndef COMMON_INTERCEPTOR_HANDLE_RECVMSG
95#define COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg) ((void)(msg))
96#endif
97
98#ifndef COMMON_INTERCEPTOR_FILE_OPEN
99#define COMMON_INTERCEPTOR_FILE_OPEN(ctx, file, path) {}
100#endif
101
102#ifndef COMMON_INTERCEPTOR_FILE_CLOSE
103#define COMMON_INTERCEPTOR_FILE_CLOSE(ctx, file) {}
104#endif
105
92a42be0
SL
106#ifndef COMMON_INTERCEPTOR_LIBRARY_LOADED
107#define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle) {}
108#endif
109
110#ifndef COMMON_INTERCEPTOR_LIBRARY_UNLOADED
111#define COMMON_INTERCEPTOR_LIBRARY_UNLOADED() {}
112#endif
113
114#ifndef COMMON_INTERCEPTOR_ENTER_NOIGNORE
115#define COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, ...) \
116 COMMON_INTERCEPTOR_ENTER(ctx, __VA_ARGS__)
117#endif
118
119#ifndef COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED
120#define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (0)
121#endif
122
123#define COMMON_INTERCEPTOR_READ_STRING_OF_LEN(ctx, s, len, n) \
124 COMMON_INTERCEPTOR_READ_RANGE((ctx), (s), \
125 common_flags()->strict_string_checks ? (len) + 1 : (n) )
126
127#define COMMON_INTERCEPTOR_READ_STRING(ctx, s, n) \
128 COMMON_INTERCEPTOR_READ_STRING_OF_LEN((ctx), (s), REAL(strlen)(s), (n))
129
130#ifndef COMMON_INTERCEPTOR_ON_DLOPEN
131#define COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag) {}
132#endif
133
134#ifndef COMMON_INTERCEPTOR_GET_TLS_RANGE
135#define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end) *begin = *end = 0;
136#endif
137
138#ifndef COMMON_INTERCEPTOR_ACQUIRE
139#define COMMON_INTERCEPTOR_ACQUIRE(ctx, u) {}
140#endif
141
142#ifndef COMMON_INTERCEPTOR_RELEASE
143#define COMMON_INTERCEPTOR_RELEASE(ctx, u) {}
144#endif
145
146struct FileMetadata {
147 // For open_memstream().
148 char **addr;
149 SIZE_T *size;
150};
151
152struct CommonInterceptorMetadata {
153 enum {
154 CIMT_INVALID = 0,
155 CIMT_FILE
156 } type;
157 union {
158 FileMetadata file;
159 };
160};
161
162typedef AddrHashMap<CommonInterceptorMetadata, 31051> MetadataHashMap;
163
164static MetadataHashMap *interceptor_metadata_map;
165
166#if SI_NOT_WINDOWS
167UNUSED static void SetInterceptorMetadata(__sanitizer_FILE *addr,
168 const FileMetadata &file) {
169 MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr);
170 CHECK(h.created());
171 h->type = CommonInterceptorMetadata::CIMT_FILE;
172 h->file = file;
173}
174
175UNUSED static const FileMetadata *GetInterceptorMetadata(
176 __sanitizer_FILE *addr) {
177 MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr,
178 /* remove */ false,
179 /* create */ false);
180 if (h.exists()) {
181 CHECK(!h.created());
182 CHECK(h->type == CommonInterceptorMetadata::CIMT_FILE);
183 return &h->file;
184 } else {
185 return 0;
186 }
187}
188
189UNUSED static void DeleteInterceptorMetadata(void *addr) {
190 MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr, true);
191 CHECK(h.exists());
192}
193#endif // SI_NOT_WINDOWS
194
1a4d82fc
JJ
195#if SANITIZER_INTERCEPT_TEXTDOMAIN
196INTERCEPTOR(char*, textdomain, const char *domainname) {
197 void *ctx;
198 COMMON_INTERCEPTOR_ENTER(ctx, textdomain, domainname);
92a42be0
SL
199 COMMON_INTERCEPTOR_READ_STRING(ctx, domainname, 0);
200 char *domain = REAL(textdomain)(domainname);
1a4d82fc
JJ
201 if (domain) {
202 COMMON_INTERCEPTOR_INITIALIZE_RANGE(domain, REAL(strlen)(domain) + 1);
203 }
204 return domain;
205}
206#define INIT_TEXTDOMAIN COMMON_INTERCEPT_FUNCTION(textdomain)
207#else
208#define INIT_TEXTDOMAIN
209#endif
210
211#if SANITIZER_INTERCEPT_STRCMP
212static inline int CharCmpX(unsigned char c1, unsigned char c2) {
213 return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1;
214}
215
92a42be0
SL
216DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcmp, uptr called_pc,
217 const char *s1, const char *s2)
218
1a4d82fc
JJ
219INTERCEPTOR(int, strcmp, const char *s1, const char *s2) {
220 void *ctx;
221 COMMON_INTERCEPTOR_ENTER(ctx, strcmp, s1, s2);
92a42be0
SL
222 CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcmp, GET_CALLER_PC(), s1,
223 s2);
1a4d82fc
JJ
224 unsigned char c1, c2;
225 uptr i;
226 for (i = 0;; i++) {
227 c1 = (unsigned char)s1[i];
228 c2 = (unsigned char)s2[i];
229 if (c1 != c2 || c1 == '\0') break;
230 }
92a42be0
SL
231 COMMON_INTERCEPTOR_READ_STRING(ctx, s1, i + 1);
232 COMMON_INTERCEPTOR_READ_STRING(ctx, s2, i + 1);
1a4d82fc
JJ
233 return CharCmpX(c1, c2);
234}
235
92a42be0
SL
236DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncmp, uptr called_pc,
237 const char *s1, const char *s2, uptr n)
238
1a4d82fc 239INTERCEPTOR(int, strncmp, const char *s1, const char *s2, uptr size) {
92a42be0
SL
240 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
241 return internal_strncmp(s1, s2, size);
1a4d82fc
JJ
242 void *ctx;
243 COMMON_INTERCEPTOR_ENTER(ctx, strncmp, s1, s2, size);
92a42be0
SL
244 CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncmp, GET_CALLER_PC(), s1,
245 s2, size);
1a4d82fc
JJ
246 unsigned char c1 = 0, c2 = 0;
247 uptr i;
248 for (i = 0; i < size; i++) {
249 c1 = (unsigned char)s1[i];
250 c2 = (unsigned char)s2[i];
251 if (c1 != c2 || c1 == '\0') break;
252 }
253 COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, size));
254 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, size));
255 return CharCmpX(c1, c2);
256}
257
258#define INIT_STRCMP COMMON_INTERCEPT_FUNCTION(strcmp)
259#define INIT_STRNCMP COMMON_INTERCEPT_FUNCTION(strncmp)
260#else
261#define INIT_STRCMP
262#define INIT_STRNCMP
263#endif
264
265#if SANITIZER_INTERCEPT_STRCASECMP
266static inline int CharCaseCmp(unsigned char c1, unsigned char c2) {
267 int c1_low = ToLower(c1);
268 int c2_low = ToLower(c2);
269 return c1_low - c2_low;
270}
271
272INTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) {
273 void *ctx;
274 COMMON_INTERCEPTOR_ENTER(ctx, strcasecmp, s1, s2);
275 unsigned char c1 = 0, c2 = 0;
276 uptr i;
277 for (i = 0;; i++) {
278 c1 = (unsigned char)s1[i];
279 c2 = (unsigned char)s2[i];
280 if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break;
281 }
92a42be0
SL
282 COMMON_INTERCEPTOR_READ_STRING(ctx, s1, i + 1);
283 COMMON_INTERCEPTOR_READ_STRING(ctx, s2, i + 1);
1a4d82fc
JJ
284 return CharCaseCmp(c1, c2);
285}
286
287INTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, SIZE_T n) {
288 void *ctx;
289 COMMON_INTERCEPTOR_ENTER(ctx, strncasecmp, s1, s2, n);
290 unsigned char c1 = 0, c2 = 0;
291 uptr i;
292 for (i = 0; i < n; i++) {
293 c1 = (unsigned char)s1[i];
294 c2 = (unsigned char)s2[i];
295 if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break;
296 }
297 COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, n));
298 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, n));
299 return CharCaseCmp(c1, c2);
300}
301
302#define INIT_STRCASECMP COMMON_INTERCEPT_FUNCTION(strcasecmp)
303#define INIT_STRNCASECMP COMMON_INTERCEPT_FUNCTION(strncasecmp)
304#else
305#define INIT_STRCASECMP
306#define INIT_STRNCASECMP
307#endif
308
92a42be0
SL
309#if SANITIZER_INTERCEPT_STRSTR || SANITIZER_INTERCEPT_STRCASESTR
310static inline void StrstrCheck(void *ctx, char *r, const char *s1,
311 const char *s2) {
312 uptr len1 = REAL(strlen)(s1);
313 uptr len2 = REAL(strlen)(s2);
314 COMMON_INTERCEPTOR_READ_STRING_OF_LEN(ctx, s1, len1,
315 r ? r - s1 + len2 : len1 + 1);
316 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, len2 + 1);
317}
318#endif
319
320#if SANITIZER_INTERCEPT_STRSTR
321INTERCEPTOR(char*, strstr, const char *s1, const char *s2) {
322 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
323 return internal_strstr(s1, s2);
324 void *ctx;
325 COMMON_INTERCEPTOR_ENTER(ctx, strstr, s1, s2);
326 char *r = REAL(strstr)(s1, s2);
327 if (common_flags()->intercept_strstr)
328 StrstrCheck(ctx, r, s1, s2);
329 return r;
330}
331
332#define INIT_STRSTR COMMON_INTERCEPT_FUNCTION(strstr);
333#else
334#define INIT_STRSTR
335#endif
336
337#if SANITIZER_INTERCEPT_STRCASESTR
338INTERCEPTOR(char*, strcasestr, const char *s1, const char *s2) {
339 void *ctx;
340 COMMON_INTERCEPTOR_ENTER(ctx, strcasestr, s1, s2);
341 char *r = REAL(strcasestr)(s1, s2);
342 if (common_flags()->intercept_strstr)
343 StrstrCheck(ctx, r, s1, s2);
344 return r;
345}
346
347#define INIT_STRCASESTR COMMON_INTERCEPT_FUNCTION(strcasestr);
348#else
349#define INIT_STRCASESTR
350#endif
351
352#if SANITIZER_INTERCEPT_STRSPN
353INTERCEPTOR(SIZE_T, strspn, const char *s1, const char *s2) {
354 void *ctx;
355 COMMON_INTERCEPTOR_ENTER(ctx, strspn, s1, s2);
356 SIZE_T r = REAL(strspn)(s1, s2);
357 if (common_flags()->intercept_strspn) {
358 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, REAL(strlen)(s2) + 1);
359 COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r + 1);
360 }
361 return r;
362}
363
364INTERCEPTOR(SIZE_T, strcspn, const char *s1, const char *s2) {
365 void *ctx;
366 COMMON_INTERCEPTOR_ENTER(ctx, strcspn, s1, s2);
367 SIZE_T r = REAL(strcspn)(s1, s2);
368 if (common_flags()->intercept_strspn) {
369 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, REAL(strlen)(s2) + 1);
370 COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r + 1);
371 }
372 return r;
373}
374
375#define INIT_STRSPN \
376 COMMON_INTERCEPT_FUNCTION(strspn); \
377 COMMON_INTERCEPT_FUNCTION(strcspn);
378#else
379#define INIT_STRSPN
380#endif
381
382#if SANITIZER_INTERCEPT_STRPBRK
383INTERCEPTOR(char *, strpbrk, const char *s1, const char *s2) {
384 void *ctx;
385 COMMON_INTERCEPTOR_ENTER(ctx, strpbrk, s1, s2);
386 char *r = REAL(strpbrk)(s1, s2);
387 if (common_flags()->intercept_strpbrk) {
388 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, REAL(strlen)(s2) + 1);
389 COMMON_INTERCEPTOR_READ_STRING(ctx, s1,
390 r ? r - s1 + 1 : REAL(strlen)(s1) + 1);
391 }
392 return r;
393}
394
395#define INIT_STRPBRK COMMON_INTERCEPT_FUNCTION(strpbrk);
396#else
397#define INIT_STRPBRK
398#endif
399
400#if SANITIZER_INTERCEPT_MEMCMP
401
402DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, uptr called_pc,
403 const void *s1, const void *s2, uptr n)
404
405INTERCEPTOR(int, memcmp, const void *a1, const void *a2, uptr size) {
406 void *ctx;
407 COMMON_INTERCEPTOR_ENTER(ctx, memcmp, a1, a2, size);
408 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
409 return internal_memcmp(a1, a2, size);
410 CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, GET_CALLER_PC(), a1,
411 a2, size);
412 if (common_flags()->intercept_memcmp) {
413 if (common_flags()->strict_memcmp) {
414 // Check the entire regions even if the first bytes of the buffers are
415 // different.
416 COMMON_INTERCEPTOR_READ_RANGE(ctx, a1, size);
417 COMMON_INTERCEPTOR_READ_RANGE(ctx, a2, size);
418 // Fallthrough to REAL(memcmp) below.
419 } else {
420 unsigned char c1 = 0, c2 = 0;
421 const unsigned char *s1 = (const unsigned char*)a1;
422 const unsigned char *s2 = (const unsigned char*)a2;
423 uptr i;
424 for (i = 0; i < size; i++) {
425 c1 = s1[i];
426 c2 = s2[i];
427 if (c1 != c2) break;
428 }
429 COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, size));
430 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, size));
431 return CharCmpX(c1, c2);
432 }
433 }
434 return REAL(memcmp(a1, a2, size));
435}
436
437#define INIT_MEMCMP COMMON_INTERCEPT_FUNCTION(memcmp)
438#else
439#define INIT_MEMCMP
440#endif
441
1a4d82fc
JJ
442#if SANITIZER_INTERCEPT_MEMCHR
443INTERCEPTOR(void*, memchr, const void *s, int c, SIZE_T n) {
92a42be0
SL
444 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
445 return internal_memchr(s, c, n);
1a4d82fc
JJ
446 void *ctx;
447 COMMON_INTERCEPTOR_ENTER(ctx, memchr, s, c, n);
448 void *res = REAL(memchr)(s, c, n);
92a42be0 449 uptr len = res ? (char *)res - (const char *)s + 1 : n;
1a4d82fc
JJ
450 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, len);
451 return res;
452}
453
454#define INIT_MEMCHR COMMON_INTERCEPT_FUNCTION(memchr)
455#else
456#define INIT_MEMCHR
457#endif
458
459#if SANITIZER_INTERCEPT_MEMRCHR
460INTERCEPTOR(void*, memrchr, const void *s, int c, SIZE_T n) {
461 void *ctx;
462 COMMON_INTERCEPTOR_ENTER(ctx, memrchr, s, c, n);
463 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, n);
464 return REAL(memrchr)(s, c, n);
465}
466
467#define INIT_MEMRCHR COMMON_INTERCEPT_FUNCTION(memrchr)
468#else
469#define INIT_MEMRCHR
470#endif
471
472#if SANITIZER_INTERCEPT_FREXP
473INTERCEPTOR(double, frexp, double x, int *exp) {
474 void *ctx;
475 COMMON_INTERCEPTOR_ENTER(ctx, frexp, x, exp);
92a42be0 476 // Assuming frexp() always writes to |exp|.
1a4d82fc 477 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
92a42be0 478 double res = REAL(frexp)(x, exp);
1a4d82fc
JJ
479 return res;
480}
481
482#define INIT_FREXP COMMON_INTERCEPT_FUNCTION(frexp);
483#else
484#define INIT_FREXP
485#endif // SANITIZER_INTERCEPT_FREXP
486
487#if SANITIZER_INTERCEPT_FREXPF_FREXPL
488INTERCEPTOR(float, frexpf, float x, int *exp) {
489 void *ctx;
490 COMMON_INTERCEPTOR_ENTER(ctx, frexpf, x, exp);
92a42be0
SL
491 // FIXME: under ASan the call below may write to freed memory and corrupt
492 // its metadata. See
493 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
494 float res = REAL(frexpf)(x, exp);
495 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
496 return res;
497}
498
499INTERCEPTOR(long double, frexpl, long double x, int *exp) {
500 void *ctx;
501 COMMON_INTERCEPTOR_ENTER(ctx, frexpl, x, exp);
92a42be0
SL
502 // FIXME: under ASan the call below may write to freed memory and corrupt
503 // its metadata. See
504 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
505 long double res = REAL(frexpl)(x, exp);
506 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
507 return res;
508}
509
510#define INIT_FREXPF_FREXPL \
511 COMMON_INTERCEPT_FUNCTION(frexpf); \
512 COMMON_INTERCEPT_FUNCTION(frexpl)
513#else
514#define INIT_FREXPF_FREXPL
515#endif // SANITIZER_INTERCEPT_FREXPF_FREXPL
516
517#if SI_NOT_WINDOWS
518static void write_iovec(void *ctx, struct __sanitizer_iovec *iovec,
519 SIZE_T iovlen, SIZE_T maxlen) {
520 for (SIZE_T i = 0; i < iovlen && maxlen; ++i) {
521 SSIZE_T sz = Min(iovec[i].iov_len, maxlen);
522 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec[i].iov_base, sz);
523 maxlen -= sz;
524 }
525}
526
527static void read_iovec(void *ctx, struct __sanitizer_iovec *iovec,
528 SIZE_T iovlen, SIZE_T maxlen) {
529 COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec) * iovlen);
530 for (SIZE_T i = 0; i < iovlen && maxlen; ++i) {
531 SSIZE_T sz = Min(iovec[i].iov_len, maxlen);
532 COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec[i].iov_base, sz);
533 maxlen -= sz;
534 }
535}
536#endif
537
538#if SANITIZER_INTERCEPT_READ
539INTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) {
540 void *ctx;
541 COMMON_INTERCEPTOR_ENTER(ctx, read, fd, ptr, count);
542 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
92a42be0
SL
543 // FIXME: under ASan the call below may write to freed memory and corrupt
544 // its metadata. See
545 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
546 SSIZE_T res = REAL(read)(fd, ptr, count);
547 if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
548 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
549 return res;
550}
551#define INIT_READ COMMON_INTERCEPT_FUNCTION(read)
552#else
553#define INIT_READ
554#endif
555
556#if SANITIZER_INTERCEPT_PREAD
557INTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) {
558 void *ctx;
559 COMMON_INTERCEPTOR_ENTER(ctx, pread, fd, ptr, count, offset);
560 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
92a42be0
SL
561 // FIXME: under ASan the call below may write to freed memory and corrupt
562 // its metadata. See
563 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
564 SSIZE_T res = REAL(pread)(fd, ptr, count, offset);
565 if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
566 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
567 return res;
568}
569#define INIT_PREAD COMMON_INTERCEPT_FUNCTION(pread)
570#else
571#define INIT_PREAD
572#endif
573
574#if SANITIZER_INTERCEPT_PREAD64
575INTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) {
576 void *ctx;
577 COMMON_INTERCEPTOR_ENTER(ctx, pread64, fd, ptr, count, offset);
578 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
92a42be0
SL
579 // FIXME: under ASan the call below may write to freed memory and corrupt
580 // its metadata. See
581 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
582 SSIZE_T res = REAL(pread64)(fd, ptr, count, offset);
583 if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
584 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
585 return res;
586}
587#define INIT_PREAD64 COMMON_INTERCEPT_FUNCTION(pread64)
588#else
589#define INIT_PREAD64
590#endif
591
592#if SANITIZER_INTERCEPT_READV
593INTERCEPTOR_WITH_SUFFIX(SSIZE_T, readv, int fd, __sanitizer_iovec *iov,
594 int iovcnt) {
595 void *ctx;
596 COMMON_INTERCEPTOR_ENTER(ctx, readv, fd, iov, iovcnt);
597 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
598 SSIZE_T res = REAL(readv)(fd, iov, iovcnt);
599 if (res > 0) write_iovec(ctx, iov, iovcnt, res);
600 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
601 return res;
602}
603#define INIT_READV COMMON_INTERCEPT_FUNCTION(readv)
604#else
605#define INIT_READV
606#endif
607
608#if SANITIZER_INTERCEPT_PREADV
609INTERCEPTOR(SSIZE_T, preadv, int fd, __sanitizer_iovec *iov, int iovcnt,
610 OFF_T offset) {
611 void *ctx;
612 COMMON_INTERCEPTOR_ENTER(ctx, preadv, fd, iov, iovcnt, offset);
613 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
614 SSIZE_T res = REAL(preadv)(fd, iov, iovcnt, offset);
615 if (res > 0) write_iovec(ctx, iov, iovcnt, res);
616 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
617 return res;
618}
619#define INIT_PREADV COMMON_INTERCEPT_FUNCTION(preadv)
620#else
621#define INIT_PREADV
622#endif
623
624#if SANITIZER_INTERCEPT_PREADV64
625INTERCEPTOR(SSIZE_T, preadv64, int fd, __sanitizer_iovec *iov, int iovcnt,
626 OFF64_T offset) {
627 void *ctx;
628 COMMON_INTERCEPTOR_ENTER(ctx, preadv64, fd, iov, iovcnt, offset);
629 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
630 SSIZE_T res = REAL(preadv64)(fd, iov, iovcnt, offset);
631 if (res > 0) write_iovec(ctx, iov, iovcnt, res);
632 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
633 return res;
634}
635#define INIT_PREADV64 COMMON_INTERCEPT_FUNCTION(preadv64)
636#else
637#define INIT_PREADV64
638#endif
639
640#if SANITIZER_INTERCEPT_WRITE
641INTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) {
642 void *ctx;
643 COMMON_INTERCEPTOR_ENTER(ctx, write, fd, ptr, count);
644 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
645 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
646 SSIZE_T res = REAL(write)(fd, ptr, count);
647 // FIXME: this check should be _before_ the call to REAL(write), not after
648 if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
649 return res;
650}
651#define INIT_WRITE COMMON_INTERCEPT_FUNCTION(write)
652#else
653#define INIT_WRITE
654#endif
655
656#if SANITIZER_INTERCEPT_PWRITE
657INTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) {
658 void *ctx;
659 COMMON_INTERCEPTOR_ENTER(ctx, pwrite, fd, ptr, count, offset);
660 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
661 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
662 SSIZE_T res = REAL(pwrite)(fd, ptr, count, offset);
663 if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
664 return res;
665}
666#define INIT_PWRITE COMMON_INTERCEPT_FUNCTION(pwrite)
667#else
668#define INIT_PWRITE
669#endif
670
671#if SANITIZER_INTERCEPT_PWRITE64
672INTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count,
673 OFF64_T offset) {
674 void *ctx;
675 COMMON_INTERCEPTOR_ENTER(ctx, pwrite64, fd, ptr, count, offset);
676 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
677 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
678 SSIZE_T res = REAL(pwrite64)(fd, ptr, count, offset);
679 if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
680 return res;
681}
682#define INIT_PWRITE64 COMMON_INTERCEPT_FUNCTION(pwrite64)
683#else
684#define INIT_PWRITE64
685#endif
686
687#if SANITIZER_INTERCEPT_WRITEV
688INTERCEPTOR_WITH_SUFFIX(SSIZE_T, writev, int fd, __sanitizer_iovec *iov,
689 int iovcnt) {
690 void *ctx;
691 COMMON_INTERCEPTOR_ENTER(ctx, writev, fd, iov, iovcnt);
692 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
693 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
694 SSIZE_T res = REAL(writev)(fd, iov, iovcnt);
695 if (res > 0) read_iovec(ctx, iov, iovcnt, res);
696 return res;
697}
698#define INIT_WRITEV COMMON_INTERCEPT_FUNCTION(writev)
699#else
700#define INIT_WRITEV
701#endif
702
703#if SANITIZER_INTERCEPT_PWRITEV
704INTERCEPTOR(SSIZE_T, pwritev, int fd, __sanitizer_iovec *iov, int iovcnt,
705 OFF_T offset) {
706 void *ctx;
707 COMMON_INTERCEPTOR_ENTER(ctx, pwritev, fd, iov, iovcnt, offset);
708 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
709 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
710 SSIZE_T res = REAL(pwritev)(fd, iov, iovcnt, offset);
711 if (res > 0) read_iovec(ctx, iov, iovcnt, res);
712 return res;
713}
714#define INIT_PWRITEV COMMON_INTERCEPT_FUNCTION(pwritev)
715#else
716#define INIT_PWRITEV
717#endif
718
719#if SANITIZER_INTERCEPT_PWRITEV64
720INTERCEPTOR(SSIZE_T, pwritev64, int fd, __sanitizer_iovec *iov, int iovcnt,
721 OFF64_T offset) {
722 void *ctx;
723 COMMON_INTERCEPTOR_ENTER(ctx, pwritev64, fd, iov, iovcnt, offset);
724 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
725 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
726 SSIZE_T res = REAL(pwritev64)(fd, iov, iovcnt, offset);
727 if (res > 0) read_iovec(ctx, iov, iovcnt, res);
728 return res;
729}
730#define INIT_PWRITEV64 COMMON_INTERCEPT_FUNCTION(pwritev64)
731#else
732#define INIT_PWRITEV64
733#endif
734
735#if SANITIZER_INTERCEPT_PRCTL
736INTERCEPTOR(int, prctl, int option, unsigned long arg2,
737 unsigned long arg3, // NOLINT
738 unsigned long arg4, unsigned long arg5) { // NOLINT
739 void *ctx;
740 COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5);
741 static const int PR_SET_NAME = 15;
742 int res = REAL(prctl(option, arg2, arg3, arg4, arg5));
743 if (option == PR_SET_NAME) {
744 char buff[16];
745 internal_strncpy(buff, (char *)arg2, 15);
746 buff[15] = 0;
747 COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff);
748 }
749 return res;
750}
751#define INIT_PRCTL COMMON_INTERCEPT_FUNCTION(prctl)
752#else
753#define INIT_PRCTL
754#endif // SANITIZER_INTERCEPT_PRCTL
755
756#if SANITIZER_INTERCEPT_TIME
757INTERCEPTOR(unsigned long, time, unsigned long *t) {
758 void *ctx;
759 COMMON_INTERCEPTOR_ENTER(ctx, time, t);
92a42be0
SL
760 unsigned long local_t;
761 unsigned long res = REAL(time)(&local_t);
1a4d82fc
JJ
762 if (t && res != (unsigned long)-1) {
763 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, t, sizeof(*t));
92a42be0 764 *t = local_t;
1a4d82fc
JJ
765 }
766 return res;
767}
768#define INIT_TIME COMMON_INTERCEPT_FUNCTION(time);
769#else
770#define INIT_TIME
771#endif // SANITIZER_INTERCEPT_TIME
772
773#if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
774static void unpoison_tm(void *ctx, __sanitizer_tm *tm) {
775 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm));
776 if (tm->tm_zone) {
777 // Can not use COMMON_INTERCEPTOR_WRITE_RANGE here, because tm->tm_zone
778 // can point to shared memory and tsan would report a data race.
779 COMMON_INTERCEPTOR_INITIALIZE_RANGE(tm->tm_zone,
780 REAL(strlen(tm->tm_zone)) + 1);
781 }
782}
783INTERCEPTOR(__sanitizer_tm *, localtime, unsigned long *timep) {
784 void *ctx;
785 COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep);
786 __sanitizer_tm *res = REAL(localtime)(timep);
787 if (res) {
788 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
789 unpoison_tm(ctx, res);
790 }
791 return res;
792}
793INTERCEPTOR(__sanitizer_tm *, localtime_r, unsigned long *timep, void *result) {
794 void *ctx;
795 COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result);
796 __sanitizer_tm *res = REAL(localtime_r)(timep, result);
797 if (res) {
798 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
799 unpoison_tm(ctx, res);
800 }
801 return res;
802}
803INTERCEPTOR(__sanitizer_tm *, gmtime, unsigned long *timep) {
804 void *ctx;
805 COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep);
806 __sanitizer_tm *res = REAL(gmtime)(timep);
807 if (res) {
808 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
809 unpoison_tm(ctx, res);
810 }
811 return res;
812}
813INTERCEPTOR(__sanitizer_tm *, gmtime_r, unsigned long *timep, void *result) {
814 void *ctx;
815 COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result);
816 __sanitizer_tm *res = REAL(gmtime_r)(timep, result);
817 if (res) {
818 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
819 unpoison_tm(ctx, res);
820 }
821 return res;
822}
823INTERCEPTOR(char *, ctime, unsigned long *timep) {
824 void *ctx;
825 COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep);
92a42be0
SL
826 // FIXME: under ASan the call below may write to freed memory and corrupt
827 // its metadata. See
828 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
829 char *res = REAL(ctime)(timep);
830 if (res) {
831 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
832 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
833 }
834 return res;
835}
836INTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) {
837 void *ctx;
838 COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result);
92a42be0
SL
839 // FIXME: under ASan the call below may write to freed memory and corrupt
840 // its metadata. See
841 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
842 char *res = REAL(ctime_r)(timep, result);
843 if (res) {
844 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
845 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
846 }
847 return res;
848}
849INTERCEPTOR(char *, asctime, __sanitizer_tm *tm) {
850 void *ctx;
851 COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm);
92a42be0
SL
852 // FIXME: under ASan the call below may write to freed memory and corrupt
853 // its metadata. See
854 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
855 char *res = REAL(asctime)(tm);
856 if (res) {
857 COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm));
858 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
859 }
860 return res;
861}
862INTERCEPTOR(char *, asctime_r, __sanitizer_tm *tm, char *result) {
863 void *ctx;
864 COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result);
92a42be0
SL
865 // FIXME: under ASan the call below may write to freed memory and corrupt
866 // its metadata. See
867 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
868 char *res = REAL(asctime_r)(tm, result);
869 if (res) {
870 COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm));
871 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
872 }
873 return res;
874}
875INTERCEPTOR(long, mktime, __sanitizer_tm *tm) {
876 void *ctx;
877 COMMON_INTERCEPTOR_ENTER(ctx, mktime, tm);
878 COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_sec, sizeof(tm->tm_sec));
879 COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_min, sizeof(tm->tm_min));
880 COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_hour, sizeof(tm->tm_hour));
881 COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_mday, sizeof(tm->tm_mday));
882 COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_mon, sizeof(tm->tm_mon));
883 COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_year, sizeof(tm->tm_year));
884 COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_isdst, sizeof(tm->tm_isdst));
885 long res = REAL(mktime)(tm);
886 if (res != -1) unpoison_tm(ctx, tm);
887 return res;
888}
889#define INIT_LOCALTIME_AND_FRIENDS \
890 COMMON_INTERCEPT_FUNCTION(localtime); \
891 COMMON_INTERCEPT_FUNCTION(localtime_r); \
892 COMMON_INTERCEPT_FUNCTION(gmtime); \
893 COMMON_INTERCEPT_FUNCTION(gmtime_r); \
894 COMMON_INTERCEPT_FUNCTION(ctime); \
895 COMMON_INTERCEPT_FUNCTION(ctime_r); \
896 COMMON_INTERCEPT_FUNCTION(asctime); \
897 COMMON_INTERCEPT_FUNCTION(asctime_r); \
898 COMMON_INTERCEPT_FUNCTION(mktime);
899#else
900#define INIT_LOCALTIME_AND_FRIENDS
901#endif // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
902
903#if SANITIZER_INTERCEPT_STRPTIME
904INTERCEPTOR(char *, strptime, char *s, char *format, __sanitizer_tm *tm) {
905 void *ctx;
906 COMMON_INTERCEPTOR_ENTER(ctx, strptime, s, format, tm);
907 if (format)
908 COMMON_INTERCEPTOR_READ_RANGE(ctx, format, REAL(strlen)(format) + 1);
92a42be0
SL
909 // FIXME: under ASan the call below may write to freed memory and corrupt
910 // its metadata. See
911 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc 912 char *res = REAL(strptime)(s, format, tm);
92a42be0
SL
913 COMMON_INTERCEPTOR_READ_STRING(ctx, s, res ? res - s : 0);
914 if (res && tm) {
1a4d82fc
JJ
915 // Do not call unpoison_tm here, because strptime does not, in fact,
916 // initialize the entire struct tm. For example, tm_zone pointer is left
917 // uninitialized.
92a42be0 918 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm));
1a4d82fc
JJ
919 }
920 return res;
921}
922#define INIT_STRPTIME COMMON_INTERCEPT_FUNCTION(strptime);
923#else
924#define INIT_STRPTIME
925#endif
926
927#if SANITIZER_INTERCEPT_SCANF || SANITIZER_INTERCEPT_PRINTF
928#include "sanitizer_common_interceptors_format.inc"
929
930#define FORMAT_INTERCEPTOR_IMPL(name, vname, ...) \
931 { \
932 void *ctx; \
933 va_list ap; \
934 va_start(ap, format); \
935 COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__, ap); \
936 int res = WRAP(vname)(__VA_ARGS__, ap); \
937 va_end(ap); \
938 return res; \
939 }
940
941#endif
942
943#if SANITIZER_INTERCEPT_SCANF
944
945#define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...) \
946 { \
947 void *ctx; \
948 COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__); \
949 va_list aq; \
950 va_copy(aq, ap); \
951 int res = REAL(vname)(__VA_ARGS__); \
952 if (res > 0) \
953 scanf_common(ctx, res, allowGnuMalloc, format, aq); \
954 va_end(aq); \
955 return res; \
956 }
957
958INTERCEPTOR(int, vscanf, const char *format, va_list ap)
959VSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap)
960
961INTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap)
962VSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap)
963
964INTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap)
965VSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap)
966
967#if SANITIZER_INTERCEPT_ISOC99_SCANF
968INTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap)
969VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap)
970
971INTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format,
972 va_list ap)
973VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap)
974
975INTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap)
976VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap)
977#endif // SANITIZER_INTERCEPT_ISOC99_SCANF
978
979INTERCEPTOR(int, scanf, const char *format, ...)
980FORMAT_INTERCEPTOR_IMPL(scanf, vscanf, format)
981
982INTERCEPTOR(int, fscanf, void *stream, const char *format, ...)
983FORMAT_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format)
984
985INTERCEPTOR(int, sscanf, const char *str, const char *format, ...)
986FORMAT_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format)
987
988#if SANITIZER_INTERCEPT_ISOC99_SCANF
989INTERCEPTOR(int, __isoc99_scanf, const char *format, ...)
990FORMAT_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format)
991
992INTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...)
993FORMAT_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format)
994
995INTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...)
996FORMAT_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format)
997#endif
998
999#endif
1000
1001#if SANITIZER_INTERCEPT_SCANF
1002#define INIT_SCANF \
1003 COMMON_INTERCEPT_FUNCTION(scanf); \
1004 COMMON_INTERCEPT_FUNCTION(sscanf); \
1005 COMMON_INTERCEPT_FUNCTION(fscanf); \
1006 COMMON_INTERCEPT_FUNCTION(vscanf); \
1007 COMMON_INTERCEPT_FUNCTION(vsscanf); \
1008 COMMON_INTERCEPT_FUNCTION(vfscanf);
1009#else
1010#define INIT_SCANF
1011#endif
1012
1013#if SANITIZER_INTERCEPT_ISOC99_SCANF
1014#define INIT_ISOC99_SCANF \
1015 COMMON_INTERCEPT_FUNCTION(__isoc99_scanf); \
1016 COMMON_INTERCEPT_FUNCTION(__isoc99_sscanf); \
1017 COMMON_INTERCEPT_FUNCTION(__isoc99_fscanf); \
1018 COMMON_INTERCEPT_FUNCTION(__isoc99_vscanf); \
1019 COMMON_INTERCEPT_FUNCTION(__isoc99_vsscanf); \
1020 COMMON_INTERCEPT_FUNCTION(__isoc99_vfscanf);
1021#else
1022#define INIT_ISOC99_SCANF
1023#endif
1024
1025#if SANITIZER_INTERCEPT_PRINTF
1026
1027#define VPRINTF_INTERCEPTOR_ENTER(vname, ...) \
1028 void *ctx; \
1029 COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__); \
1030 va_list aq; \
1031 va_copy(aq, ap);
1032
1033#define VPRINTF_INTERCEPTOR_RETURN() \
1034 va_end(aq);
1035
1036#define VPRINTF_INTERCEPTOR_IMPL(vname, ...) \
1037 { \
1038 VPRINTF_INTERCEPTOR_ENTER(vname, __VA_ARGS__); \
1039 if (common_flags()->check_printf) \
1040 printf_common(ctx, format, aq); \
1041 int res = REAL(vname)(__VA_ARGS__); \
1042 VPRINTF_INTERCEPTOR_RETURN(); \
1043 return res; \
1044 }
1045
92a42be0
SL
1046// FIXME: under ASan the REAL() call below may write to freed memory and
1047// corrupt its metadata. See
1048// https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
1049#define VSPRINTF_INTERCEPTOR_IMPL(vname, str, ...) \
1050 { \
1051 VPRINTF_INTERCEPTOR_ENTER(vname, str, __VA_ARGS__) \
1052 if (common_flags()->check_printf) { \
1053 printf_common(ctx, format, aq); \
1054 } \
1055 int res = REAL(vname)(str, __VA_ARGS__); \
92a42be0 1056 if (res >= 0) { \
1a4d82fc
JJ
1057 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, res + 1); \
1058 } \
1059 VPRINTF_INTERCEPTOR_RETURN(); \
1060 return res; \
1061 }
1062
92a42be0
SL
1063// FIXME: under ASan the REAL() call below may write to freed memory and
1064// corrupt its metadata. See
1065// https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
1066#define VSNPRINTF_INTERCEPTOR_IMPL(vname, str, size, ...) \
1067 { \
1068 VPRINTF_INTERCEPTOR_ENTER(vname, str, size, __VA_ARGS__) \
1069 if (common_flags()->check_printf) { \
1070 printf_common(ctx, format, aq); \
1071 } \
1072 int res = REAL(vname)(str, size, __VA_ARGS__); \
92a42be0 1073 if (res >= 0) { \
1a4d82fc
JJ
1074 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, Min(size, (SIZE_T)(res + 1))); \
1075 } \
1076 VPRINTF_INTERCEPTOR_RETURN(); \
1077 return res; \
1078 }
1079
92a42be0
SL
1080// FIXME: under ASan the REAL() call below may write to freed memory and
1081// corrupt its metadata. See
1082// https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
1083#define VASPRINTF_INTERCEPTOR_IMPL(vname, strp, ...) \
1084 { \
1085 VPRINTF_INTERCEPTOR_ENTER(vname, strp, __VA_ARGS__) \
92a42be0 1086 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, strp, sizeof(char *)); \
1a4d82fc 1087 if (common_flags()->check_printf) { \
1a4d82fc
JJ
1088 printf_common(ctx, format, aq); \
1089 } \
1090 int res = REAL(vname)(strp, __VA_ARGS__); \
92a42be0 1091 if (res >= 0) { \
1a4d82fc
JJ
1092 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *strp, res + 1); \
1093 } \
1094 VPRINTF_INTERCEPTOR_RETURN(); \
1095 return res; \
1096 }
1097
1098INTERCEPTOR(int, vprintf, const char *format, va_list ap)
1099VPRINTF_INTERCEPTOR_IMPL(vprintf, format, ap)
1100
92a42be0
SL
1101INTERCEPTOR(int, vfprintf, __sanitizer_FILE *stream, const char *format,
1102 va_list ap)
1a4d82fc
JJ
1103VPRINTF_INTERCEPTOR_IMPL(vfprintf, stream, format, ap)
1104
1105INTERCEPTOR(int, vsnprintf, char *str, SIZE_T size, const char *format,
1106 va_list ap)
1107VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf, str, size, format, ap)
1108
92a42be0
SL
1109#if SANITIZER_INTERCEPT_PRINTF_L
1110INTERCEPTOR(int, vsnprintf_l, char *str, SIZE_T size, void *loc,
1111 const char *format, va_list ap)
1112VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf_l, str, size, loc, format, ap)
1113
1114INTERCEPTOR(int, snprintf_l, char *str, SIZE_T size, void *loc,
1115 const char *format, ...)
1116FORMAT_INTERCEPTOR_IMPL(snprintf_l, vsnprintf_l, str, size, loc, format)
1117#endif // SANITIZER_INTERCEPT_PRINTF_L
1118
1a4d82fc
JJ
1119INTERCEPTOR(int, vsprintf, char *str, const char *format, va_list ap)
1120VSPRINTF_INTERCEPTOR_IMPL(vsprintf, str, format, ap)
1121
1122INTERCEPTOR(int, vasprintf, char **strp, const char *format, va_list ap)
1123VASPRINTF_INTERCEPTOR_IMPL(vasprintf, strp, format, ap)
1124
1125#if SANITIZER_INTERCEPT_ISOC99_PRINTF
1126INTERCEPTOR(int, __isoc99_vprintf, const char *format, va_list ap)
1127VPRINTF_INTERCEPTOR_IMPL(__isoc99_vprintf, format, ap)
1128
92a42be0
SL
1129INTERCEPTOR(int, __isoc99_vfprintf, __sanitizer_FILE *stream,
1130 const char *format, va_list ap)
1a4d82fc
JJ
1131VPRINTF_INTERCEPTOR_IMPL(__isoc99_vfprintf, stream, format, ap)
1132
1133INTERCEPTOR(int, __isoc99_vsnprintf, char *str, SIZE_T size, const char *format,
1134 va_list ap)
1135VSNPRINTF_INTERCEPTOR_IMPL(__isoc99_vsnprintf, str, size, format, ap)
1136
1137INTERCEPTOR(int, __isoc99_vsprintf, char *str, const char *format,
1138 va_list ap)
1139VSPRINTF_INTERCEPTOR_IMPL(__isoc99_vsprintf, str, format,
1140 ap)
1141
1142#endif // SANITIZER_INTERCEPT_ISOC99_PRINTF
1143
1144INTERCEPTOR(int, printf, const char *format, ...)
1145FORMAT_INTERCEPTOR_IMPL(printf, vprintf, format)
1146
92a42be0 1147INTERCEPTOR(int, fprintf, __sanitizer_FILE *stream, const char *format, ...)
1a4d82fc
JJ
1148FORMAT_INTERCEPTOR_IMPL(fprintf, vfprintf, stream, format)
1149
1150INTERCEPTOR(int, sprintf, char *str, const char *format, ...) // NOLINT
1151FORMAT_INTERCEPTOR_IMPL(sprintf, vsprintf, str, format) // NOLINT
1152
1153INTERCEPTOR(int, snprintf, char *str, SIZE_T size, const char *format, ...)
1154FORMAT_INTERCEPTOR_IMPL(snprintf, vsnprintf, str, size, format)
1155
1156INTERCEPTOR(int, asprintf, char **strp, const char *format, ...)
1157FORMAT_INTERCEPTOR_IMPL(asprintf, vasprintf, strp, format)
1158
1159#if SANITIZER_INTERCEPT_ISOC99_PRINTF
1160INTERCEPTOR(int, __isoc99_printf, const char *format, ...)
1161FORMAT_INTERCEPTOR_IMPL(__isoc99_printf, __isoc99_vprintf, format)
1162
92a42be0
SL
1163INTERCEPTOR(int, __isoc99_fprintf, __sanitizer_FILE *stream, const char *format,
1164 ...)
1a4d82fc
JJ
1165FORMAT_INTERCEPTOR_IMPL(__isoc99_fprintf, __isoc99_vfprintf, stream, format)
1166
1167INTERCEPTOR(int, __isoc99_sprintf, char *str, const char *format, ...)
1168FORMAT_INTERCEPTOR_IMPL(__isoc99_sprintf, __isoc99_vsprintf, str, format)
1169
1170INTERCEPTOR(int, __isoc99_snprintf, char *str, SIZE_T size,
1171 const char *format, ...)
1172FORMAT_INTERCEPTOR_IMPL(__isoc99_snprintf, __isoc99_vsnprintf, str, size,
1173 format)
1174
1175#endif // SANITIZER_INTERCEPT_ISOC99_PRINTF
1176
1177#endif // SANITIZER_INTERCEPT_PRINTF
1178
1179#if SANITIZER_INTERCEPT_PRINTF
1180#define INIT_PRINTF \
1181 COMMON_INTERCEPT_FUNCTION(printf); \
1182 COMMON_INTERCEPT_FUNCTION(sprintf); \
1183 COMMON_INTERCEPT_FUNCTION(snprintf); \
1184 COMMON_INTERCEPT_FUNCTION(asprintf); \
1185 COMMON_INTERCEPT_FUNCTION(fprintf); \
1186 COMMON_INTERCEPT_FUNCTION(vprintf); \
1187 COMMON_INTERCEPT_FUNCTION(vsprintf); \
1188 COMMON_INTERCEPT_FUNCTION(vsnprintf); \
1189 COMMON_INTERCEPT_FUNCTION(vasprintf); \
1190 COMMON_INTERCEPT_FUNCTION(vfprintf);
1191#else
1192#define INIT_PRINTF
1193#endif
1194
92a42be0
SL
1195#if SANITIZER_INTERCEPT_PRINTF_L
1196#define INIT_PRINTF_L \
1197 COMMON_INTERCEPT_FUNCTION(snprintf_l); \
1198 COMMON_INTERCEPT_FUNCTION(vsnprintf_l);
1199#else
1200#define INIT_PRINTF_L
1201#endif
1202
1a4d82fc
JJ
1203#if SANITIZER_INTERCEPT_ISOC99_PRINTF
1204#define INIT_ISOC99_PRINTF \
1205 COMMON_INTERCEPT_FUNCTION(__isoc99_printf); \
1206 COMMON_INTERCEPT_FUNCTION(__isoc99_sprintf); \
1207 COMMON_INTERCEPT_FUNCTION(__isoc99_snprintf); \
1208 COMMON_INTERCEPT_FUNCTION(__isoc99_fprintf); \
1209 COMMON_INTERCEPT_FUNCTION(__isoc99_vprintf); \
1210 COMMON_INTERCEPT_FUNCTION(__isoc99_vsprintf); \
1211 COMMON_INTERCEPT_FUNCTION(__isoc99_vsnprintf); \
1212 COMMON_INTERCEPT_FUNCTION(__isoc99_vfprintf);
1213#else
1214#define INIT_ISOC99_PRINTF
1215#endif
1216
1217#if SANITIZER_INTERCEPT_IOCTL
1218#include "sanitizer_common_interceptors_ioctl.inc"
92a42be0
SL
1219INTERCEPTOR(int, ioctl, int d, unsigned long request, ...) {
1220 // We need a frame pointer, because we call into ioctl_common_[pre|post] which
1221 // can trigger a report and we need to be able to unwind through this
1222 // function. On Mac in debug mode we might not have a frame pointer, because
1223 // ioctl_common_[pre|post] doesn't get inlined here.
1224 ENABLE_FRAME_POINTER;
1225
1226 void *ctx;
1227 va_list ap;
1228 va_start(ap, request);
1229 void *arg = va_arg(ap, void *);
1230 va_end(ap);
1a4d82fc
JJ
1231 COMMON_INTERCEPTOR_ENTER(ctx, ioctl, d, request, arg);
1232
1233 CHECK(ioctl_initialized);
1234
1235 // Note: TSan does not use common flags, and they are zero-initialized.
1236 // This effectively disables ioctl handling in TSan.
1237 if (!common_flags()->handle_ioctl) return REAL(ioctl)(d, request, arg);
1238
92a42be0
SL
1239 // Although request is unsigned long, the rest of the interceptor uses it
1240 // as just "unsigned" to save space, because we know that all values fit in
1241 // "unsigned" - they are compile-time constants.
1242
1a4d82fc
JJ
1243 const ioctl_desc *desc = ioctl_lookup(request);
1244 ioctl_desc decoded_desc;
1245 if (!desc) {
1246 VPrintf(2, "Decoding unknown ioctl 0x%x\n", request);
1247 if (!ioctl_decode(request, &decoded_desc))
1248 Printf("WARNING: failed decoding unknown ioctl 0x%x\n", request);
1249 else
1250 desc = &decoded_desc;
1251 }
1252
1253 if (desc) ioctl_common_pre(ctx, desc, d, request, arg);
1254 int res = REAL(ioctl)(d, request, arg);
1255 // FIXME: some ioctls have different return values for success and failure.
1256 if (desc && res != -1) ioctl_common_post(ctx, desc, res, d, request, arg);
1257 return res;
1258}
1259#define INIT_IOCTL \
1260 ioctl_init(); \
1261 COMMON_INTERCEPT_FUNCTION(ioctl);
1262#else
1263#define INIT_IOCTL
1264#endif
1265
1266#if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS || \
92a42be0
SL
1267 SANITIZER_INTERCEPT_GETPWENT || SANITIZER_INTERCEPT_FGETPWENT || \
1268 SANITIZER_INTERCEPT_GETPWENT_R || SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS
1a4d82fc
JJ
1269static void unpoison_passwd(void *ctx, __sanitizer_passwd *pwd) {
1270 if (pwd) {
1271 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, sizeof(*pwd));
1272 if (pwd->pw_name)
1273 COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_name,
1274 REAL(strlen)(pwd->pw_name) + 1);
1275 if (pwd->pw_passwd)
1276 COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_passwd,
1277 REAL(strlen)(pwd->pw_passwd) + 1);
1278#if !SANITIZER_ANDROID
1279 if (pwd->pw_gecos)
1280 COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_gecos,
1281 REAL(strlen)(pwd->pw_gecos) + 1);
1282#endif
1283#if SANITIZER_MAC
1284 if (pwd->pw_class)
1285 COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_class,
1286 REAL(strlen)(pwd->pw_class) + 1);
1287#endif
1288 if (pwd->pw_dir)
1289 COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_dir,
1290 REAL(strlen)(pwd->pw_dir) + 1);
1291 if (pwd->pw_shell)
1292 COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_shell,
1293 REAL(strlen)(pwd->pw_shell) + 1);
1294 }
1295}
1296
1297static void unpoison_group(void *ctx, __sanitizer_group *grp) {
1298 if (grp) {
1299 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, sizeof(*grp));
1300 if (grp->gr_name)
1301 COMMON_INTERCEPTOR_INITIALIZE_RANGE(grp->gr_name,
1302 REAL(strlen)(grp->gr_name) + 1);
1303 if (grp->gr_passwd)
1304 COMMON_INTERCEPTOR_INITIALIZE_RANGE(grp->gr_passwd,
1305 REAL(strlen)(grp->gr_passwd) + 1);
1306 char **p = grp->gr_mem;
1307 for (; *p; ++p) {
1308 COMMON_INTERCEPTOR_INITIALIZE_RANGE(*p, REAL(strlen)(*p) + 1);
1309 }
1310 COMMON_INTERCEPTOR_INITIALIZE_RANGE(grp->gr_mem,
1311 (p - grp->gr_mem + 1) * sizeof(*p));
1312 }
1313}
1314#endif // SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS ||
92a42be0
SL
1315 // SANITIZER_INTERCEPT_GETPWENT || SANITIZER_INTERCEPT_FGETPWENT ||
1316 // SANITIZER_INTERCEPT_GETPWENT_R ||
1317 // SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS
1a4d82fc
JJ
1318
1319#if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS
1320INTERCEPTOR(__sanitizer_passwd *, getpwnam, const char *name) {
1321 void *ctx;
1322 COMMON_INTERCEPTOR_ENTER(ctx, getpwnam, name);
1323 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
1324 __sanitizer_passwd *res = REAL(getpwnam)(name);
92a42be0 1325 if (res) unpoison_passwd(ctx, res);
1a4d82fc
JJ
1326 return res;
1327}
1328INTERCEPTOR(__sanitizer_passwd *, getpwuid, u32 uid) {
1329 void *ctx;
1330 COMMON_INTERCEPTOR_ENTER(ctx, getpwuid, uid);
1331 __sanitizer_passwd *res = REAL(getpwuid)(uid);
92a42be0 1332 if (res) unpoison_passwd(ctx, res);
1a4d82fc
JJ
1333 return res;
1334}
1335INTERCEPTOR(__sanitizer_group *, getgrnam, const char *name) {
1336 void *ctx;
1337 COMMON_INTERCEPTOR_ENTER(ctx, getgrnam, name);
1338 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
1339 __sanitizer_group *res = REAL(getgrnam)(name);
92a42be0 1340 if (res) unpoison_group(ctx, res);
1a4d82fc
JJ
1341 return res;
1342}
1343INTERCEPTOR(__sanitizer_group *, getgrgid, u32 gid) {
1344 void *ctx;
1345 COMMON_INTERCEPTOR_ENTER(ctx, getgrgid, gid);
1346 __sanitizer_group *res = REAL(getgrgid)(gid);
92a42be0 1347 if (res) unpoison_group(ctx, res);
1a4d82fc
JJ
1348 return res;
1349}
1350#define INIT_GETPWNAM_AND_FRIENDS \
1351 COMMON_INTERCEPT_FUNCTION(getpwnam); \
1352 COMMON_INTERCEPT_FUNCTION(getpwuid); \
1353 COMMON_INTERCEPT_FUNCTION(getgrnam); \
1354 COMMON_INTERCEPT_FUNCTION(getgrgid);
1355#else
1356#define INIT_GETPWNAM_AND_FRIENDS
1357#endif
1358
1359#if SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS
1360INTERCEPTOR(int, getpwnam_r, const char *name, __sanitizer_passwd *pwd,
1361 char *buf, SIZE_T buflen, __sanitizer_passwd **result) {
1362 void *ctx;
1363 COMMON_INTERCEPTOR_ENTER(ctx, getpwnam_r, name, pwd, buf, buflen, result);
1364 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
92a42be0
SL
1365 // FIXME: under ASan the call below may write to freed memory and corrupt
1366 // its metadata. See
1367 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
1368 int res = REAL(getpwnam_r)(name, pwd, buf, buflen, result);
1369 if (!res) {
92a42be0 1370 if (result && *result) unpoison_passwd(ctx, *result);
1a4d82fc
JJ
1371 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
1372 }
1373 if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1374 return res;
1375}
1376INTERCEPTOR(int, getpwuid_r, u32 uid, __sanitizer_passwd *pwd, char *buf,
1377 SIZE_T buflen, __sanitizer_passwd **result) {
1378 void *ctx;
1379 COMMON_INTERCEPTOR_ENTER(ctx, getpwuid_r, uid, pwd, buf, buflen, result);
92a42be0
SL
1380 // FIXME: under ASan the call below may write to freed memory and corrupt
1381 // its metadata. See
1382 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
1383 int res = REAL(getpwuid_r)(uid, pwd, buf, buflen, result);
1384 if (!res) {
92a42be0 1385 if (result && *result) unpoison_passwd(ctx, *result);
1a4d82fc
JJ
1386 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
1387 }
1388 if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1389 return res;
1390}
1391INTERCEPTOR(int, getgrnam_r, const char *name, __sanitizer_group *grp,
1392 char *buf, SIZE_T buflen, __sanitizer_group **result) {
1393 void *ctx;
1394 COMMON_INTERCEPTOR_ENTER(ctx, getgrnam_r, name, grp, buf, buflen, result);
1395 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
92a42be0
SL
1396 // FIXME: under ASan the call below may write to freed memory and corrupt
1397 // its metadata. See
1398 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
1399 int res = REAL(getgrnam_r)(name, grp, buf, buflen, result);
1400 if (!res) {
92a42be0 1401 if (result && *result) unpoison_group(ctx, *result);
1a4d82fc
JJ
1402 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
1403 }
1404 if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1405 return res;
1406}
1407INTERCEPTOR(int, getgrgid_r, u32 gid, __sanitizer_group *grp, char *buf,
1408 SIZE_T buflen, __sanitizer_group **result) {
1409 void *ctx;
1410 COMMON_INTERCEPTOR_ENTER(ctx, getgrgid_r, gid, grp, buf, buflen, result);
92a42be0
SL
1411 // FIXME: under ASan the call below may write to freed memory and corrupt
1412 // its metadata. See
1413 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
1414 int res = REAL(getgrgid_r)(gid, grp, buf, buflen, result);
1415 if (!res) {
92a42be0 1416 if (result && *result) unpoison_group(ctx, *result);
1a4d82fc
JJ
1417 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
1418 }
1419 if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1420 return res;
1421}
1422#define INIT_GETPWNAM_R_AND_FRIENDS \
1423 COMMON_INTERCEPT_FUNCTION(getpwnam_r); \
1424 COMMON_INTERCEPT_FUNCTION(getpwuid_r); \
1425 COMMON_INTERCEPT_FUNCTION(getgrnam_r); \
1426 COMMON_INTERCEPT_FUNCTION(getgrgid_r);
1427#else
1428#define INIT_GETPWNAM_R_AND_FRIENDS
1429#endif
1430
1431#if SANITIZER_INTERCEPT_GETPWENT
1432INTERCEPTOR(__sanitizer_passwd *, getpwent, int dummy) {
1433 void *ctx;
1434 COMMON_INTERCEPTOR_ENTER(ctx, getpwent, dummy);
1435 __sanitizer_passwd *res = REAL(getpwent)(dummy);
92a42be0 1436 if (res) unpoison_passwd(ctx, res);
1a4d82fc
JJ
1437 return res;
1438}
1439INTERCEPTOR(__sanitizer_group *, getgrent, int dummy) {
1440 void *ctx;
1441 COMMON_INTERCEPTOR_ENTER(ctx, getgrent, dummy);
1442 __sanitizer_group *res = REAL(getgrent)(dummy);
92a42be0 1443 if (res) unpoison_group(ctx, res);;
1a4d82fc
JJ
1444 return res;
1445}
1446#define INIT_GETPWENT \
1447 COMMON_INTERCEPT_FUNCTION(getpwent); \
1448 COMMON_INTERCEPT_FUNCTION(getgrent);
1449#else
1450#define INIT_GETPWENT
1451#endif
1452
1453#if SANITIZER_INTERCEPT_FGETPWENT
1454INTERCEPTOR(__sanitizer_passwd *, fgetpwent, void *fp) {
1455 void *ctx;
1456 COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent, fp);
1457 __sanitizer_passwd *res = REAL(fgetpwent)(fp);
92a42be0 1458 if (res) unpoison_passwd(ctx, res);
1a4d82fc
JJ
1459 return res;
1460}
1461INTERCEPTOR(__sanitizer_group *, fgetgrent, void *fp) {
1462 void *ctx;
1463 COMMON_INTERCEPTOR_ENTER(ctx, fgetgrent, fp);
1464 __sanitizer_group *res = REAL(fgetgrent)(fp);
92a42be0 1465 if (res) unpoison_group(ctx, res);
1a4d82fc
JJ
1466 return res;
1467}
1468#define INIT_FGETPWENT \
1469 COMMON_INTERCEPT_FUNCTION(fgetpwent); \
1470 COMMON_INTERCEPT_FUNCTION(fgetgrent);
1471#else
1472#define INIT_FGETPWENT
1473#endif
1474
1475#if SANITIZER_INTERCEPT_GETPWENT_R
1476INTERCEPTOR(int, getpwent_r, __sanitizer_passwd *pwbuf, char *buf,
1477 SIZE_T buflen, __sanitizer_passwd **pwbufp) {
1478 void *ctx;
1479 COMMON_INTERCEPTOR_ENTER(ctx, getpwent_r, pwbuf, buf, buflen, pwbufp);
92a42be0
SL
1480 // FIXME: under ASan the call below may write to freed memory and corrupt
1481 // its metadata. See
1482 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
1483 int res = REAL(getpwent_r)(pwbuf, buf, buflen, pwbufp);
1484 if (!res) {
92a42be0 1485 if (pwbufp && *pwbufp) unpoison_passwd(ctx, *pwbufp);
1a4d82fc
JJ
1486 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
1487 }
1488 if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
1489 return res;
1490}
1491INTERCEPTOR(int, fgetpwent_r, void *fp, __sanitizer_passwd *pwbuf, char *buf,
1492 SIZE_T buflen, __sanitizer_passwd **pwbufp) {
1493 void *ctx;
1494 COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent_r, fp, pwbuf, buf, buflen, pwbufp);
92a42be0
SL
1495 // FIXME: under ASan the call below may write to freed memory and corrupt
1496 // its metadata. See
1497 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
1498 int res = REAL(fgetpwent_r)(fp, pwbuf, buf, buflen, pwbufp);
1499 if (!res) {
92a42be0 1500 if (pwbufp && *pwbufp) unpoison_passwd(ctx, *pwbufp);
1a4d82fc
JJ
1501 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
1502 }
1503 if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
1504 return res;
1505}
1506INTERCEPTOR(int, getgrent_r, __sanitizer_group *pwbuf, char *buf, SIZE_T buflen,
1507 __sanitizer_group **pwbufp) {
1508 void *ctx;
1509 COMMON_INTERCEPTOR_ENTER(ctx, getgrent_r, pwbuf, buf, buflen, pwbufp);
92a42be0
SL
1510 // FIXME: under ASan the call below may write to freed memory and corrupt
1511 // its metadata. See
1512 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
1513 int res = REAL(getgrent_r)(pwbuf, buf, buflen, pwbufp);
1514 if (!res) {
92a42be0 1515 if (pwbufp && *pwbufp) unpoison_group(ctx, *pwbufp);
1a4d82fc
JJ
1516 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
1517 }
1518 if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
1519 return res;
1520}
1521INTERCEPTOR(int, fgetgrent_r, void *fp, __sanitizer_group *pwbuf, char *buf,
1522 SIZE_T buflen, __sanitizer_group **pwbufp) {
1523 void *ctx;
1524 COMMON_INTERCEPTOR_ENTER(ctx, fgetgrent_r, fp, pwbuf, buf, buflen, pwbufp);
92a42be0
SL
1525 // FIXME: under ASan the call below may write to freed memory and corrupt
1526 // its metadata. See
1527 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
1528 int res = REAL(fgetgrent_r)(fp, pwbuf, buf, buflen, pwbufp);
1529 if (!res) {
92a42be0 1530 if (pwbufp && *pwbufp) unpoison_group(ctx, *pwbufp);
1a4d82fc
JJ
1531 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
1532 }
1533 if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
1534 return res;
1535}
1536#define INIT_GETPWENT_R \
1537 COMMON_INTERCEPT_FUNCTION(getpwent_r); \
1538 COMMON_INTERCEPT_FUNCTION(fgetpwent_r); \
1539 COMMON_INTERCEPT_FUNCTION(getgrent_r); \
1540 COMMON_INTERCEPT_FUNCTION(fgetgrent_r);
1541#else
1542#define INIT_GETPWENT_R
1543#endif
1544
1545#if SANITIZER_INTERCEPT_SETPWENT
1546// The only thing these interceptors do is disable any nested interceptors.
1547// These functions may open nss modules and call uninstrumented functions from
1548// them, and we don't want things like strlen() to trigger.
1549INTERCEPTOR(void, setpwent, int dummy) {
1550 void *ctx;
1551 COMMON_INTERCEPTOR_ENTER(ctx, setpwent, dummy);
1552 REAL(setpwent)(dummy);
1553}
1554INTERCEPTOR(void, endpwent, int dummy) {
1555 void *ctx;
1556 COMMON_INTERCEPTOR_ENTER(ctx, endpwent, dummy);
1557 REAL(endpwent)(dummy);
1558}
1559INTERCEPTOR(void, setgrent, int dummy) {
1560 void *ctx;
1561 COMMON_INTERCEPTOR_ENTER(ctx, setgrent, dummy);
1562 REAL(setgrent)(dummy);
1563}
1564INTERCEPTOR(void, endgrent, int dummy) {
1565 void *ctx;
1566 COMMON_INTERCEPTOR_ENTER(ctx, endgrent, dummy);
1567 REAL(endgrent)(dummy);
1568}
1569#define INIT_SETPWENT \
1570 COMMON_INTERCEPT_FUNCTION(setpwent); \
1571 COMMON_INTERCEPT_FUNCTION(endpwent); \
1572 COMMON_INTERCEPT_FUNCTION(setgrent); \
1573 COMMON_INTERCEPT_FUNCTION(endgrent);
1574#else
1575#define INIT_SETPWENT
1576#endif
1577
1578#if SANITIZER_INTERCEPT_CLOCK_GETTIME
1579INTERCEPTOR(int, clock_getres, u32 clk_id, void *tp) {
1580 void *ctx;
1581 COMMON_INTERCEPTOR_ENTER(ctx, clock_getres, clk_id, tp);
92a42be0
SL
1582 // FIXME: under ASan the call below may write to freed memory and corrupt
1583 // its metadata. See
1584 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
1585 int res = REAL(clock_getres)(clk_id, tp);
1586 if (!res && tp) {
1587 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);
1588 }
1589 return res;
1590}
1591INTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) {
1592 void *ctx;
1593 COMMON_INTERCEPTOR_ENTER(ctx, clock_gettime, clk_id, tp);
92a42be0
SL
1594 // FIXME: under ASan the call below may write to freed memory and corrupt
1595 // its metadata. See
1596 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
1597 int res = REAL(clock_gettime)(clk_id, tp);
1598 if (!res) {
1599 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);
1600 }
1601 return res;
1602}
1603INTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) {
1604 void *ctx;
1605 COMMON_INTERCEPTOR_ENTER(ctx, clock_settime, clk_id, tp);
1606 COMMON_INTERCEPTOR_READ_RANGE(ctx, tp, struct_timespec_sz);
1607 return REAL(clock_settime)(clk_id, tp);
1608}
1609#define INIT_CLOCK_GETTIME \
1610 COMMON_INTERCEPT_FUNCTION(clock_getres); \
1611 COMMON_INTERCEPT_FUNCTION(clock_gettime); \
1612 COMMON_INTERCEPT_FUNCTION(clock_settime);
1613#else
1614#define INIT_CLOCK_GETTIME
1615#endif
1616
1617#if SANITIZER_INTERCEPT_GETITIMER
1618INTERCEPTOR(int, getitimer, int which, void *curr_value) {
1619 void *ctx;
1620 COMMON_INTERCEPTOR_ENTER(ctx, getitimer, which, curr_value);
92a42be0
SL
1621 // FIXME: under ASan the call below may write to freed memory and corrupt
1622 // its metadata. See
1623 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
1624 int res = REAL(getitimer)(which, curr_value);
1625 if (!res && curr_value) {
1626 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerval_sz);
1627 }
1628 return res;
1629}
1630INTERCEPTOR(int, setitimer, int which, const void *new_value, void *old_value) {
1631 void *ctx;
1632 COMMON_INTERCEPTOR_ENTER(ctx, setitimer, which, new_value, old_value);
1633 if (new_value)
1634 COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerval_sz);
92a42be0
SL
1635 // FIXME: under ASan the call below may write to freed memory and corrupt
1636 // its metadata. See
1637 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
1638 int res = REAL(setitimer)(which, new_value, old_value);
1639 if (!res && old_value) {
1640 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerval_sz);
1641 }
1642 return res;
1643}
1644#define INIT_GETITIMER \
1645 COMMON_INTERCEPT_FUNCTION(getitimer); \
1646 COMMON_INTERCEPT_FUNCTION(setitimer);
1647#else
1648#define INIT_GETITIMER
1649#endif
1650
1651#if SANITIZER_INTERCEPT_GLOB
1652static void unpoison_glob_t(void *ctx, __sanitizer_glob_t *pglob) {
1653 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob));
1654 // +1 for NULL pointer at the end.
1655 if (pglob->gl_pathv)
1656 COMMON_INTERCEPTOR_WRITE_RANGE(
1657 ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv));
1658 for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) {
1659 char *p = pglob->gl_pathv[i];
1660 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, REAL(strlen)(p) + 1);
1661 }
1662}
1663
1664static THREADLOCAL __sanitizer_glob_t *pglob_copy;
1665
1666static void wrapped_gl_closedir(void *dir) {
1667 COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
92a42be0 1668 pglob_copy->gl_closedir(dir);
1a4d82fc
JJ
1669}
1670
1671static void *wrapped_gl_readdir(void *dir) {
1672 COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
92a42be0 1673 return pglob_copy->gl_readdir(dir);
1a4d82fc
JJ
1674}
1675
1676static void *wrapped_gl_opendir(const char *s) {
1677 COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
1678 COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1);
92a42be0 1679 return pglob_copy->gl_opendir(s);
1a4d82fc
JJ
1680}
1681
1682static int wrapped_gl_lstat(const char *s, void *st) {
1683 COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
1684 COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1);
92a42be0 1685 return pglob_copy->gl_lstat(s, st);
1a4d82fc
JJ
1686}
1687
1688static int wrapped_gl_stat(const char *s, void *st) {
1689 COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
1690 COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1);
92a42be0 1691 return pglob_copy->gl_stat(s, st);
1a4d82fc
JJ
1692}
1693
1694INTERCEPTOR(int, glob, const char *pattern, int flags,
1695 int (*errfunc)(const char *epath, int eerrno),
1696 __sanitizer_glob_t *pglob) {
1697 void *ctx;
1698 COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob);
92a42be0 1699 COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0);
1a4d82fc
JJ
1700 __sanitizer_glob_t glob_copy = {
1701 0, 0, 0,
1702 0, wrapped_gl_closedir, wrapped_gl_readdir,
1703 wrapped_gl_opendir, wrapped_gl_lstat, wrapped_gl_stat};
1704 if (flags & glob_altdirfunc) {
1705 Swap(pglob->gl_closedir, glob_copy.gl_closedir);
1706 Swap(pglob->gl_readdir, glob_copy.gl_readdir);
1707 Swap(pglob->gl_opendir, glob_copy.gl_opendir);
1708 Swap(pglob->gl_lstat, glob_copy.gl_lstat);
1709 Swap(pglob->gl_stat, glob_copy.gl_stat);
1710 pglob_copy = &glob_copy;
1711 }
1712 int res = REAL(glob)(pattern, flags, errfunc, pglob);
1713 if (flags & glob_altdirfunc) {
1714 Swap(pglob->gl_closedir, glob_copy.gl_closedir);
1715 Swap(pglob->gl_readdir, glob_copy.gl_readdir);
1716 Swap(pglob->gl_opendir, glob_copy.gl_opendir);
1717 Swap(pglob->gl_lstat, glob_copy.gl_lstat);
1718 Swap(pglob->gl_stat, glob_copy.gl_stat);
1719 }
1720 pglob_copy = 0;
1721 if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
1722 return res;
1723}
1724
1725INTERCEPTOR(int, glob64, const char *pattern, int flags,
1726 int (*errfunc)(const char *epath, int eerrno),
1727 __sanitizer_glob_t *pglob) {
1728 void *ctx;
1729 COMMON_INTERCEPTOR_ENTER(ctx, glob64, pattern, flags, errfunc, pglob);
92a42be0 1730 COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0);
1a4d82fc
JJ
1731 __sanitizer_glob_t glob_copy = {
1732 0, 0, 0,
1733 0, wrapped_gl_closedir, wrapped_gl_readdir,
1734 wrapped_gl_opendir, wrapped_gl_lstat, wrapped_gl_stat};
1735 if (flags & glob_altdirfunc) {
1736 Swap(pglob->gl_closedir, glob_copy.gl_closedir);
1737 Swap(pglob->gl_readdir, glob_copy.gl_readdir);
1738 Swap(pglob->gl_opendir, glob_copy.gl_opendir);
1739 Swap(pglob->gl_lstat, glob_copy.gl_lstat);
1740 Swap(pglob->gl_stat, glob_copy.gl_stat);
1741 pglob_copy = &glob_copy;
1742 }
1743 int res = REAL(glob64)(pattern, flags, errfunc, pglob);
1744 if (flags & glob_altdirfunc) {
1745 Swap(pglob->gl_closedir, glob_copy.gl_closedir);
1746 Swap(pglob->gl_readdir, glob_copy.gl_readdir);
1747 Swap(pglob->gl_opendir, glob_copy.gl_opendir);
1748 Swap(pglob->gl_lstat, glob_copy.gl_lstat);
1749 Swap(pglob->gl_stat, glob_copy.gl_stat);
1750 }
1751 pglob_copy = 0;
1752 if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
1753 return res;
1754}
1755#define INIT_GLOB \
1756 COMMON_INTERCEPT_FUNCTION(glob); \
1757 COMMON_INTERCEPT_FUNCTION(glob64);
1758#else // SANITIZER_INTERCEPT_GLOB
1759#define INIT_GLOB
1760#endif // SANITIZER_INTERCEPT_GLOB
1761
1762#if SANITIZER_INTERCEPT_WAIT
1763// According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version
1764// suffixes on Darwin. See the declaration of INTERCEPTOR_WITH_SUFFIX for
1765// details.
1766INTERCEPTOR_WITH_SUFFIX(int, wait, int *status) {
1767 void *ctx;
1768 COMMON_INTERCEPTOR_ENTER(ctx, wait, status);
92a42be0
SL
1769 // FIXME: under ASan the call below may write to freed memory and corrupt
1770 // its metadata. See
1771 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
1772 int res = REAL(wait)(status);
1773 if (res != -1 && status)
1774 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
1775 return res;
1776}
92a42be0
SL
1777// On FreeBSD id_t is always 64-bit wide.
1778#if SANITIZER_FREEBSD && (SANITIZER_WORDSIZE == 32)
1779INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, long long id, void *infop,
1780 int options) {
1781#else
1a4d82fc
JJ
1782INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, int id, void *infop,
1783 int options) {
92a42be0 1784#endif
1a4d82fc
JJ
1785 void *ctx;
1786 COMMON_INTERCEPTOR_ENTER(ctx, waitid, idtype, id, infop, options);
92a42be0
SL
1787 // FIXME: under ASan the call below may write to freed memory and corrupt
1788 // its metadata. See
1789 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
1790 int res = REAL(waitid)(idtype, id, infop, options);
1791 if (res != -1 && infop)
1792 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, infop, siginfo_t_sz);
1793 return res;
1794}
1795INTERCEPTOR_WITH_SUFFIX(int, waitpid, int pid, int *status, int options) {
1796 void *ctx;
1797 COMMON_INTERCEPTOR_ENTER(ctx, waitpid, pid, status, options);
92a42be0
SL
1798 // FIXME: under ASan the call below may write to freed memory and corrupt
1799 // its metadata. See
1800 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
1801 int res = REAL(waitpid)(pid, status, options);
1802 if (res != -1 && status)
1803 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
1804 return res;
1805}
1806INTERCEPTOR(int, wait3, int *status, int options, void *rusage) {
1807 void *ctx;
1808 COMMON_INTERCEPTOR_ENTER(ctx, wait3, status, options, rusage);
92a42be0
SL
1809 // FIXME: under ASan the call below may write to freed memory and corrupt
1810 // its metadata. See
1811 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
1812 int res = REAL(wait3)(status, options, rusage);
1813 if (res != -1) {
1814 if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
1815 if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
1816 }
1817 return res;
1818}
1819#if SANITIZER_ANDROID
1820INTERCEPTOR(int, __wait4, int pid, int *status, int options, void *rusage) {
1821 void *ctx;
1822 COMMON_INTERCEPTOR_ENTER(ctx, __wait4, pid, status, options, rusage);
92a42be0
SL
1823 // FIXME: under ASan the call below may write to freed memory and corrupt
1824 // its metadata. See
1825 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
1826 int res = REAL(__wait4)(pid, status, options, rusage);
1827 if (res != -1) {
1828 if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
1829 if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
1830 }
1831 return res;
1832}
1833#define INIT_WAIT4 COMMON_INTERCEPT_FUNCTION(__wait4);
1834#else
1835INTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) {
1836 void *ctx;
1837 COMMON_INTERCEPTOR_ENTER(ctx, wait4, pid, status, options, rusage);
92a42be0
SL
1838 // FIXME: under ASan the call below may write to freed memory and corrupt
1839 // its metadata. See
1840 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
1841 int res = REAL(wait4)(pid, status, options, rusage);
1842 if (res != -1) {
1843 if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
1844 if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
1845 }
1846 return res;
1847}
1848#define INIT_WAIT4 COMMON_INTERCEPT_FUNCTION(wait4);
1849#endif // SANITIZER_ANDROID
1850#define INIT_WAIT \
1851 COMMON_INTERCEPT_FUNCTION(wait); \
1852 COMMON_INTERCEPT_FUNCTION(waitid); \
1853 COMMON_INTERCEPT_FUNCTION(waitpid); \
1854 COMMON_INTERCEPT_FUNCTION(wait3);
1855#else
1856#define INIT_WAIT
1857#define INIT_WAIT4
1858#endif
1859
1860#if SANITIZER_INTERCEPT_INET
1861INTERCEPTOR(char *, inet_ntop, int af, const void *src, char *dst, u32 size) {
1862 void *ctx;
1863 COMMON_INTERCEPTOR_ENTER(ctx, inet_ntop, af, src, dst, size);
1864 uptr sz = __sanitizer_in_addr_sz(af);
1865 if (sz) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sz);
1866 // FIXME: figure out read size based on the address family.
92a42be0
SL
1867 // FIXME: under ASan the call below may write to freed memory and corrupt
1868 // its metadata. See
1869 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
1870 char *res = REAL(inet_ntop)(af, src, dst, size);
1871 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
1872 return res;
1873}
1874INTERCEPTOR(int, inet_pton, int af, const char *src, void *dst) {
1875 void *ctx;
1876 COMMON_INTERCEPTOR_ENTER(ctx, inet_pton, af, src, dst);
92a42be0 1877 COMMON_INTERCEPTOR_READ_STRING(ctx, src, 0);
1a4d82fc 1878 // FIXME: figure out read size based on the address family.
92a42be0
SL
1879 // FIXME: under ASan the call below may write to freed memory and corrupt
1880 // its metadata. See
1881 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
1882 int res = REAL(inet_pton)(af, src, dst);
1883 if (res == 1) {
1884 uptr sz = __sanitizer_in_addr_sz(af);
1885 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);
1886 }
1887 return res;
1888}
1889#define INIT_INET \
1890 COMMON_INTERCEPT_FUNCTION(inet_ntop); \
1891 COMMON_INTERCEPT_FUNCTION(inet_pton);
1892#else
1893#define INIT_INET
1894#endif
1895
1896#if SANITIZER_INTERCEPT_INET
1897INTERCEPTOR(int, inet_aton, const char *cp, void *dst) {
1898 void *ctx;
1899 COMMON_INTERCEPTOR_ENTER(ctx, inet_aton, cp, dst);
1900 if (cp) COMMON_INTERCEPTOR_READ_RANGE(ctx, cp, REAL(strlen)(cp) + 1);
92a42be0
SL
1901 // FIXME: under ASan the call below may write to freed memory and corrupt
1902 // its metadata. See
1903 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
1904 int res = REAL(inet_aton)(cp, dst);
1905 if (res != 0) {
1906 uptr sz = __sanitizer_in_addr_sz(af_inet);
1907 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);
1908 }
1909 return res;
1910}
1911#define INIT_INET_ATON COMMON_INTERCEPT_FUNCTION(inet_aton);
1912#else
1913#define INIT_INET_ATON
1914#endif
1915
1916#if SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM
1917INTERCEPTOR(int, pthread_getschedparam, uptr thread, int *policy, int *param) {
1918 void *ctx;
1919 COMMON_INTERCEPTOR_ENTER(ctx, pthread_getschedparam, thread, policy, param);
92a42be0
SL
1920 // FIXME: under ASan the call below may write to freed memory and corrupt
1921 // its metadata. See
1922 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
1923 int res = REAL(pthread_getschedparam)(thread, policy, param);
1924 if (res == 0) {
1925 if (policy) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, policy, sizeof(*policy));
1926 if (param) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, sizeof(*param));
1927 }
1928 return res;
1929}
1930#define INIT_PTHREAD_GETSCHEDPARAM \
1931 COMMON_INTERCEPT_FUNCTION(pthread_getschedparam);
1932#else
1933#define INIT_PTHREAD_GETSCHEDPARAM
1934#endif
1935
1936#if SANITIZER_INTERCEPT_GETADDRINFO
1937INTERCEPTOR(int, getaddrinfo, char *node, char *service,
1938 struct __sanitizer_addrinfo *hints,
1939 struct __sanitizer_addrinfo **out) {
1940 void *ctx;
1941 COMMON_INTERCEPTOR_ENTER(ctx, getaddrinfo, node, service, hints, out);
1942 if (node) COMMON_INTERCEPTOR_READ_RANGE(ctx, node, REAL(strlen)(node) + 1);
1943 if (service)
1944 COMMON_INTERCEPTOR_READ_RANGE(ctx, service, REAL(strlen)(service) + 1);
1945 if (hints)
1946 COMMON_INTERCEPTOR_READ_RANGE(ctx, hints, sizeof(__sanitizer_addrinfo));
92a42be0
SL
1947 // FIXME: under ASan the call below may write to freed memory and corrupt
1948 // its metadata. See
1949 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
1950 int res = REAL(getaddrinfo)(node, service, hints, out);
1951 if (res == 0 && out) {
1952 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, out, sizeof(*out));
1953 struct __sanitizer_addrinfo *p = *out;
1954 while (p) {
1955 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
1956 if (p->ai_addr)
1957 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_addr, p->ai_addrlen);
1958 if (p->ai_canonname)
1959 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_canonname,
1960 REAL(strlen)(p->ai_canonname) + 1);
1961 p = p->ai_next;
1962 }
1963 }
1964 return res;
1965}
1966#define INIT_GETADDRINFO COMMON_INTERCEPT_FUNCTION(getaddrinfo);
1967#else
1968#define INIT_GETADDRINFO
1969#endif
1970
1971#if SANITIZER_INTERCEPT_GETNAMEINFO
1972INTERCEPTOR(int, getnameinfo, void *sockaddr, unsigned salen, char *host,
1973 unsigned hostlen, char *serv, unsigned servlen, int flags) {
1974 void *ctx;
1975 COMMON_INTERCEPTOR_ENTER(ctx, getnameinfo, sockaddr, salen, host, hostlen,
1976 serv, servlen, flags);
1977 // FIXME: consider adding READ_RANGE(sockaddr, salen)
1978 // There is padding in in_addr that may make this too noisy
92a42be0
SL
1979 // FIXME: under ASan the call below may write to freed memory and corrupt
1980 // its metadata. See
1981 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
1982 int res =
1983 REAL(getnameinfo)(sockaddr, salen, host, hostlen, serv, servlen, flags);
1984 if (res == 0) {
1985 if (host && hostlen)
1986 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, host, REAL(strlen)(host) + 1);
1987 if (serv && servlen)
1988 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, serv, REAL(strlen)(serv) + 1);
1989 }
1990 return res;
1991}
1992#define INIT_GETNAMEINFO COMMON_INTERCEPT_FUNCTION(getnameinfo);
1993#else
1994#define INIT_GETNAMEINFO
1995#endif
1996
1997#if SANITIZER_INTERCEPT_GETSOCKNAME
1998INTERCEPTOR(int, getsockname, int sock_fd, void *addr, int *addrlen) {
1999 void *ctx;
2000 COMMON_INTERCEPTOR_ENTER(ctx, getsockname, sock_fd, addr, addrlen);
2001 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
2002 int addrlen_in = *addrlen;
92a42be0
SL
2003 // FIXME: under ASan the call below may write to freed memory and corrupt
2004 // its metadata. See
2005 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
2006 int res = REAL(getsockname)(sock_fd, addr, addrlen);
2007 if (res == 0) {
2008 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addrlen_in, *addrlen));
2009 }
2010 return res;
2011}
2012#define INIT_GETSOCKNAME COMMON_INTERCEPT_FUNCTION(getsockname);
2013#else
2014#define INIT_GETSOCKNAME
2015#endif
2016
2017#if SANITIZER_INTERCEPT_GETHOSTBYNAME || SANITIZER_INTERCEPT_GETHOSTBYNAME_R
2018static void write_hostent(void *ctx, struct __sanitizer_hostent *h) {
2019 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h, sizeof(__sanitizer_hostent));
2020 if (h->h_name)
2021 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h->h_name, REAL(strlen)(h->h_name) + 1);
2022 char **p = h->h_aliases;
2023 while (*p) {
2024 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1);
2025 ++p;
2026 }
2027 COMMON_INTERCEPTOR_WRITE_RANGE(
2028 ctx, h->h_aliases, (p - h->h_aliases + 1) * sizeof(*h->h_aliases));
2029 p = h->h_addr_list;
2030 while (*p) {
2031 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, h->h_length);
2032 ++p;
2033 }
2034 COMMON_INTERCEPTOR_WRITE_RANGE(
2035 ctx, h->h_addr_list, (p - h->h_addr_list + 1) * sizeof(*h->h_addr_list));
2036}
2037#endif
2038
2039#if SANITIZER_INTERCEPT_GETHOSTBYNAME
2040INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname, char *name) {
2041 void *ctx;
2042 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname, name);
2043 struct __sanitizer_hostent *res = REAL(gethostbyname)(name);
2044 if (res) write_hostent(ctx, res);
2045 return res;
2046}
2047
2048INTERCEPTOR(struct __sanitizer_hostent *, gethostbyaddr, void *addr, int len,
2049 int type) {
2050 void *ctx;
2051 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr, addr, len, type);
2052 COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);
2053 struct __sanitizer_hostent *res = REAL(gethostbyaddr)(addr, len, type);
2054 if (res) write_hostent(ctx, res);
2055 return res;
2056}
2057
2058INTERCEPTOR(struct __sanitizer_hostent *, gethostent, int fake) {
2059 void *ctx;
2060 COMMON_INTERCEPTOR_ENTER(ctx, gethostent, fake);
2061 struct __sanitizer_hostent *res = REAL(gethostent)(fake);
2062 if (res) write_hostent(ctx, res);
2063 return res;
2064}
2065
2066INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname2, char *name, int af) {
2067 void *ctx;
2068 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2, name, af);
2069 struct __sanitizer_hostent *res = REAL(gethostbyname2)(name, af);
2070 if (res) write_hostent(ctx, res);
2071 return res;
2072}
2073#define INIT_GETHOSTBYNAME \
2074 COMMON_INTERCEPT_FUNCTION(gethostent); \
2075 COMMON_INTERCEPT_FUNCTION(gethostbyaddr); \
2076 COMMON_INTERCEPT_FUNCTION(gethostbyname); \
2077 COMMON_INTERCEPT_FUNCTION(gethostbyname2);
2078#else
2079#define INIT_GETHOSTBYNAME
2080#endif
2081
2082#if SANITIZER_INTERCEPT_GETHOSTBYNAME_R
92a42be0
SL
2083INTERCEPTOR(int, gethostbyname_r, char *name, struct __sanitizer_hostent *ret,
2084 char *buf, SIZE_T buflen, __sanitizer_hostent **result,
2085 int *h_errnop) {
2086 void *ctx;
2087 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname_r, name, ret, buf, buflen, result,
2088 h_errnop);
2089 // FIXME: under ASan the call below may write to freed memory and corrupt
2090 // its metadata. See
2091 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2092 int res = REAL(gethostbyname_r)(name, ret, buf, buflen, result, h_errnop);
2093 if (result) {
2094 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
2095 if (res == 0 && *result) write_hostent(ctx, *result);
2096 }
2097 if (h_errnop)
2098 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
2099 return res;
2100}
2101#define INIT_GETHOSTBYNAME_R COMMON_INTERCEPT_FUNCTION(gethostbyname_r);
2102#else
2103#define INIT_GETHOSTBYNAME_R
2104#endif
2105
2106#if SANITIZER_INTERCEPT_GETHOSTENT_R
1a4d82fc
JJ
2107INTERCEPTOR(int, gethostent_r, struct __sanitizer_hostent *ret, char *buf,
2108 SIZE_T buflen, __sanitizer_hostent **result, int *h_errnop) {
2109 void *ctx;
2110 COMMON_INTERCEPTOR_ENTER(ctx, gethostent_r, ret, buf, buflen, result,
2111 h_errnop);
92a42be0
SL
2112 // FIXME: under ASan the call below may write to freed memory and corrupt
2113 // its metadata. See
2114 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
2115 int res = REAL(gethostent_r)(ret, buf, buflen, result, h_errnop);
2116 if (result) {
2117 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
2118 if (res == 0 && *result) write_hostent(ctx, *result);
2119 }
2120 if (h_errnop)
2121 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
2122 return res;
2123}
92a42be0
SL
2124#define INIT_GETHOSTENT_R \
2125 COMMON_INTERCEPT_FUNCTION(gethostent_r);
2126#else
2127#define INIT_GETHOSTENT_R
2128#endif
1a4d82fc 2129
92a42be0 2130#if SANITIZER_INTERCEPT_GETHOSTBYADDR_R
1a4d82fc
JJ
2131INTERCEPTOR(int, gethostbyaddr_r, void *addr, int len, int type,
2132 struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,
2133 __sanitizer_hostent **result, int *h_errnop) {
2134 void *ctx;
2135 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr_r, addr, len, type, ret, buf,
2136 buflen, result, h_errnop);
2137 COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);
92a42be0
SL
2138 // FIXME: under ASan the call below may write to freed memory and corrupt
2139 // its metadata. See
2140 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
2141 int res = REAL(gethostbyaddr_r)(addr, len, type, ret, buf, buflen, result,
2142 h_errnop);
2143 if (result) {
2144 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
2145 if (res == 0 && *result) write_hostent(ctx, *result);
2146 }
2147 if (h_errnop)
2148 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
2149 return res;
2150}
92a42be0
SL
2151#define INIT_GETHOSTBYADDR_R \
2152 COMMON_INTERCEPT_FUNCTION(gethostbyaddr_r);
2153#else
2154#define INIT_GETHOSTBYADDR_R
2155#endif
1a4d82fc 2156
92a42be0 2157#if SANITIZER_INTERCEPT_GETHOSTBYNAME2_R
1a4d82fc
JJ
2158INTERCEPTOR(int, gethostbyname2_r, char *name, int af,
2159 struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,
2160 __sanitizer_hostent **result, int *h_errnop) {
2161 void *ctx;
2162 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2_r, name, af, ret, buf, buflen,
2163 result, h_errnop);
92a42be0
SL
2164 // FIXME: under ASan the call below may write to freed memory and corrupt
2165 // its metadata. See
2166 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
2167 int res =
2168 REAL(gethostbyname2_r)(name, af, ret, buf, buflen, result, h_errnop);
2169 if (result) {
2170 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
2171 if (res == 0 && *result) write_hostent(ctx, *result);
2172 }
2173 if (h_errnop)
2174 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
2175 return res;
2176}
92a42be0 2177#define INIT_GETHOSTBYNAME2_R \
1a4d82fc
JJ
2178 COMMON_INTERCEPT_FUNCTION(gethostbyname2_r);
2179#else
92a42be0 2180#define INIT_GETHOSTBYNAME2_R
1a4d82fc
JJ
2181#endif
2182
2183#if SANITIZER_INTERCEPT_GETSOCKOPT
2184INTERCEPTOR(int, getsockopt, int sockfd, int level, int optname, void *optval,
2185 int *optlen) {
2186 void *ctx;
2187 COMMON_INTERCEPTOR_ENTER(ctx, getsockopt, sockfd, level, optname, optval,
2188 optlen);
2189 if (optlen) COMMON_INTERCEPTOR_READ_RANGE(ctx, optlen, sizeof(*optlen));
92a42be0
SL
2190 // FIXME: under ASan the call below may write to freed memory and corrupt
2191 // its metadata. See
2192 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
2193 int res = REAL(getsockopt)(sockfd, level, optname, optval, optlen);
2194 if (res == 0)
2195 if (optval && optlen) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, optval, *optlen);
2196 return res;
2197}
2198#define INIT_GETSOCKOPT COMMON_INTERCEPT_FUNCTION(getsockopt);
2199#else
2200#define INIT_GETSOCKOPT
2201#endif
2202
2203#if SANITIZER_INTERCEPT_ACCEPT
2204INTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) {
2205 void *ctx;
2206 COMMON_INTERCEPTOR_ENTER(ctx, accept, fd, addr, addrlen);
92a42be0 2207 unsigned addrlen0 = 0;
1a4d82fc
JJ
2208 if (addrlen) {
2209 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
2210 addrlen0 = *addrlen;
2211 }
2212 int fd2 = REAL(accept)(fd, addr, addrlen);
2213 if (fd2 >= 0) {
2214 if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
2215 if (addr && addrlen)
2216 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
2217 }
2218 return fd2;
2219}
2220#define INIT_ACCEPT COMMON_INTERCEPT_FUNCTION(accept);
2221#else
2222#define INIT_ACCEPT
2223#endif
2224
2225#if SANITIZER_INTERCEPT_ACCEPT4
2226INTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) {
2227 void *ctx;
2228 COMMON_INTERCEPTOR_ENTER(ctx, accept4, fd, addr, addrlen, f);
92a42be0 2229 unsigned addrlen0 = 0;
1a4d82fc
JJ
2230 if (addrlen) {
2231 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
2232 addrlen0 = *addrlen;
2233 }
92a42be0
SL
2234 // FIXME: under ASan the call below may write to freed memory and corrupt
2235 // its metadata. See
2236 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
2237 int fd2 = REAL(accept4)(fd, addr, addrlen, f);
2238 if (fd2 >= 0) {
2239 if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
2240 if (addr && addrlen)
2241 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
2242 }
2243 return fd2;
2244}
2245#define INIT_ACCEPT4 COMMON_INTERCEPT_FUNCTION(accept4);
2246#else
2247#define INIT_ACCEPT4
2248#endif
2249
2250#if SANITIZER_INTERCEPT_MODF
2251INTERCEPTOR(double, modf, double x, double *iptr) {
2252 void *ctx;
2253 COMMON_INTERCEPTOR_ENTER(ctx, modf, x, iptr);
92a42be0
SL
2254 // FIXME: under ASan the call below may write to freed memory and corrupt
2255 // its metadata. See
2256 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
2257 double res = REAL(modf)(x, iptr);
2258 if (iptr) {
2259 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
2260 }
2261 return res;
2262}
2263INTERCEPTOR(float, modff, float x, float *iptr) {
2264 void *ctx;
2265 COMMON_INTERCEPTOR_ENTER(ctx, modff, x, iptr);
92a42be0
SL
2266 // FIXME: under ASan the call below may write to freed memory and corrupt
2267 // its metadata. See
2268 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
2269 float res = REAL(modff)(x, iptr);
2270 if (iptr) {
2271 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
2272 }
2273 return res;
2274}
2275INTERCEPTOR(long double, modfl, long double x, long double *iptr) {
2276 void *ctx;
2277 COMMON_INTERCEPTOR_ENTER(ctx, modfl, x, iptr);
92a42be0
SL
2278 // FIXME: under ASan the call below may write to freed memory and corrupt
2279 // its metadata. See
2280 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
2281 long double res = REAL(modfl)(x, iptr);
2282 if (iptr) {
2283 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
2284 }
2285 return res;
2286}
2287#define INIT_MODF \
2288 COMMON_INTERCEPT_FUNCTION(modf); \
2289 COMMON_INTERCEPT_FUNCTION(modff); \
2290 COMMON_INTERCEPT_FUNCTION(modfl);
2291#else
2292#define INIT_MODF
2293#endif
2294
2295#if SANITIZER_INTERCEPT_RECVMSG
2296static void write_msghdr(void *ctx, struct __sanitizer_msghdr *msg,
2297 SSIZE_T maxlen) {
2298 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg, sizeof(*msg));
2299 if (msg->msg_name && msg->msg_namelen)
2300 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_name, msg->msg_namelen);
2301 if (msg->msg_iov && msg->msg_iovlen)
2302 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_iov,
2303 sizeof(*msg->msg_iov) * msg->msg_iovlen);
2304 write_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen);
2305 if (msg->msg_control && msg->msg_controllen)
2306 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_control, msg->msg_controllen);
2307}
2308
2309INTERCEPTOR(SSIZE_T, recvmsg, int fd, struct __sanitizer_msghdr *msg,
2310 int flags) {
2311 void *ctx;
2312 COMMON_INTERCEPTOR_ENTER(ctx, recvmsg, fd, msg, flags);
92a42be0
SL
2313 // FIXME: under ASan the call below may write to freed memory and corrupt
2314 // its metadata. See
2315 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
2316 SSIZE_T res = REAL(recvmsg)(fd, msg, flags);
2317 if (res >= 0) {
2318 if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
2319 if (msg) {
2320 write_msghdr(ctx, msg, res);
2321 COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg);
2322 }
2323 }
2324 return res;
2325}
2326#define INIT_RECVMSG COMMON_INTERCEPT_FUNCTION(recvmsg);
2327#else
2328#define INIT_RECVMSG
2329#endif
2330
2331#if SANITIZER_INTERCEPT_GETPEERNAME
2332INTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) {
2333 void *ctx;
2334 COMMON_INTERCEPTOR_ENTER(ctx, getpeername, sockfd, addr, addrlen);
2335 unsigned addr_sz;
2336 if (addrlen) addr_sz = *addrlen;
92a42be0
SL
2337 // FIXME: under ASan the call below may write to freed memory and corrupt
2338 // its metadata. See
2339 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
2340 int res = REAL(getpeername)(sockfd, addr, addrlen);
2341 if (!res && addr && addrlen)
2342 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen));
2343 return res;
2344}
2345#define INIT_GETPEERNAME COMMON_INTERCEPT_FUNCTION(getpeername);
2346#else
2347#define INIT_GETPEERNAME
2348#endif
2349
2350#if SANITIZER_INTERCEPT_SYSINFO
2351INTERCEPTOR(int, sysinfo, void *info) {
2352 void *ctx;
92a42be0
SL
2353 // FIXME: under ASan the call below may write to freed memory and corrupt
2354 // its metadata. See
2355 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
2356 COMMON_INTERCEPTOR_ENTER(ctx, sysinfo, info);
2357 int res = REAL(sysinfo)(info);
2358 if (!res && info)
2359 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, struct_sysinfo_sz);
2360 return res;
2361}
2362#define INIT_SYSINFO COMMON_INTERCEPT_FUNCTION(sysinfo);
2363#else
2364#define INIT_SYSINFO
2365#endif
2366
2367#if SANITIZER_INTERCEPT_READDIR
92a42be0
SL
2368INTERCEPTOR(__sanitizer_dirent *, opendir, const char *path) {
2369 void *ctx;
2370 COMMON_INTERCEPTOR_ENTER(ctx, opendir, path);
2371 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
2372 __sanitizer_dirent *res = REAL(opendir)(path);
2373 if (res)
2374 COMMON_INTERCEPTOR_DIR_ACQUIRE(ctx, path);
2375 return res;
2376}
2377
1a4d82fc
JJ
2378INTERCEPTOR(__sanitizer_dirent *, readdir, void *dirp) {
2379 void *ctx;
2380 COMMON_INTERCEPTOR_ENTER(ctx, readdir, dirp);
92a42be0
SL
2381 // FIXME: under ASan the call below may write to freed memory and corrupt
2382 // its metadata. See
2383 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
2384 __sanitizer_dirent *res = REAL(readdir)(dirp);
2385 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen);
2386 return res;
2387}
2388
2389INTERCEPTOR(int, readdir_r, void *dirp, __sanitizer_dirent *entry,
2390 __sanitizer_dirent **result) {
2391 void *ctx;
2392 COMMON_INTERCEPTOR_ENTER(ctx, readdir_r, dirp, entry, result);
92a42be0
SL
2393 // FIXME: under ASan the call below may write to freed memory and corrupt
2394 // its metadata. See
2395 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
2396 int res = REAL(readdir_r)(dirp, entry, result);
2397 if (!res) {
2398 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
2399 if (*result)
2400 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen);
2401 }
2402 return res;
2403}
2404
2405#define INIT_READDIR \
92a42be0 2406 COMMON_INTERCEPT_FUNCTION(opendir); \
1a4d82fc
JJ
2407 COMMON_INTERCEPT_FUNCTION(readdir); \
2408 COMMON_INTERCEPT_FUNCTION(readdir_r);
2409#else
2410#define INIT_READDIR
2411#endif
2412
2413#if SANITIZER_INTERCEPT_READDIR64
2414INTERCEPTOR(__sanitizer_dirent64 *, readdir64, void *dirp) {
2415 void *ctx;
2416 COMMON_INTERCEPTOR_ENTER(ctx, readdir64, dirp);
92a42be0
SL
2417 // FIXME: under ASan the call below may write to freed memory and corrupt
2418 // its metadata. See
2419 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
2420 __sanitizer_dirent64 *res = REAL(readdir64)(dirp);
2421 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen);
2422 return res;
2423}
2424
2425INTERCEPTOR(int, readdir64_r, void *dirp, __sanitizer_dirent64 *entry,
2426 __sanitizer_dirent64 **result) {
2427 void *ctx;
2428 COMMON_INTERCEPTOR_ENTER(ctx, readdir64_r, dirp, entry, result);
92a42be0
SL
2429 // FIXME: under ASan the call below may write to freed memory and corrupt
2430 // its metadata. See
2431 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
2432 int res = REAL(readdir64_r)(dirp, entry, result);
2433 if (!res) {
2434 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
2435 if (*result)
2436 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen);
2437 }
2438 return res;
2439}
2440#define INIT_READDIR64 \
2441 COMMON_INTERCEPT_FUNCTION(readdir64); \
2442 COMMON_INTERCEPT_FUNCTION(readdir64_r);
2443#else
2444#define INIT_READDIR64
2445#endif
2446
2447#if SANITIZER_INTERCEPT_PTRACE
2448INTERCEPTOR(uptr, ptrace, int request, int pid, void *addr, void *data) {
2449 void *ctx;
2450 COMMON_INTERCEPTOR_ENTER(ctx, ptrace, request, pid, addr, data);
92a42be0 2451 __sanitizer_iovec local_iovec;
1a4d82fc
JJ
2452
2453 if (data) {
2454 if (request == ptrace_setregs)
2455 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_regs_struct_sz);
2456 else if (request == ptrace_setfpregs)
2457 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpregs_struct_sz);
2458 else if (request == ptrace_setfpxregs)
2459 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpxregs_struct_sz);
92a42be0
SL
2460 else if (request == ptrace_setvfpregs)
2461 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_vfpregs_struct_sz);
1a4d82fc
JJ
2462 else if (request == ptrace_setsiginfo)
2463 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, siginfo_t_sz);
92a42be0
SL
2464 // Some kernel might zero the iovec::iov_base in case of invalid
2465 // write access. In this case copy the invalid address for further
2466 // inspection.
2467 else if (request == ptrace_setregset || request == ptrace_getregset) {
2468 __sanitizer_iovec *iovec = (__sanitizer_iovec*)data;
2469 COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec));
2470 local_iovec = *iovec;
2471 if (request == ptrace_setregset)
2472 COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec->iov_base, iovec->iov_len);
1a4d82fc
JJ
2473 }
2474 }
2475
92a42be0
SL
2476 // FIXME: under ASan the call below may write to freed memory and corrupt
2477 // its metadata. See
2478 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
2479 uptr res = REAL(ptrace)(request, pid, addr, data);
2480
2481 if (!res && data) {
92a42be0 2482 // Note that PEEK* requests assign different meaning to the return value.
1a4d82fc
JJ
2483 // This function does not handle them (nor does it need to).
2484 if (request == ptrace_getregs)
2485 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_regs_struct_sz);
2486 else if (request == ptrace_getfpregs)
2487 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpregs_struct_sz);
2488 else if (request == ptrace_getfpxregs)
2489 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpxregs_struct_sz);
92a42be0
SL
2490 else if (request == ptrace_getvfpregs)
2491 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_vfpregs_struct_sz);
1a4d82fc
JJ
2492 else if (request == ptrace_getsiginfo)
2493 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, siginfo_t_sz);
92a42be0
SL
2494 else if (request == ptrace_geteventmsg)
2495 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, sizeof(unsigned long));
1a4d82fc 2496 else if (request == ptrace_getregset) {
92a42be0
SL
2497 __sanitizer_iovec *iovec = (__sanitizer_iovec*)data;
2498 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec, sizeof(*iovec));
2499 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, local_iovec.iov_base,
2500 local_iovec.iov_len);
1a4d82fc
JJ
2501 }
2502 }
2503 return res;
2504}
2505
2506#define INIT_PTRACE COMMON_INTERCEPT_FUNCTION(ptrace);
2507#else
2508#define INIT_PTRACE
2509#endif
2510
2511#if SANITIZER_INTERCEPT_SETLOCALE
2512INTERCEPTOR(char *, setlocale, int category, char *locale) {
2513 void *ctx;
2514 COMMON_INTERCEPTOR_ENTER(ctx, setlocale, category, locale);
2515 if (locale)
2516 COMMON_INTERCEPTOR_READ_RANGE(ctx, locale, REAL(strlen)(locale) + 1);
2517 char *res = REAL(setlocale)(category, locale);
2518 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
2519 return res;
2520}
2521
2522#define INIT_SETLOCALE COMMON_INTERCEPT_FUNCTION(setlocale);
2523#else
2524#define INIT_SETLOCALE
2525#endif
2526
2527#if SANITIZER_INTERCEPT_GETCWD
2528INTERCEPTOR(char *, getcwd, char *buf, SIZE_T size) {
2529 void *ctx;
2530 COMMON_INTERCEPTOR_ENTER(ctx, getcwd, buf, size);
92a42be0
SL
2531 // FIXME: under ASan the call below may write to freed memory and corrupt
2532 // its metadata. See
2533 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
2534 char *res = REAL(getcwd)(buf, size);
2535 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
2536 return res;
2537}
2538#define INIT_GETCWD COMMON_INTERCEPT_FUNCTION(getcwd);
2539#else
2540#define INIT_GETCWD
2541#endif
2542
2543#if SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME
2544INTERCEPTOR(char *, get_current_dir_name, int fake) {
2545 void *ctx;
2546 COMMON_INTERCEPTOR_ENTER(ctx, get_current_dir_name, fake);
92a42be0
SL
2547 // FIXME: under ASan the call below may write to freed memory and corrupt
2548 // its metadata. See
2549 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
2550 char *res = REAL(get_current_dir_name)(fake);
2551 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
2552 return res;
2553}
2554
2555#define INIT_GET_CURRENT_DIR_NAME \
2556 COMMON_INTERCEPT_FUNCTION(get_current_dir_name);
2557#else
2558#define INIT_GET_CURRENT_DIR_NAME
2559#endif
2560
92a42be0
SL
2561UNUSED static inline void FixRealStrtolEndptr(const char *nptr, char **endptr) {
2562 CHECK(endptr);
2563 if (nptr == *endptr) {
2564 // No digits were found at strtol call, we need to find out the last
2565 // symbol accessed by strtoll on our own.
2566 // We get this symbol by skipping leading blanks and optional +/- sign.
2567 while (IsSpace(*nptr)) nptr++;
2568 if (*nptr == '+' || *nptr == '-') nptr++;
2569 *endptr = const_cast<char *>(nptr);
2570 }
2571 CHECK(*endptr >= nptr);
2572}
2573
2574UNUSED static inline void StrtolFixAndCheck(void *ctx, const char *nptr,
2575 char **endptr, char *real_endptr, int base) {
2576 if (endptr) {
2577 *endptr = real_endptr;
2578 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr));
2579 }
2580 // If base has unsupported value, strtol can exit with EINVAL
2581 // without reading any characters. So do additional checks only
2582 // if base is valid.
2583 bool is_valid_base = (base == 0) || (2 <= base && base <= 36);
2584 if (is_valid_base) {
2585 FixRealStrtolEndptr(nptr, &real_endptr);
2586 }
2587 COMMON_INTERCEPTOR_READ_STRING(ctx, nptr, is_valid_base ?
2588 (real_endptr - nptr) + 1 : 0);
2589}
2590
2591
1a4d82fc
JJ
2592#if SANITIZER_INTERCEPT_STRTOIMAX
2593INTERCEPTOR(INTMAX_T, strtoimax, const char *nptr, char **endptr, int base) {
2594 void *ctx;
2595 COMMON_INTERCEPTOR_ENTER(ctx, strtoimax, nptr, endptr, base);
92a42be0
SL
2596 // FIXME: under ASan the call below may write to freed memory and corrupt
2597 // its metadata. See
2598 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2599 char *real_endptr;
2600 INTMAX_T res = REAL(strtoimax)(nptr, &real_endptr, base);
2601 StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
1a4d82fc
JJ
2602 return res;
2603}
2604
2605INTERCEPTOR(INTMAX_T, strtoumax, const char *nptr, char **endptr, int base) {
2606 void *ctx;
2607 COMMON_INTERCEPTOR_ENTER(ctx, strtoumax, nptr, endptr, base);
92a42be0
SL
2608 // FIXME: under ASan the call below may write to freed memory and corrupt
2609 // its metadata. See
2610 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2611 char *real_endptr;
2612 INTMAX_T res = REAL(strtoumax)(nptr, &real_endptr, base);
2613 StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
1a4d82fc
JJ
2614 return res;
2615}
2616
2617#define INIT_STRTOIMAX \
2618 COMMON_INTERCEPT_FUNCTION(strtoimax); \
2619 COMMON_INTERCEPT_FUNCTION(strtoumax);
2620#else
2621#define INIT_STRTOIMAX
2622#endif
2623
2624#if SANITIZER_INTERCEPT_MBSTOWCS
2625INTERCEPTOR(SIZE_T, mbstowcs, wchar_t *dest, const char *src, SIZE_T len) {
2626 void *ctx;
2627 COMMON_INTERCEPTOR_ENTER(ctx, mbstowcs, dest, src, len);
92a42be0
SL
2628 // FIXME: under ASan the call below may write to freed memory and corrupt
2629 // its metadata. See
2630 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
2631 SIZE_T res = REAL(mbstowcs)(dest, src, len);
2632 if (res != (SIZE_T) - 1 && dest) {
2633 SIZE_T write_cnt = res + (res < len);
2634 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
2635 }
2636 return res;
2637}
2638
2639INTERCEPTOR(SIZE_T, mbsrtowcs, wchar_t *dest, const char **src, SIZE_T len,
2640 void *ps) {
2641 void *ctx;
2642 COMMON_INTERCEPTOR_ENTER(ctx, mbsrtowcs, dest, src, len, ps);
2643 if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
2644 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
92a42be0
SL
2645 // FIXME: under ASan the call below may write to freed memory and corrupt
2646 // its metadata. See
2647 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
2648 SIZE_T res = REAL(mbsrtowcs)(dest, src, len, ps);
2649 if (res != (SIZE_T)(-1) && dest && src) {
2650 // This function, and several others, may or may not write the terminating
2651 // \0 character. They write it iff they clear *src.
2652 SIZE_T write_cnt = res + !*src;
2653 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
2654 }
2655 return res;
2656}
2657
2658#define INIT_MBSTOWCS \
2659 COMMON_INTERCEPT_FUNCTION(mbstowcs); \
2660 COMMON_INTERCEPT_FUNCTION(mbsrtowcs);
2661#else
2662#define INIT_MBSTOWCS
2663#endif
2664
2665#if SANITIZER_INTERCEPT_MBSNRTOWCS
2666INTERCEPTOR(SIZE_T, mbsnrtowcs, wchar_t *dest, const char **src, SIZE_T nms,
2667 SIZE_T len, void *ps) {
2668 void *ctx;
2669 COMMON_INTERCEPTOR_ENTER(ctx, mbsnrtowcs, dest, src, nms, len, ps);
2670 if (src) {
2671 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
2672 if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
2673 }
2674 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
92a42be0
SL
2675 // FIXME: under ASan the call below may write to freed memory and corrupt
2676 // its metadata. See
2677 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
2678 SIZE_T res = REAL(mbsnrtowcs)(dest, src, nms, len, ps);
2679 if (res != (SIZE_T)(-1) && dest && src) {
2680 SIZE_T write_cnt = res + !*src;
2681 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
2682 }
2683 return res;
2684}
2685
2686#define INIT_MBSNRTOWCS COMMON_INTERCEPT_FUNCTION(mbsnrtowcs);
2687#else
2688#define INIT_MBSNRTOWCS
2689#endif
2690
2691#if SANITIZER_INTERCEPT_WCSTOMBS
2692INTERCEPTOR(SIZE_T, wcstombs, char *dest, const wchar_t *src, SIZE_T len) {
2693 void *ctx;
2694 COMMON_INTERCEPTOR_ENTER(ctx, wcstombs, dest, src, len);
92a42be0
SL
2695 // FIXME: under ASan the call below may write to freed memory and corrupt
2696 // its metadata. See
2697 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
2698 SIZE_T res = REAL(wcstombs)(dest, src, len);
2699 if (res != (SIZE_T) - 1 && dest) {
2700 SIZE_T write_cnt = res + (res < len);
2701 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
2702 }
2703 return res;
2704}
2705
2706INTERCEPTOR(SIZE_T, wcsrtombs, char *dest, const wchar_t **src, SIZE_T len,
2707 void *ps) {
2708 void *ctx;
2709 COMMON_INTERCEPTOR_ENTER(ctx, wcsrtombs, dest, src, len, ps);
2710 if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
2711 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
92a42be0
SL
2712 // FIXME: under ASan the call below may write to freed memory and corrupt
2713 // its metadata. See
2714 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
2715 SIZE_T res = REAL(wcsrtombs)(dest, src, len, ps);
2716 if (res != (SIZE_T) - 1 && dest && src) {
2717 SIZE_T write_cnt = res + !*src;
2718 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
2719 }
2720 return res;
2721}
2722
2723#define INIT_WCSTOMBS \
2724 COMMON_INTERCEPT_FUNCTION(wcstombs); \
2725 COMMON_INTERCEPT_FUNCTION(wcsrtombs);
2726#else
2727#define INIT_WCSTOMBS
2728#endif
2729
2730#if SANITIZER_INTERCEPT_WCSNRTOMBS
2731INTERCEPTOR(SIZE_T, wcsnrtombs, char *dest, const wchar_t **src, SIZE_T nms,
2732 SIZE_T len, void *ps) {
2733 void *ctx;
2734 COMMON_INTERCEPTOR_ENTER(ctx, wcsnrtombs, dest, src, nms, len, ps);
2735 if (src) {
2736 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
2737 if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
2738 }
2739 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
92a42be0
SL
2740 // FIXME: under ASan the call below may write to freed memory and corrupt
2741 // its metadata. See
2742 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc 2743 SIZE_T res = REAL(wcsnrtombs)(dest, src, nms, len, ps);
92a42be0 2744 if (res != ((SIZE_T)-1) && dest && src) {
1a4d82fc
JJ
2745 SIZE_T write_cnt = res + !*src;
2746 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
2747 }
2748 return res;
2749}
2750
2751#define INIT_WCSNRTOMBS COMMON_INTERCEPT_FUNCTION(wcsnrtombs);
2752#else
2753#define INIT_WCSNRTOMBS
2754#endif
2755
92a42be0
SL
2756
2757#if SANITIZER_INTERCEPT_WCRTOMB
2758INTERCEPTOR(SIZE_T, wcrtomb, char *dest, wchar_t src, void *ps) {
2759 void *ctx;
2760 COMMON_INTERCEPTOR_ENTER(ctx, wcrtomb, dest, src, ps);
2761 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
2762 // FIXME: under ASan the call below may write to freed memory and corrupt
2763 // its metadata. See
2764 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2765 SIZE_T res = REAL(wcrtomb)(dest, src, ps);
2766 if (res != ((SIZE_T)-1) && dest) {
2767 SIZE_T write_cnt = res;
2768 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
2769 }
2770 return res;
2771}
2772
2773#define INIT_WCRTOMB COMMON_INTERCEPT_FUNCTION(wcrtomb);
2774#else
2775#define INIT_WCRTOMB
2776#endif
2777
1a4d82fc
JJ
2778#if SANITIZER_INTERCEPT_TCGETATTR
2779INTERCEPTOR(int, tcgetattr, int fd, void *termios_p) {
2780 void *ctx;
2781 COMMON_INTERCEPTOR_ENTER(ctx, tcgetattr, fd, termios_p);
92a42be0
SL
2782 // FIXME: under ASan the call below may write to freed memory and corrupt
2783 // its metadata. See
2784 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
2785 int res = REAL(tcgetattr)(fd, termios_p);
2786 if (!res && termios_p)
2787 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, termios_p, struct_termios_sz);
2788 return res;
2789}
2790
2791#define INIT_TCGETATTR COMMON_INTERCEPT_FUNCTION(tcgetattr);
2792#else
2793#define INIT_TCGETATTR
2794#endif
2795
2796#if SANITIZER_INTERCEPT_REALPATH
2797INTERCEPTOR(char *, realpath, const char *path, char *resolved_path) {
2798 void *ctx;
2799 COMMON_INTERCEPTOR_ENTER(ctx, realpath, path, resolved_path);
2800 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
2801
2802 // Workaround a bug in glibc where dlsym(RTLD_NEXT, ...) returns the oldest
2803 // version of a versioned symbol. For realpath(), this gives us something
2804 // (called __old_realpath) that does not handle NULL in the second argument.
2805 // Handle it as part of the interceptor.
92a42be0 2806 char *allocated_path = nullptr;
1a4d82fc
JJ
2807 if (!resolved_path)
2808 allocated_path = resolved_path = (char *)WRAP(malloc)(path_max + 1);
2809
2810 char *res = REAL(realpath)(path, resolved_path);
2811 if (allocated_path && !res) WRAP(free)(allocated_path);
2812 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
2813 return res;
2814}
2815#define INIT_REALPATH COMMON_INTERCEPT_FUNCTION(realpath);
2816#else
2817#define INIT_REALPATH
2818#endif
2819
2820#if SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME
2821INTERCEPTOR(char *, canonicalize_file_name, const char *path) {
2822 void *ctx;
2823 COMMON_INTERCEPTOR_ENTER(ctx, canonicalize_file_name, path);
2824 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
2825 char *res = REAL(canonicalize_file_name)(path);
2826 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
2827 return res;
2828}
2829#define INIT_CANONICALIZE_FILE_NAME \
2830 COMMON_INTERCEPT_FUNCTION(canonicalize_file_name);
2831#else
2832#define INIT_CANONICALIZE_FILE_NAME
2833#endif
2834
2835#if SANITIZER_INTERCEPT_CONFSTR
2836INTERCEPTOR(SIZE_T, confstr, int name, char *buf, SIZE_T len) {
2837 void *ctx;
2838 COMMON_INTERCEPTOR_ENTER(ctx, confstr, name, buf, len);
92a42be0
SL
2839 // FIXME: under ASan the call below may write to freed memory and corrupt
2840 // its metadata. See
2841 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
2842 SIZE_T res = REAL(confstr)(name, buf, len);
2843 if (buf && res)
2844 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res < len ? res : len);
2845 return res;
2846}
2847#define INIT_CONFSTR COMMON_INTERCEPT_FUNCTION(confstr);
2848#else
2849#define INIT_CONFSTR
2850#endif
2851
2852#if SANITIZER_INTERCEPT_SCHED_GETAFFINITY
2853INTERCEPTOR(int, sched_getaffinity, int pid, SIZE_T cpusetsize, void *mask) {
2854 void *ctx;
2855 COMMON_INTERCEPTOR_ENTER(ctx, sched_getaffinity, pid, cpusetsize, mask);
92a42be0
SL
2856 // FIXME: under ASan the call below may write to freed memory and corrupt
2857 // its metadata. See
2858 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
2859 int res = REAL(sched_getaffinity)(pid, cpusetsize, mask);
2860 if (mask && !res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mask, cpusetsize);
2861 return res;
2862}
2863#define INIT_SCHED_GETAFFINITY COMMON_INTERCEPT_FUNCTION(sched_getaffinity);
2864#else
2865#define INIT_SCHED_GETAFFINITY
2866#endif
2867
92a42be0
SL
2868#if SANITIZER_INTERCEPT_SCHED_GETPARAM
2869INTERCEPTOR(int, sched_getparam, int pid, void *param) {
2870 void *ctx;
2871 COMMON_INTERCEPTOR_ENTER(ctx, sched_getparam, pid, param);
2872 int res = REAL(sched_getparam)(pid, param);
2873 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, struct_sched_param_sz);
2874 return res;
2875}
2876#define INIT_SCHED_GETPARAM COMMON_INTERCEPT_FUNCTION(sched_getparam);
2877#else
2878#define INIT_SCHED_GETPARAM
2879#endif
2880
1a4d82fc
JJ
2881#if SANITIZER_INTERCEPT_STRERROR
2882INTERCEPTOR(char *, strerror, int errnum) {
2883 void *ctx;
2884 COMMON_INTERCEPTOR_ENTER(ctx, strerror, errnum);
2885 char *res = REAL(strerror)(errnum);
2886 if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
2887 return res;
2888}
2889#define INIT_STRERROR COMMON_INTERCEPT_FUNCTION(strerror);
2890#else
2891#define INIT_STRERROR
2892#endif
2893
2894#if SANITIZER_INTERCEPT_STRERROR_R
2895INTERCEPTOR(char *, strerror_r, int errnum, char *buf, SIZE_T buflen) {
2896 void *ctx;
2897 COMMON_INTERCEPTOR_ENTER(ctx, strerror_r, errnum, buf, buflen);
92a42be0
SL
2898 // FIXME: under ASan the call below may write to freed memory and corrupt
2899 // its metadata. See
2900 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
2901 char *res = REAL(strerror_r)(errnum, buf, buflen);
2902 // There are 2 versions of strerror_r:
2903 // * POSIX version returns 0 on success, negative error code on failure,
2904 // writes message to buf.
2905 // * GNU version returns message pointer, which points to either buf or some
2906 // static storage.
2907 SIZE_T posix_res = (SIZE_T)res;
2908 if (posix_res < 1024 || posix_res > (SIZE_T) - 1024) {
2909 // POSIX version. Spec is not clear on whether buf is NULL-terminated.
2910 // At least on OSX, buf contents are valid even when the call fails.
2911 SIZE_T sz = internal_strnlen(buf, buflen);
2912 if (sz < buflen) ++sz;
2913 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz);
2914 } else {
2915 // GNU version.
2916 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
2917 }
2918 return res;
2919}
2920#define INIT_STRERROR_R COMMON_INTERCEPT_FUNCTION(strerror_r);
2921#else
2922#define INIT_STRERROR_R
2923#endif
2924
2925#if SANITIZER_INTERCEPT_XPG_STRERROR_R
2926INTERCEPTOR(int, __xpg_strerror_r, int errnum, char *buf, SIZE_T buflen) {
2927 void *ctx;
2928 COMMON_INTERCEPTOR_ENTER(ctx, __xpg_strerror_r, errnum, buf, buflen);
92a42be0
SL
2929 // FIXME: under ASan the call below may write to freed memory and corrupt
2930 // its metadata. See
2931 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
2932 int res = REAL(__xpg_strerror_r)(errnum, buf, buflen);
2933 // This version always returns a null-terminated string.
2934 if (buf && buflen)
2935 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, REAL(strlen)(buf) + 1);
2936 return res;
2937}
2938#define INIT_XPG_STRERROR_R COMMON_INTERCEPT_FUNCTION(__xpg_strerror_r);
2939#else
2940#define INIT_XPG_STRERROR_R
2941#endif
2942
2943#if SANITIZER_INTERCEPT_SCANDIR
2944typedef int (*scandir_filter_f)(const struct __sanitizer_dirent *);
2945typedef int (*scandir_compar_f)(const struct __sanitizer_dirent **,
2946 const struct __sanitizer_dirent **);
2947
2948static THREADLOCAL scandir_filter_f scandir_filter;
2949static THREADLOCAL scandir_compar_f scandir_compar;
2950
2951static int wrapped_scandir_filter(const struct __sanitizer_dirent *dir) {
2952 COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
2953 COMMON_INTERCEPTOR_INITIALIZE_RANGE(dir, dir->d_reclen);
92a42be0 2954 return scandir_filter(dir);
1a4d82fc
JJ
2955}
2956
2957static int wrapped_scandir_compar(const struct __sanitizer_dirent **a,
2958 const struct __sanitizer_dirent **b) {
2959 COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
2960 COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, sizeof(*a));
2961 COMMON_INTERCEPTOR_INITIALIZE_RANGE(*a, (*a)->d_reclen);
2962 COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, sizeof(*b));
2963 COMMON_INTERCEPTOR_INITIALIZE_RANGE(*b, (*b)->d_reclen);
92a42be0 2964 return scandir_compar(a, b);
1a4d82fc
JJ
2965}
2966
2967INTERCEPTOR(int, scandir, char *dirp, __sanitizer_dirent ***namelist,
2968 scandir_filter_f filter, scandir_compar_f compar) {
2969 void *ctx;
2970 COMMON_INTERCEPTOR_ENTER(ctx, scandir, dirp, namelist, filter, compar);
2971 if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1);
2972 scandir_filter = filter;
2973 scandir_compar = compar;
92a42be0
SL
2974 // FIXME: under ASan the call below may write to freed memory and corrupt
2975 // its metadata. See
2976 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2977 int res = REAL(scandir)(dirp, namelist,
2978 filter ? wrapped_scandir_filter : nullptr,
2979 compar ? wrapped_scandir_compar : nullptr);
2980 scandir_filter = nullptr;
2981 scandir_compar = nullptr;
1a4d82fc
JJ
2982 if (namelist && res > 0) {
2983 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist));
2984 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res);
2985 for (int i = 0; i < res; ++i)
2986 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i],
2987 (*namelist)[i]->d_reclen);
2988 }
2989 return res;
2990}
2991#define INIT_SCANDIR COMMON_INTERCEPT_FUNCTION(scandir);
2992#else
2993#define INIT_SCANDIR
2994#endif
2995
2996#if SANITIZER_INTERCEPT_SCANDIR64
2997typedef int (*scandir64_filter_f)(const struct __sanitizer_dirent64 *);
2998typedef int (*scandir64_compar_f)(const struct __sanitizer_dirent64 **,
2999 const struct __sanitizer_dirent64 **);
3000
3001static THREADLOCAL scandir64_filter_f scandir64_filter;
3002static THREADLOCAL scandir64_compar_f scandir64_compar;
3003
3004static int wrapped_scandir64_filter(const struct __sanitizer_dirent64 *dir) {
3005 COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
3006 COMMON_INTERCEPTOR_INITIALIZE_RANGE(dir, dir->d_reclen);
92a42be0 3007 return scandir64_filter(dir);
1a4d82fc
JJ
3008}
3009
3010static int wrapped_scandir64_compar(const struct __sanitizer_dirent64 **a,
3011 const struct __sanitizer_dirent64 **b) {
3012 COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
3013 COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, sizeof(*a));
3014 COMMON_INTERCEPTOR_INITIALIZE_RANGE(*a, (*a)->d_reclen);
3015 COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, sizeof(*b));
3016 COMMON_INTERCEPTOR_INITIALIZE_RANGE(*b, (*b)->d_reclen);
92a42be0 3017 return scandir64_compar(a, b);
1a4d82fc
JJ
3018}
3019
3020INTERCEPTOR(int, scandir64, char *dirp, __sanitizer_dirent64 ***namelist,
3021 scandir64_filter_f filter, scandir64_compar_f compar) {
3022 void *ctx;
3023 COMMON_INTERCEPTOR_ENTER(ctx, scandir64, dirp, namelist, filter, compar);
3024 if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1);
3025 scandir64_filter = filter;
3026 scandir64_compar = compar;
92a42be0
SL
3027 // FIXME: under ASan the call below may write to freed memory and corrupt
3028 // its metadata. See
3029 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc 3030 int res =
92a42be0
SL
3031 REAL(scandir64)(dirp, namelist,
3032 filter ? wrapped_scandir64_filter : nullptr,
3033 compar ? wrapped_scandir64_compar : nullptr);
3034 scandir64_filter = nullptr;
3035 scandir64_compar = nullptr;
1a4d82fc
JJ
3036 if (namelist && res > 0) {
3037 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist));
3038 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res);
3039 for (int i = 0; i < res; ++i)
3040 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i],
3041 (*namelist)[i]->d_reclen);
3042 }
3043 return res;
3044}
3045#define INIT_SCANDIR64 COMMON_INTERCEPT_FUNCTION(scandir64);
3046#else
3047#define INIT_SCANDIR64
3048#endif
3049
3050#if SANITIZER_INTERCEPT_GETGROUPS
3051INTERCEPTOR(int, getgroups, int size, u32 *lst) {
3052 void *ctx;
3053 COMMON_INTERCEPTOR_ENTER(ctx, getgroups, size, lst);
92a42be0
SL
3054 // FIXME: under ASan the call below may write to freed memory and corrupt
3055 // its metadata. See
3056 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
3057 int res = REAL(getgroups)(size, lst);
3058 if (res && lst) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lst, res * sizeof(*lst));
3059 return res;
3060}
3061#define INIT_GETGROUPS COMMON_INTERCEPT_FUNCTION(getgroups);
3062#else
3063#define INIT_GETGROUPS
3064#endif
3065
3066#if SANITIZER_INTERCEPT_POLL
3067static void read_pollfd(void *ctx, __sanitizer_pollfd *fds,
3068 __sanitizer_nfds_t nfds) {
3069 for (unsigned i = 0; i < nfds; ++i) {
3070 COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].fd, sizeof(fds[i].fd));
3071 COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].events, sizeof(fds[i].events));
3072 }
3073}
3074
3075static void write_pollfd(void *ctx, __sanitizer_pollfd *fds,
3076 __sanitizer_nfds_t nfds) {
3077 for (unsigned i = 0; i < nfds; ++i)
3078 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &fds[i].revents,
3079 sizeof(fds[i].revents));
3080}
3081
3082INTERCEPTOR(int, poll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds,
3083 int timeout) {
3084 void *ctx;
3085 COMMON_INTERCEPTOR_ENTER(ctx, poll, fds, nfds, timeout);
3086 if (fds && nfds) read_pollfd(ctx, fds, nfds);
3087 int res = COMMON_INTERCEPTOR_BLOCK_REAL(poll)(fds, nfds, timeout);
3088 if (fds && nfds) write_pollfd(ctx, fds, nfds);
3089 return res;
3090}
3091#define INIT_POLL COMMON_INTERCEPT_FUNCTION(poll);
3092#else
3093#define INIT_POLL
3094#endif
3095
3096#if SANITIZER_INTERCEPT_PPOLL
3097INTERCEPTOR(int, ppoll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds,
3098 void *timeout_ts, __sanitizer_sigset_t *sigmask) {
3099 void *ctx;
3100 COMMON_INTERCEPTOR_ENTER(ctx, ppoll, fds, nfds, timeout_ts, sigmask);
3101 if (fds && nfds) read_pollfd(ctx, fds, nfds);
3102 if (timeout_ts)
3103 COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout_ts, struct_timespec_sz);
3104 // FIXME: read sigmask when all of sigemptyset, etc are intercepted.
3105 int res =
3106 COMMON_INTERCEPTOR_BLOCK_REAL(ppoll)(fds, nfds, timeout_ts, sigmask);
3107 if (fds && nfds) write_pollfd(ctx, fds, nfds);
3108 return res;
3109}
3110#define INIT_PPOLL COMMON_INTERCEPT_FUNCTION(ppoll);
3111#else
3112#define INIT_PPOLL
3113#endif
3114
3115#if SANITIZER_INTERCEPT_WORDEXP
3116INTERCEPTOR(int, wordexp, char *s, __sanitizer_wordexp_t *p, int flags) {
3117 void *ctx;
3118 COMMON_INTERCEPTOR_ENTER(ctx, wordexp, s, p, flags);
3119 if (s) COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1);
92a42be0
SL
3120 // FIXME: under ASan the call below may write to freed memory and corrupt
3121 // its metadata. See
3122 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
3123 int res = REAL(wordexp)(s, p, flags);
3124 if (!res && p) {
3125 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
3126 if (p->we_wordc)
3127 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->we_wordv,
3128 sizeof(*p->we_wordv) * p->we_wordc);
3129 for (uptr i = 0; i < p->we_wordc; ++i) {
3130 char *w = p->we_wordv[i];
3131 if (w) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, w, REAL(strlen)(w) + 1);
3132 }
3133 }
3134 return res;
3135}
3136#define INIT_WORDEXP COMMON_INTERCEPT_FUNCTION(wordexp);
3137#else
3138#define INIT_WORDEXP
3139#endif
3140
3141#if SANITIZER_INTERCEPT_SIGWAIT
3142INTERCEPTOR(int, sigwait, __sanitizer_sigset_t *set, int *sig) {
3143 void *ctx;
3144 COMMON_INTERCEPTOR_ENTER(ctx, sigwait, set, sig);
3145 // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
92a42be0
SL
3146 // FIXME: under ASan the call below may write to freed memory and corrupt
3147 // its metadata. See
3148 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
3149 int res = REAL(sigwait)(set, sig);
3150 if (!res && sig) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sig, sizeof(*sig));
3151 return res;
3152}
3153#define INIT_SIGWAIT COMMON_INTERCEPT_FUNCTION(sigwait);
3154#else
3155#define INIT_SIGWAIT
3156#endif
3157
3158#if SANITIZER_INTERCEPT_SIGWAITINFO
3159INTERCEPTOR(int, sigwaitinfo, __sanitizer_sigset_t *set, void *info) {
3160 void *ctx;
3161 COMMON_INTERCEPTOR_ENTER(ctx, sigwaitinfo, set, info);
3162 // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
92a42be0
SL
3163 // FIXME: under ASan the call below may write to freed memory and corrupt
3164 // its metadata. See
3165 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
3166 int res = REAL(sigwaitinfo)(set, info);
3167 if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz);
3168 return res;
3169}
3170#define INIT_SIGWAITINFO COMMON_INTERCEPT_FUNCTION(sigwaitinfo);
3171#else
3172#define INIT_SIGWAITINFO
3173#endif
3174
3175#if SANITIZER_INTERCEPT_SIGTIMEDWAIT
3176INTERCEPTOR(int, sigtimedwait, __sanitizer_sigset_t *set, void *info,
3177 void *timeout) {
3178 void *ctx;
3179 COMMON_INTERCEPTOR_ENTER(ctx, sigtimedwait, set, info, timeout);
3180 if (timeout) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout, struct_timespec_sz);
3181 // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
92a42be0
SL
3182 // FIXME: under ASan the call below may write to freed memory and corrupt
3183 // its metadata. See
3184 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
3185 int res = REAL(sigtimedwait)(set, info, timeout);
3186 if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz);
3187 return res;
3188}
3189#define INIT_SIGTIMEDWAIT COMMON_INTERCEPT_FUNCTION(sigtimedwait);
3190#else
3191#define INIT_SIGTIMEDWAIT
3192#endif
3193
3194#if SANITIZER_INTERCEPT_SIGSETOPS
3195INTERCEPTOR(int, sigemptyset, __sanitizer_sigset_t *set) {
3196 void *ctx;
3197 COMMON_INTERCEPTOR_ENTER(ctx, sigemptyset, set);
92a42be0
SL
3198 // FIXME: under ASan the call below may write to freed memory and corrupt
3199 // its metadata. See
3200 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
3201 int res = REAL(sigemptyset)(set);
3202 if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
3203 return res;
3204}
3205
3206INTERCEPTOR(int, sigfillset, __sanitizer_sigset_t *set) {
3207 void *ctx;
3208 COMMON_INTERCEPTOR_ENTER(ctx, sigfillset, set);
92a42be0
SL
3209 // FIXME: under ASan the call below may write to freed memory and corrupt
3210 // its metadata. See
3211 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
3212 int res = REAL(sigfillset)(set);
3213 if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
3214 return res;
3215}
3216#define INIT_SIGSETOPS \
3217 COMMON_INTERCEPT_FUNCTION(sigemptyset); \
3218 COMMON_INTERCEPT_FUNCTION(sigfillset);
3219#else
3220#define INIT_SIGSETOPS
3221#endif
3222
3223#if SANITIZER_INTERCEPT_SIGPENDING
3224INTERCEPTOR(int, sigpending, __sanitizer_sigset_t *set) {
3225 void *ctx;
3226 COMMON_INTERCEPTOR_ENTER(ctx, sigpending, set);
92a42be0
SL
3227 // FIXME: under ASan the call below may write to freed memory and corrupt
3228 // its metadata. See
3229 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
3230 int res = REAL(sigpending)(set);
3231 if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
3232 return res;
3233}
3234#define INIT_SIGPENDING COMMON_INTERCEPT_FUNCTION(sigpending);
3235#else
3236#define INIT_SIGPENDING
3237#endif
3238
3239#if SANITIZER_INTERCEPT_SIGPROCMASK
3240INTERCEPTOR(int, sigprocmask, int how, __sanitizer_sigset_t *set,
3241 __sanitizer_sigset_t *oldset) {
3242 void *ctx;
3243 COMMON_INTERCEPTOR_ENTER(ctx, sigprocmask, how, set, oldset);
3244 // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
92a42be0
SL
3245 // FIXME: under ASan the call below may write to freed memory and corrupt
3246 // its metadata. See
3247 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
3248 int res = REAL(sigprocmask)(how, set, oldset);
3249 if (!res && oldset)
3250 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset));
3251 return res;
3252}
3253#define INIT_SIGPROCMASK COMMON_INTERCEPT_FUNCTION(sigprocmask);
3254#else
3255#define INIT_SIGPROCMASK
3256#endif
3257
3258#if SANITIZER_INTERCEPT_BACKTRACE
3259INTERCEPTOR(int, backtrace, void **buffer, int size) {
3260 void *ctx;
3261 COMMON_INTERCEPTOR_ENTER(ctx, backtrace, buffer, size);
92a42be0
SL
3262 // FIXME: under ASan the call below may write to freed memory and corrupt
3263 // its metadata. See
3264 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
3265 int res = REAL(backtrace)(buffer, size);
3266 if (res && buffer)
3267 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buffer, res * sizeof(*buffer));
3268 return res;
3269}
3270
3271INTERCEPTOR(char **, backtrace_symbols, void **buffer, int size) {
3272 void *ctx;
3273 COMMON_INTERCEPTOR_ENTER(ctx, backtrace_symbols, buffer, size);
3274 if (buffer && size)
3275 COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, size * sizeof(*buffer));
92a42be0
SL
3276 // FIXME: under ASan the call below may write to freed memory and corrupt
3277 // its metadata. See
3278 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
3279 char **res = REAL(backtrace_symbols)(buffer, size);
3280 if (res && size) {
3281 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, size * sizeof(*res));
3282 for (int i = 0; i < size; ++i)
3283 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res[i], REAL(strlen(res[i])) + 1);
3284 }
3285 return res;
3286}
3287#define INIT_BACKTRACE \
3288 COMMON_INTERCEPT_FUNCTION(backtrace); \
3289 COMMON_INTERCEPT_FUNCTION(backtrace_symbols);
3290#else
3291#define INIT_BACKTRACE
3292#endif
3293
3294#if SANITIZER_INTERCEPT__EXIT
3295INTERCEPTOR(void, _exit, int status) {
3296 void *ctx;
3297 COMMON_INTERCEPTOR_ENTER(ctx, _exit, status);
3298 int status1 = COMMON_INTERCEPTOR_ON_EXIT(ctx);
3299 if (status == 0) status = status1;
3300 REAL(_exit)(status);
3301}
3302#define INIT__EXIT COMMON_INTERCEPT_FUNCTION(_exit);
3303#else
3304#define INIT__EXIT
3305#endif
3306
3307#if SANITIZER_INTERCEPT_PHTREAD_MUTEX
3308INTERCEPTOR(int, pthread_mutex_lock, void *m) {
3309 void *ctx;
3310 COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_lock, m);
3311 int res = REAL(pthread_mutex_lock)(m);
3312 if (res == errno_EOWNERDEAD)
3313 COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m);
3314 if (res == 0 || res == errno_EOWNERDEAD)
3315 COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m);
3316 return res;
3317}
3318
3319INTERCEPTOR(int, pthread_mutex_unlock, void *m) {
3320 void *ctx;
3321 COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_unlock, m);
3322 COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m);
3323 return REAL(pthread_mutex_unlock)(m);
3324}
3325
3326#define INIT_PTHREAD_MUTEX_LOCK COMMON_INTERCEPT_FUNCTION(pthread_mutex_lock)
3327#define INIT_PTHREAD_MUTEX_UNLOCK \
3328 COMMON_INTERCEPT_FUNCTION(pthread_mutex_unlock)
3329#else
3330#define INIT_PTHREAD_MUTEX_LOCK
3331#define INIT_PTHREAD_MUTEX_UNLOCK
3332#endif
3333
3334#if SANITIZER_INTERCEPT_GETMNTENT || SANITIZER_INTERCEPT_GETMNTENT_R
3335static void write_mntent(void *ctx, __sanitizer_mntent *mnt) {
3336 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt, sizeof(*mnt));
3337 if (mnt->mnt_fsname)
3338 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_fsname,
3339 REAL(strlen)(mnt->mnt_fsname) + 1);
3340 if (mnt->mnt_dir)
3341 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_dir,
3342 REAL(strlen)(mnt->mnt_dir) + 1);
3343 if (mnt->mnt_type)
3344 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_type,
3345 REAL(strlen)(mnt->mnt_type) + 1);
3346 if (mnt->mnt_opts)
3347 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_opts,
3348 REAL(strlen)(mnt->mnt_opts) + 1);
3349}
3350#endif
3351
3352#if SANITIZER_INTERCEPT_GETMNTENT
3353INTERCEPTOR(__sanitizer_mntent *, getmntent, void *fp) {
3354 void *ctx;
3355 COMMON_INTERCEPTOR_ENTER(ctx, getmntent, fp);
3356 __sanitizer_mntent *res = REAL(getmntent)(fp);
3357 if (res) write_mntent(ctx, res);
3358 return res;
3359}
3360#define INIT_GETMNTENT COMMON_INTERCEPT_FUNCTION(getmntent);
3361#else
3362#define INIT_GETMNTENT
3363#endif
3364
3365#if SANITIZER_INTERCEPT_GETMNTENT_R
3366INTERCEPTOR(__sanitizer_mntent *, getmntent_r, void *fp,
3367 __sanitizer_mntent *mntbuf, char *buf, int buflen) {
3368 void *ctx;
3369 COMMON_INTERCEPTOR_ENTER(ctx, getmntent_r, fp, mntbuf, buf, buflen);
3370 __sanitizer_mntent *res = REAL(getmntent_r)(fp, mntbuf, buf, buflen);
3371 if (res) write_mntent(ctx, res);
3372 return res;
3373}
3374#define INIT_GETMNTENT_R COMMON_INTERCEPT_FUNCTION(getmntent_r);
3375#else
3376#define INIT_GETMNTENT_R
3377#endif
3378
3379#if SANITIZER_INTERCEPT_STATFS
3380INTERCEPTOR(int, statfs, char *path, void *buf) {
3381 void *ctx;
3382 COMMON_INTERCEPTOR_ENTER(ctx, statfs, path, buf);
3383 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
92a42be0
SL
3384 // FIXME: under ASan the call below may write to freed memory and corrupt
3385 // its metadata. See
3386 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
3387 int res = REAL(statfs)(path, buf);
3388 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz);
3389 return res;
3390}
3391INTERCEPTOR(int, fstatfs, int fd, void *buf) {
3392 void *ctx;
3393 COMMON_INTERCEPTOR_ENTER(ctx, fstatfs, fd, buf);
92a42be0
SL
3394 // FIXME: under ASan the call below may write to freed memory and corrupt
3395 // its metadata. See
3396 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
3397 int res = REAL(fstatfs)(fd, buf);
3398 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz);
3399 return res;
3400}
3401#define INIT_STATFS \
3402 COMMON_INTERCEPT_FUNCTION(statfs); \
3403 COMMON_INTERCEPT_FUNCTION(fstatfs);
3404#else
3405#define INIT_STATFS
3406#endif
3407
3408#if SANITIZER_INTERCEPT_STATFS64
3409INTERCEPTOR(int, statfs64, char *path, void *buf) {
3410 void *ctx;
3411 COMMON_INTERCEPTOR_ENTER(ctx, statfs64, path, buf);
3412 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
92a42be0
SL
3413 // FIXME: under ASan the call below may write to freed memory and corrupt
3414 // its metadata. See
3415 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
3416 int res = REAL(statfs64)(path, buf);
3417 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz);
3418 return res;
3419}
3420INTERCEPTOR(int, fstatfs64, int fd, void *buf) {
3421 void *ctx;
3422 COMMON_INTERCEPTOR_ENTER(ctx, fstatfs64, fd, buf);
92a42be0
SL
3423 // FIXME: under ASan the call below may write to freed memory and corrupt
3424 // its metadata. See
3425 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
3426 int res = REAL(fstatfs64)(fd, buf);
3427 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz);
3428 return res;
3429}
3430#define INIT_STATFS64 \
3431 COMMON_INTERCEPT_FUNCTION(statfs64); \
3432 COMMON_INTERCEPT_FUNCTION(fstatfs64);
3433#else
3434#define INIT_STATFS64
3435#endif
3436
3437#if SANITIZER_INTERCEPT_STATVFS
3438INTERCEPTOR(int, statvfs, char *path, void *buf) {
3439 void *ctx;
3440 COMMON_INTERCEPTOR_ENTER(ctx, statvfs, path, buf);
3441 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
92a42be0
SL
3442 // FIXME: under ASan the call below may write to freed memory and corrupt
3443 // its metadata. See
3444 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
3445 int res = REAL(statvfs)(path, buf);
3446 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
3447 return res;
3448}
3449INTERCEPTOR(int, fstatvfs, int fd, void *buf) {
3450 void *ctx;
3451 COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs, fd, buf);
92a42be0
SL
3452 // FIXME: under ASan the call below may write to freed memory and corrupt
3453 // its metadata. See
3454 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
3455 int res = REAL(fstatvfs)(fd, buf);
3456 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
3457 return res;
3458}
3459#define INIT_STATVFS \
3460 COMMON_INTERCEPT_FUNCTION(statvfs); \
3461 COMMON_INTERCEPT_FUNCTION(fstatvfs);
3462#else
3463#define INIT_STATVFS
3464#endif
3465
3466#if SANITIZER_INTERCEPT_STATVFS64
3467INTERCEPTOR(int, statvfs64, char *path, void *buf) {
3468 void *ctx;
3469 COMMON_INTERCEPTOR_ENTER(ctx, statvfs64, path, buf);
3470 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
92a42be0
SL
3471 // FIXME: under ASan the call below may write to freed memory and corrupt
3472 // its metadata. See
3473 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
3474 int res = REAL(statvfs64)(path, buf);
3475 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz);
3476 return res;
3477}
3478INTERCEPTOR(int, fstatvfs64, int fd, void *buf) {
3479 void *ctx;
3480 COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs64, fd, buf);
92a42be0
SL
3481 // FIXME: under ASan the call below may write to freed memory and corrupt
3482 // its metadata. See
3483 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
3484 int res = REAL(fstatvfs64)(fd, buf);
3485 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz);
3486 return res;
3487}
3488#define INIT_STATVFS64 \
3489 COMMON_INTERCEPT_FUNCTION(statvfs64); \
3490 COMMON_INTERCEPT_FUNCTION(fstatvfs64);
3491#else
3492#define INIT_STATVFS64
3493#endif
3494
3495#if SANITIZER_INTERCEPT_INITGROUPS
3496INTERCEPTOR(int, initgroups, char *user, u32 group) {
3497 void *ctx;
3498 COMMON_INTERCEPTOR_ENTER(ctx, initgroups, user, group);
3499 if (user) COMMON_INTERCEPTOR_READ_RANGE(ctx, user, REAL(strlen)(user) + 1);
3500 int res = REAL(initgroups)(user, group);
3501 return res;
3502}
3503#define INIT_INITGROUPS COMMON_INTERCEPT_FUNCTION(initgroups);
3504#else
3505#define INIT_INITGROUPS
3506#endif
3507
92a42be0 3508#if SANITIZER_INTERCEPT_ETHER_NTOA_ATON
1a4d82fc
JJ
3509INTERCEPTOR(char *, ether_ntoa, __sanitizer_ether_addr *addr) {
3510 void *ctx;
3511 COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa, addr);
3512 if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
3513 char *res = REAL(ether_ntoa)(addr);
3514 if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
3515 return res;
3516}
3517INTERCEPTOR(__sanitizer_ether_addr *, ether_aton, char *buf) {
3518 void *ctx;
3519 COMMON_INTERCEPTOR_ENTER(ctx, ether_aton, buf);
3520 if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1);
3521 __sanitizer_ether_addr *res = REAL(ether_aton)(buf);
3522 if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, sizeof(*res));
3523 return res;
3524}
92a42be0
SL
3525#define INIT_ETHER_NTOA_ATON \
3526 COMMON_INTERCEPT_FUNCTION(ether_ntoa); \
3527 COMMON_INTERCEPT_FUNCTION(ether_aton);
3528#else
3529#define INIT_ETHER_NTOA_ATON
3530#endif
3531
3532#if SANITIZER_INTERCEPT_ETHER_HOST
1a4d82fc
JJ
3533INTERCEPTOR(int, ether_ntohost, char *hostname, __sanitizer_ether_addr *addr) {
3534 void *ctx;
3535 COMMON_INTERCEPTOR_ENTER(ctx, ether_ntohost, hostname, addr);
3536 if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
92a42be0
SL
3537 // FIXME: under ASan the call below may write to freed memory and corrupt
3538 // its metadata. See
3539 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
3540 int res = REAL(ether_ntohost)(hostname, addr);
3541 if (!res && hostname)
3542 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1);
3543 return res;
3544}
3545INTERCEPTOR(int, ether_hostton, char *hostname, __sanitizer_ether_addr *addr) {
3546 void *ctx;
3547 COMMON_INTERCEPTOR_ENTER(ctx, ether_hostton, hostname, addr);
3548 if (hostname)
3549 COMMON_INTERCEPTOR_READ_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1);
92a42be0
SL
3550 // FIXME: under ASan the call below may write to freed memory and corrupt
3551 // its metadata. See
3552 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
3553 int res = REAL(ether_hostton)(hostname, addr);
3554 if (!res && addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
3555 return res;
3556}
3557INTERCEPTOR(int, ether_line, char *line, __sanitizer_ether_addr *addr,
3558 char *hostname) {
3559 void *ctx;
3560 COMMON_INTERCEPTOR_ENTER(ctx, ether_line, line, addr, hostname);
3561 if (line) COMMON_INTERCEPTOR_READ_RANGE(ctx, line, REAL(strlen)(line) + 1);
92a42be0
SL
3562 // FIXME: under ASan the call below may write to freed memory and corrupt
3563 // its metadata. See
3564 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
3565 int res = REAL(ether_line)(line, addr, hostname);
3566 if (!res) {
3567 if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
3568 if (hostname)
3569 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1);
3570 }
3571 return res;
3572}
92a42be0 3573#define INIT_ETHER_HOST \
1a4d82fc
JJ
3574 COMMON_INTERCEPT_FUNCTION(ether_ntohost); \
3575 COMMON_INTERCEPT_FUNCTION(ether_hostton); \
3576 COMMON_INTERCEPT_FUNCTION(ether_line);
3577#else
92a42be0 3578#define INIT_ETHER_HOST
1a4d82fc
JJ
3579#endif
3580
3581#if SANITIZER_INTERCEPT_ETHER_R
3582INTERCEPTOR(char *, ether_ntoa_r, __sanitizer_ether_addr *addr, char *buf) {
3583 void *ctx;
3584 COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa_r, addr, buf);
3585 if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
92a42be0
SL
3586 // FIXME: under ASan the call below may write to freed memory and corrupt
3587 // its metadata. See
3588 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
3589 char *res = REAL(ether_ntoa_r)(addr, buf);
3590 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
3591 return res;
3592}
3593INTERCEPTOR(__sanitizer_ether_addr *, ether_aton_r, char *buf,
3594 __sanitizer_ether_addr *addr) {
3595 void *ctx;
3596 COMMON_INTERCEPTOR_ENTER(ctx, ether_aton_r, buf, addr);
3597 if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1);
92a42be0
SL
3598 // FIXME: under ASan the call below may write to freed memory and corrupt
3599 // its metadata. See
3600 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
3601 __sanitizer_ether_addr *res = REAL(ether_aton_r)(buf, addr);
3602 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(*res));
3603 return res;
3604}
3605#define INIT_ETHER_R \
3606 COMMON_INTERCEPT_FUNCTION(ether_ntoa_r); \
3607 COMMON_INTERCEPT_FUNCTION(ether_aton_r);
3608#else
3609#define INIT_ETHER_R
3610#endif
3611
3612#if SANITIZER_INTERCEPT_SHMCTL
3613INTERCEPTOR(int, shmctl, int shmid, int cmd, void *buf) {
3614 void *ctx;
3615 COMMON_INTERCEPTOR_ENTER(ctx, shmctl, shmid, cmd, buf);
92a42be0
SL
3616 // FIXME: under ASan the call below may write to freed memory and corrupt
3617 // its metadata. See
3618 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
3619 int res = REAL(shmctl)(shmid, cmd, buf);
3620 if (res >= 0) {
3621 unsigned sz = 0;
3622 if (cmd == shmctl_ipc_stat || cmd == shmctl_shm_stat)
3623 sz = sizeof(__sanitizer_shmid_ds);
3624 else if (cmd == shmctl_ipc_info)
3625 sz = struct_shminfo_sz;
3626 else if (cmd == shmctl_shm_info)
3627 sz = struct_shm_info_sz;
3628 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz);
3629 }
3630 return res;
3631}
3632#define INIT_SHMCTL COMMON_INTERCEPT_FUNCTION(shmctl);
3633#else
3634#define INIT_SHMCTL
3635#endif
3636
3637#if SANITIZER_INTERCEPT_RANDOM_R
3638INTERCEPTOR(int, random_r, void *buf, u32 *result) {
3639 void *ctx;
3640 COMMON_INTERCEPTOR_ENTER(ctx, random_r, buf, result);
92a42be0
SL
3641 // FIXME: under ASan the call below may write to freed memory and corrupt
3642 // its metadata. See
3643 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
3644 int res = REAL(random_r)(buf, result);
3645 if (!res && result)
3646 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
3647 return res;
3648}
3649#define INIT_RANDOM_R COMMON_INTERCEPT_FUNCTION(random_r);
3650#else
3651#define INIT_RANDOM_R
3652#endif
3653
92a42be0
SL
3654// FIXME: under ASan the REAL() call below may write to freed memory and corrupt
3655// its metadata. See
3656// https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3657#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET || \
3658 SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSSCHED || \
3659 SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GET || \
3660 SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GET || \
3661 SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GET || \
3662 SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GET
3663#define INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(fn, sz) \
3664 INTERCEPTOR(int, fn, void *attr, void *r) { \
3665 void *ctx; \
3666 COMMON_INTERCEPTOR_ENTER(ctx, fn, attr, r); \
3667 int res = REAL(fn)(attr, r); \
3668 if (!res && r) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, r, sz); \
3669 return res; \
1a4d82fc 3670 }
92a42be0
SL
3671#define INTERCEPTOR_PTHREAD_ATTR_GET(what, sz) \
3672 INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_attr_get##what, sz)
3673#define INTERCEPTOR_PTHREAD_MUTEXATTR_GET(what, sz) \
3674 INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_mutexattr_get##what, sz)
3675#define INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(what, sz) \
3676 INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_rwlockattr_get##what, sz)
3677#define INTERCEPTOR_PTHREAD_CONDATTR_GET(what, sz) \
3678 INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_condattr_get##what, sz)
3679#define INTERCEPTOR_PTHREAD_BARRIERATTR_GET(what, sz) \
3680 INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_barrierattr_get##what, sz)
1a4d82fc
JJ
3681#endif
3682
3683#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET
3684INTERCEPTOR_PTHREAD_ATTR_GET(detachstate, sizeof(int))
3685INTERCEPTOR_PTHREAD_ATTR_GET(guardsize, sizeof(SIZE_T))
3686INTERCEPTOR_PTHREAD_ATTR_GET(schedparam, struct_sched_param_sz)
3687INTERCEPTOR_PTHREAD_ATTR_GET(schedpolicy, sizeof(int))
3688INTERCEPTOR_PTHREAD_ATTR_GET(scope, sizeof(int))
3689INTERCEPTOR_PTHREAD_ATTR_GET(stacksize, sizeof(SIZE_T))
3690INTERCEPTOR(int, pthread_attr_getstack, void *attr, void **addr, SIZE_T *size) {
3691 void *ctx;
3692 COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getstack, attr, addr, size);
92a42be0
SL
3693 // FIXME: under ASan the call below may write to freed memory and corrupt
3694 // its metadata. See
3695 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
3696 int res = REAL(pthread_attr_getstack)(attr, addr, size);
3697 if (!res) {
3698 if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
3699 if (size) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, size, sizeof(*size));
3700 }
3701 return res;
3702}
3703
3704// We may need to call the real pthread_attr_getstack from the run-time
3705// in sanitizer_common, but we don't want to include the interception headers
3706// there. So, just define this function here.
3707namespace __sanitizer {
3708extern "C" {
3709int real_pthread_attr_getstack(void *attr, void **addr, SIZE_T *size) {
3710 return REAL(pthread_attr_getstack)(attr, addr, size);
3711}
3712} // extern "C"
3713} // namespace __sanitizer
3714
3715#define INIT_PTHREAD_ATTR_GET \
3716 COMMON_INTERCEPT_FUNCTION(pthread_attr_getdetachstate); \
3717 COMMON_INTERCEPT_FUNCTION(pthread_attr_getguardsize); \
3718 COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedparam); \
3719 COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedpolicy); \
3720 COMMON_INTERCEPT_FUNCTION(pthread_attr_getscope); \
3721 COMMON_INTERCEPT_FUNCTION(pthread_attr_getstacksize); \
3722 COMMON_INTERCEPT_FUNCTION(pthread_attr_getstack);
3723#else
3724#define INIT_PTHREAD_ATTR_GET
3725#endif
3726
3727#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSCHED
3728INTERCEPTOR_PTHREAD_ATTR_GET(inheritsched, sizeof(int))
3729
3730#define INIT_PTHREAD_ATTR_GETINHERITSCHED \
3731 COMMON_INTERCEPT_FUNCTION(pthread_attr_getinheritsched);
3732#else
3733#define INIT_PTHREAD_ATTR_GETINHERITSCHED
3734#endif
3735
3736#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETAFFINITY_NP
3737INTERCEPTOR(int, pthread_attr_getaffinity_np, void *attr, SIZE_T cpusetsize,
3738 void *cpuset) {
3739 void *ctx;
3740 COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getaffinity_np, attr, cpusetsize,
3741 cpuset);
92a42be0
SL
3742 // FIXME: under ASan the call below may write to freed memory and corrupt
3743 // its metadata. See
3744 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
3745 int res = REAL(pthread_attr_getaffinity_np)(attr, cpusetsize, cpuset);
3746 if (!res && cpusetsize && cpuset)
3747 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cpuset, cpusetsize);
3748 return res;
3749}
3750
3751#define INIT_PTHREAD_ATTR_GETAFFINITY_NP \
3752 COMMON_INTERCEPT_FUNCTION(pthread_attr_getaffinity_np);
3753#else
3754#define INIT_PTHREAD_ATTR_GETAFFINITY_NP
3755#endif
3756
92a42be0
SL
3757#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPSHARED
3758INTERCEPTOR_PTHREAD_MUTEXATTR_GET(pshared, sizeof(int))
3759#define INIT_PTHREAD_MUTEXATTR_GETPSHARED \
3760 COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getpshared);
3761#else
3762#define INIT_PTHREAD_MUTEXATTR_GETPSHARED
3763#endif
3764
3765#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETTYPE
3766INTERCEPTOR_PTHREAD_MUTEXATTR_GET(type, sizeof(int))
3767#define INIT_PTHREAD_MUTEXATTR_GETTYPE \
3768 COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_gettype);
3769#else
3770#define INIT_PTHREAD_MUTEXATTR_GETTYPE
3771#endif
3772
3773#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPROTOCOL
3774INTERCEPTOR_PTHREAD_MUTEXATTR_GET(protocol, sizeof(int))
3775#define INIT_PTHREAD_MUTEXATTR_GETPROTOCOL \
3776 COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getprotocol);
3777#else
3778#define INIT_PTHREAD_MUTEXATTR_GETPROTOCOL
3779#endif
3780
3781#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPRIOCEILING
3782INTERCEPTOR_PTHREAD_MUTEXATTR_GET(prioceiling, sizeof(int))
3783#define INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING \
3784 COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getprioceiling);
3785#else
3786#define INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING
3787#endif
3788
3789#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST
3790INTERCEPTOR_PTHREAD_MUTEXATTR_GET(robust, sizeof(int))
3791#define INIT_PTHREAD_MUTEXATTR_GETROBUST \
3792 COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getrobust);
3793#else
3794#define INIT_PTHREAD_MUTEXATTR_GETROBUST
3795#endif
3796
3797#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST_NP
3798INTERCEPTOR_PTHREAD_MUTEXATTR_GET(robust_np, sizeof(int))
3799#define INIT_PTHREAD_MUTEXATTR_GETROBUST_NP \
3800 COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getrobust_np);
3801#else
3802#define INIT_PTHREAD_MUTEXATTR_GETROBUST_NP
3803#endif
3804
3805#if SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETPSHARED
3806INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(pshared, sizeof(int))
3807#define INIT_PTHREAD_RWLOCKATTR_GETPSHARED \
3808 COMMON_INTERCEPT_FUNCTION(pthread_rwlockattr_getpshared);
3809#else
3810#define INIT_PTHREAD_RWLOCKATTR_GETPSHARED
3811#endif
3812
3813#if SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETKIND_NP
3814INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(kind_np, sizeof(int))
3815#define INIT_PTHREAD_RWLOCKATTR_GETKIND_NP \
3816 COMMON_INTERCEPT_FUNCTION(pthread_rwlockattr_getkind_np);
3817#else
3818#define INIT_PTHREAD_RWLOCKATTR_GETKIND_NP
3819#endif
3820
3821#if SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETPSHARED
3822INTERCEPTOR_PTHREAD_CONDATTR_GET(pshared, sizeof(int))
3823#define INIT_PTHREAD_CONDATTR_GETPSHARED \
3824 COMMON_INTERCEPT_FUNCTION(pthread_condattr_getpshared);
3825#else
3826#define INIT_PTHREAD_CONDATTR_GETPSHARED
3827#endif
3828
3829#if SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETCLOCK
3830INTERCEPTOR_PTHREAD_CONDATTR_GET(clock, sizeof(int))
3831#define INIT_PTHREAD_CONDATTR_GETCLOCK \
3832 COMMON_INTERCEPT_FUNCTION(pthread_condattr_getclock);
3833#else
3834#define INIT_PTHREAD_CONDATTR_GETCLOCK
3835#endif
3836
3837#if SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GETPSHARED
3838INTERCEPTOR_PTHREAD_BARRIERATTR_GET(pshared, sizeof(int)) // !mac !android
3839#define INIT_PTHREAD_BARRIERATTR_GETPSHARED \
3840 COMMON_INTERCEPT_FUNCTION(pthread_barrierattr_getpshared);
3841#else
3842#define INIT_PTHREAD_BARRIERATTR_GETPSHARED
3843#endif
3844
1a4d82fc
JJ
3845#if SANITIZER_INTERCEPT_TMPNAM
3846INTERCEPTOR(char *, tmpnam, char *s) {
3847 void *ctx;
3848 COMMON_INTERCEPTOR_ENTER(ctx, tmpnam, s);
3849 char *res = REAL(tmpnam)(s);
3850 if (res) {
3851 if (s)
92a42be0
SL
3852 // FIXME: under ASan the call below may write to freed memory and corrupt
3853 // its metadata. See
3854 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
3855 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1);
3856 else
3857 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
3858 }
3859 return res;
3860}
3861#define INIT_TMPNAM COMMON_INTERCEPT_FUNCTION(tmpnam);
3862#else
3863#define INIT_TMPNAM
3864#endif
3865
3866#if SANITIZER_INTERCEPT_TMPNAM_R
3867INTERCEPTOR(char *, tmpnam_r, char *s) {
3868 void *ctx;
3869 COMMON_INTERCEPTOR_ENTER(ctx, tmpnam_r, s);
92a42be0
SL
3870 // FIXME: under ASan the call below may write to freed memory and corrupt
3871 // its metadata. See
3872 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
3873 char *res = REAL(tmpnam_r)(s);
3874 if (res && s) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1);
3875 return res;
3876}
3877#define INIT_TMPNAM_R COMMON_INTERCEPT_FUNCTION(tmpnam_r);
3878#else
3879#define INIT_TMPNAM_R
3880#endif
3881
3882#if SANITIZER_INTERCEPT_TEMPNAM
3883INTERCEPTOR(char *, tempnam, char *dir, char *pfx) {
3884 void *ctx;
3885 COMMON_INTERCEPTOR_ENTER(ctx, tempnam, dir, pfx);
3886 if (dir) COMMON_INTERCEPTOR_READ_RANGE(ctx, dir, REAL(strlen)(dir) + 1);
3887 if (pfx) COMMON_INTERCEPTOR_READ_RANGE(ctx, pfx, REAL(strlen)(pfx) + 1);
3888 char *res = REAL(tempnam)(dir, pfx);
3889 if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
3890 return res;
3891}
3892#define INIT_TEMPNAM COMMON_INTERCEPT_FUNCTION(tempnam);
3893#else
3894#define INIT_TEMPNAM
3895#endif
3896
3897#if SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP
3898INTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name) {
3899 void *ctx;
3900 COMMON_INTERCEPTOR_ENTER(ctx, pthread_setname_np, thread, name);
92a42be0 3901 COMMON_INTERCEPTOR_READ_STRING(ctx, name, 0);
1a4d82fc
JJ
3902 COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name);
3903 return REAL(pthread_setname_np)(thread, name);
3904}
3905#define INIT_PTHREAD_SETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_setname_np);
3906#else
3907#define INIT_PTHREAD_SETNAME_NP
3908#endif
3909
3910#if SANITIZER_INTERCEPT_SINCOS
3911INTERCEPTOR(void, sincos, double x, double *sin, double *cos) {
3912 void *ctx;
3913 COMMON_INTERCEPTOR_ENTER(ctx, sincos, x, sin, cos);
92a42be0
SL
3914 // FIXME: under ASan the call below may write to freed memory and corrupt
3915 // its metadata. See
3916 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
3917 REAL(sincos)(x, sin, cos);
3918 if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));
3919 if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));
3920}
3921INTERCEPTOR(void, sincosf, float x, float *sin, float *cos) {
3922 void *ctx;
3923 COMMON_INTERCEPTOR_ENTER(ctx, sincosf, x, sin, cos);
92a42be0
SL
3924 // FIXME: under ASan the call below may write to freed memory and corrupt
3925 // its metadata. See
3926 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
3927 REAL(sincosf)(x, sin, cos);
3928 if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));
3929 if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));
3930}
3931INTERCEPTOR(void, sincosl, long double x, long double *sin, long double *cos) {
3932 void *ctx;
3933 COMMON_INTERCEPTOR_ENTER(ctx, sincosl, x, sin, cos);
92a42be0
SL
3934 // FIXME: under ASan the call below may write to freed memory and corrupt
3935 // its metadata. See
3936 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
3937 REAL(sincosl)(x, sin, cos);
3938 if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));
3939 if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));
3940}
3941#define INIT_SINCOS \
3942 COMMON_INTERCEPT_FUNCTION(sincos); \
3943 COMMON_INTERCEPT_FUNCTION(sincosf); \
3944 COMMON_INTERCEPT_FUNCTION(sincosl);
3945#else
3946#define INIT_SINCOS
3947#endif
3948
3949#if SANITIZER_INTERCEPT_REMQUO
3950INTERCEPTOR(double, remquo, double x, double y, int *quo) {
3951 void *ctx;
3952 COMMON_INTERCEPTOR_ENTER(ctx, remquo, x, y, quo);
92a42be0
SL
3953 // FIXME: under ASan the call below may write to freed memory and corrupt
3954 // its metadata. See
3955 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
3956 double res = REAL(remquo)(x, y, quo);
3957 if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
3958 return res;
3959}
3960INTERCEPTOR(float, remquof, float x, float y, int *quo) {
3961 void *ctx;
3962 COMMON_INTERCEPTOR_ENTER(ctx, remquof, x, y, quo);
92a42be0
SL
3963 // FIXME: under ASan the call below may write to freed memory and corrupt
3964 // its metadata. See
3965 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
3966 float res = REAL(remquof)(x, y, quo);
3967 if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
3968 return res;
3969}
3970INTERCEPTOR(long double, remquol, long double x, long double y, int *quo) {
3971 void *ctx;
3972 COMMON_INTERCEPTOR_ENTER(ctx, remquol, x, y, quo);
92a42be0
SL
3973 // FIXME: under ASan the call below may write to freed memory and corrupt
3974 // its metadata. See
3975 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
3976 long double res = REAL(remquol)(x, y, quo);
3977 if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
3978 return res;
3979}
3980#define INIT_REMQUO \
3981 COMMON_INTERCEPT_FUNCTION(remquo); \
3982 COMMON_INTERCEPT_FUNCTION(remquof); \
3983 COMMON_INTERCEPT_FUNCTION(remquol);
3984#else
3985#define INIT_REMQUO
3986#endif
3987
3988#if SANITIZER_INTERCEPT_LGAMMA
3989extern int signgam;
3990INTERCEPTOR(double, lgamma, double x) {
3991 void *ctx;
3992 COMMON_INTERCEPTOR_ENTER(ctx, lgamma, x);
3993 double res = REAL(lgamma)(x);
3994 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
3995 return res;
3996}
3997INTERCEPTOR(float, lgammaf, float x) {
3998 void *ctx;
3999 COMMON_INTERCEPTOR_ENTER(ctx, lgammaf, x);
4000 float res = REAL(lgammaf)(x);
4001 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
4002 return res;
4003}
4004INTERCEPTOR(long double, lgammal, long double x) {
4005 void *ctx;
4006 COMMON_INTERCEPTOR_ENTER(ctx, lgammal, x);
4007 long double res = REAL(lgammal)(x);
4008 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
4009 return res;
4010}
4011#define INIT_LGAMMA \
4012 COMMON_INTERCEPT_FUNCTION(lgamma); \
4013 COMMON_INTERCEPT_FUNCTION(lgammaf); \
4014 COMMON_INTERCEPT_FUNCTION(lgammal);
4015#else
4016#define INIT_LGAMMA
4017#endif
4018
4019#if SANITIZER_INTERCEPT_LGAMMA_R
4020INTERCEPTOR(double, lgamma_r, double x, int *signp) {
4021 void *ctx;
4022 COMMON_INTERCEPTOR_ENTER(ctx, lgamma_r, x, signp);
92a42be0
SL
4023 // FIXME: under ASan the call below may write to freed memory and corrupt
4024 // its metadata. See
4025 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
4026 double res = REAL(lgamma_r)(x, signp);
4027 if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
4028 return res;
4029}
4030INTERCEPTOR(float, lgammaf_r, float x, int *signp) {
4031 void *ctx;
4032 COMMON_INTERCEPTOR_ENTER(ctx, lgammaf_r, x, signp);
92a42be0
SL
4033 // FIXME: under ASan the call below may write to freed memory and corrupt
4034 // its metadata. See
4035 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
4036 float res = REAL(lgammaf_r)(x, signp);
4037 if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
4038 return res;
4039}
92a42be0
SL
4040#define INIT_LGAMMA_R \
4041 COMMON_INTERCEPT_FUNCTION(lgamma_r); \
4042 COMMON_INTERCEPT_FUNCTION(lgammaf_r);
4043#else
4044#define INIT_LGAMMA_R
4045#endif
4046
4047#if SANITIZER_INTERCEPT_LGAMMAL_R
1a4d82fc
JJ
4048INTERCEPTOR(long double, lgammal_r, long double x, int *signp) {
4049 void *ctx;
4050 COMMON_INTERCEPTOR_ENTER(ctx, lgammal_r, x, signp);
92a42be0
SL
4051 // FIXME: under ASan the call below may write to freed memory and corrupt
4052 // its metadata. See
4053 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
4054 long double res = REAL(lgammal_r)(x, signp);
4055 if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
4056 return res;
4057}
92a42be0 4058#define INIT_LGAMMAL_R COMMON_INTERCEPT_FUNCTION(lgammal_r);
1a4d82fc 4059#else
92a42be0 4060#define INIT_LGAMMAL_R
1a4d82fc
JJ
4061#endif
4062
4063#if SANITIZER_INTERCEPT_DRAND48_R
4064INTERCEPTOR(int, drand48_r, void *buffer, double *result) {
4065 void *ctx;
4066 COMMON_INTERCEPTOR_ENTER(ctx, drand48_r, buffer, result);
92a42be0
SL
4067 // FIXME: under ASan the call below may write to freed memory and corrupt
4068 // its metadata. See
4069 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
4070 int res = REAL(drand48_r)(buffer, result);
4071 if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
4072 return res;
4073}
4074INTERCEPTOR(int, lrand48_r, void *buffer, long *result) {
4075 void *ctx;
4076 COMMON_INTERCEPTOR_ENTER(ctx, lrand48_r, buffer, result);
92a42be0
SL
4077 // FIXME: under ASan the call below may write to freed memory and corrupt
4078 // its metadata. See
4079 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
4080 int res = REAL(lrand48_r)(buffer, result);
4081 if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
4082 return res;
4083}
4084#define INIT_DRAND48_R \
4085 COMMON_INTERCEPT_FUNCTION(drand48_r); \
4086 COMMON_INTERCEPT_FUNCTION(lrand48_r);
4087#else
4088#define INIT_DRAND48_R
4089#endif
4090
4091#if SANITIZER_INTERCEPT_RAND_R
4092INTERCEPTOR(int, rand_r, unsigned *seedp) {
4093 void *ctx;
4094 COMMON_INTERCEPTOR_ENTER(ctx, rand_r, seedp);
4095 COMMON_INTERCEPTOR_READ_RANGE(ctx, seedp, sizeof(*seedp));
4096 return REAL(rand_r)(seedp);
4097}
4098#define INIT_RAND_R COMMON_INTERCEPT_FUNCTION(rand_r);
4099#else
4100#define INIT_RAND_R
4101#endif
4102
4103#if SANITIZER_INTERCEPT_GETLINE
4104INTERCEPTOR(SSIZE_T, getline, char **lineptr, SIZE_T *n, void *stream) {
4105 void *ctx;
4106 COMMON_INTERCEPTOR_ENTER(ctx, getline, lineptr, n, stream);
92a42be0
SL
4107 // FIXME: under ASan the call below may write to freed memory and corrupt
4108 // its metadata. See
4109 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
4110 SSIZE_T res = REAL(getline)(lineptr, n, stream);
4111 if (res > 0) {
4112 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr));
4113 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));
4114 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1);
4115 }
4116 return res;
4117}
92a42be0
SL
4118
4119// FIXME: under ASan the call below may write to freed memory and corrupt its
4120// metadata. See
4121// https://code.google.com/p/address-sanitizer/issues/detail?id=321.
4122#define GETDELIM_INTERCEPTOR_IMPL(vname) \
4123 { \
4124 void *ctx; \
4125 COMMON_INTERCEPTOR_ENTER(ctx, vname, lineptr, n, delim, stream); \
4126 SSIZE_T res = REAL(vname)(lineptr, n, delim, stream); \
4127 if (res > 0) { \
4128 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr)); \
4129 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n)); \
4130 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1); \
4131 } \
4132 return res; \
1a4d82fc 4133 }
92a42be0
SL
4134
4135INTERCEPTOR(SSIZE_T, __getdelim, char **lineptr, SIZE_T *n, int delim,
4136 void *stream)
4137GETDELIM_INTERCEPTOR_IMPL(__getdelim)
4138
4139// There's no __getdelim() on FreeBSD so we supply the getdelim() interceptor
4140// with its own body.
4141INTERCEPTOR(SSIZE_T, getdelim, char **lineptr, SIZE_T *n, int delim,
4142 void *stream)
4143GETDELIM_INTERCEPTOR_IMPL(getdelim)
4144
4145#define INIT_GETLINE \
4146 COMMON_INTERCEPT_FUNCTION(getline); \
4147 COMMON_INTERCEPT_FUNCTION(__getdelim); \
1a4d82fc
JJ
4148 COMMON_INTERCEPT_FUNCTION(getdelim);
4149#else
4150#define INIT_GETLINE
4151#endif
4152
4153#if SANITIZER_INTERCEPT_ICONV
4154INTERCEPTOR(SIZE_T, iconv, void *cd, char **inbuf, SIZE_T *inbytesleft,
4155 char **outbuf, SIZE_T *outbytesleft) {
4156 void *ctx;
4157 COMMON_INTERCEPTOR_ENTER(ctx, iconv, cd, inbuf, inbytesleft, outbuf,
4158 outbytesleft);
4159 if (inbytesleft)
4160 COMMON_INTERCEPTOR_READ_RANGE(ctx, inbytesleft, sizeof(*inbytesleft));
4161 if (inbuf && inbytesleft)
4162 COMMON_INTERCEPTOR_READ_RANGE(ctx, *inbuf, *inbytesleft);
4163 if (outbytesleft)
4164 COMMON_INTERCEPTOR_READ_RANGE(ctx, outbytesleft, sizeof(*outbytesleft));
92a42be0
SL
4165 void *outbuf_orig = outbuf ? *outbuf : nullptr;
4166 // FIXME: under ASan the call below may write to freed memory and corrupt
4167 // its metadata. See
4168 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
4169 SIZE_T res = REAL(iconv)(cd, inbuf, inbytesleft, outbuf, outbytesleft);
4170 if (res != (SIZE_T) - 1 && outbuf && *outbuf > outbuf_orig) {
4171 SIZE_T sz = (char *)*outbuf - (char *)outbuf_orig;
4172 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, outbuf_orig, sz);
4173 }
4174 return res;
4175}
4176#define INIT_ICONV COMMON_INTERCEPT_FUNCTION(iconv);
4177#else
4178#define INIT_ICONV
4179#endif
4180
4181#if SANITIZER_INTERCEPT_TIMES
4182INTERCEPTOR(__sanitizer_clock_t, times, void *tms) {
4183 void *ctx;
4184 COMMON_INTERCEPTOR_ENTER(ctx, times, tms);
92a42be0
SL
4185 // FIXME: under ASan the call below may write to freed memory and corrupt
4186 // its metadata. See
4187 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
4188 __sanitizer_clock_t res = REAL(times)(tms);
4189 if (res != (__sanitizer_clock_t)-1 && tms)
4190 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tms, struct_tms_sz);
4191 return res;
4192}
4193#define INIT_TIMES COMMON_INTERCEPT_FUNCTION(times);
4194#else
4195#define INIT_TIMES
4196#endif
4197
4198#if SANITIZER_INTERCEPT_TLS_GET_ADDR
4199#define INIT_TLS_GET_ADDR COMMON_INTERCEPT_FUNCTION(__tls_get_addr)
92a42be0
SL
4200// If you see any crashes around this functions, there are 2 known issues with
4201// it: 1. __tls_get_addr can be called with mis-aligned stack due to:
4202// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58066
4203// 2. It can be called recursively if sanitizer code uses __tls_get_addr
4204// to access thread local variables (it should not happen normally,
4205// because sanitizers use initial-exec tls model).
1a4d82fc
JJ
4206INTERCEPTOR(void *, __tls_get_addr, void *arg) {
4207 void *ctx;
4208 COMMON_INTERCEPTOR_ENTER(ctx, __tls_get_addr, arg);
4209 void *res = REAL(__tls_get_addr)(arg);
92a42be0
SL
4210 uptr tls_begin, tls_end;
4211 COMMON_INTERCEPTOR_GET_TLS_RANGE(&tls_begin, &tls_end);
4212 DTLS::DTV *dtv = DTLS_on_tls_get_addr(arg, res, tls_begin, tls_end);
4213 if (dtv) {
4214 // New DTLS block has been allocated.
4215 COMMON_INTERCEPTOR_INITIALIZE_RANGE((void *)dtv->beg, dtv->size);
4216 }
1a4d82fc
JJ
4217 return res;
4218}
4219#else
4220#define INIT_TLS_GET_ADDR
4221#endif
4222
4223#if SANITIZER_INTERCEPT_LISTXATTR
4224INTERCEPTOR(SSIZE_T, listxattr, const char *path, char *list, SIZE_T size) {
4225 void *ctx;
4226 COMMON_INTERCEPTOR_ENTER(ctx, listxattr, path, list, size);
4227 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
92a42be0
SL
4228 // FIXME: under ASan the call below may write to freed memory and corrupt
4229 // its metadata. See
4230 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
4231 SSIZE_T res = REAL(listxattr)(path, list, size);
4232 // Here and below, size == 0 is a special case where nothing is written to the
4233 // buffer, and res contains the desired buffer size.
4234 if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);
4235 return res;
4236}
4237INTERCEPTOR(SSIZE_T, llistxattr, const char *path, char *list, SIZE_T size) {
4238 void *ctx;
4239 COMMON_INTERCEPTOR_ENTER(ctx, llistxattr, path, list, size);
4240 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
92a42be0
SL
4241 // FIXME: under ASan the call below may write to freed memory and corrupt
4242 // its metadata. See
4243 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
4244 SSIZE_T res = REAL(llistxattr)(path, list, size);
4245 if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);
4246 return res;
4247}
4248INTERCEPTOR(SSIZE_T, flistxattr, int fd, char *list, SIZE_T size) {
4249 void *ctx;
4250 COMMON_INTERCEPTOR_ENTER(ctx, flistxattr, fd, list, size);
92a42be0
SL
4251 // FIXME: under ASan the call below may write to freed memory and corrupt
4252 // its metadata. See
4253 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
4254 SSIZE_T res = REAL(flistxattr)(fd, list, size);
4255 if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);
4256 return res;
4257}
4258#define INIT_LISTXATTR \
4259 COMMON_INTERCEPT_FUNCTION(listxattr); \
4260 COMMON_INTERCEPT_FUNCTION(llistxattr); \
4261 COMMON_INTERCEPT_FUNCTION(flistxattr);
4262#else
4263#define INIT_LISTXATTR
4264#endif
4265
4266#if SANITIZER_INTERCEPT_GETXATTR
4267INTERCEPTOR(SSIZE_T, getxattr, const char *path, const char *name, char *value,
4268 SIZE_T size) {
4269 void *ctx;
4270 COMMON_INTERCEPTOR_ENTER(ctx, getxattr, path, name, value, size);
4271 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
4272 if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
92a42be0
SL
4273 // FIXME: under ASan the call below may write to freed memory and corrupt
4274 // its metadata. See
4275 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
4276 SSIZE_T res = REAL(getxattr)(path, name, value, size);
4277 if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);
4278 return res;
4279}
4280INTERCEPTOR(SSIZE_T, lgetxattr, const char *path, const char *name, char *value,
4281 SIZE_T size) {
4282 void *ctx;
4283 COMMON_INTERCEPTOR_ENTER(ctx, lgetxattr, path, name, value, size);
4284 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
4285 if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
92a42be0
SL
4286 // FIXME: under ASan the call below may write to freed memory and corrupt
4287 // its metadata. See
4288 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
4289 SSIZE_T res = REAL(lgetxattr)(path, name, value, size);
4290 if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);
4291 return res;
4292}
4293INTERCEPTOR(SSIZE_T, fgetxattr, int fd, const char *name, char *value,
4294 SIZE_T size) {
4295 void *ctx;
4296 COMMON_INTERCEPTOR_ENTER(ctx, fgetxattr, fd, name, value, size);
4297 if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
92a42be0
SL
4298 // FIXME: under ASan the call below may write to freed memory and corrupt
4299 // its metadata. See
4300 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
4301 SSIZE_T res = REAL(fgetxattr)(fd, name, value, size);
4302 if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);
4303 return res;
4304}
4305#define INIT_GETXATTR \
4306 COMMON_INTERCEPT_FUNCTION(getxattr); \
4307 COMMON_INTERCEPT_FUNCTION(lgetxattr); \
4308 COMMON_INTERCEPT_FUNCTION(fgetxattr);
4309#else
4310#define INIT_GETXATTR
4311#endif
4312
4313#if SANITIZER_INTERCEPT_GETRESID
4314INTERCEPTOR(int, getresuid, void *ruid, void *euid, void *suid) {
4315 void *ctx;
4316 COMMON_INTERCEPTOR_ENTER(ctx, getresuid, ruid, euid, suid);
92a42be0
SL
4317 // FIXME: under ASan the call below may write to freed memory and corrupt
4318 // its metadata. See
4319 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
4320 int res = REAL(getresuid)(ruid, euid, suid);
4321 if (res >= 0) {
4322 if (ruid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ruid, uid_t_sz);
4323 if (euid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, euid, uid_t_sz);
4324 if (suid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, suid, uid_t_sz);
4325 }
4326 return res;
4327}
4328INTERCEPTOR(int, getresgid, void *rgid, void *egid, void *sgid) {
4329 void *ctx;
4330 COMMON_INTERCEPTOR_ENTER(ctx, getresgid, rgid, egid, sgid);
92a42be0
SL
4331 // FIXME: under ASan the call below may write to freed memory and corrupt
4332 // its metadata. See
4333 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
4334 int res = REAL(getresgid)(rgid, egid, sgid);
4335 if (res >= 0) {
4336 if (rgid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rgid, gid_t_sz);
4337 if (egid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, egid, gid_t_sz);
4338 if (sgid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sgid, gid_t_sz);
4339 }
4340 return res;
4341}
4342#define INIT_GETRESID \
4343 COMMON_INTERCEPT_FUNCTION(getresuid); \
4344 COMMON_INTERCEPT_FUNCTION(getresgid);
4345#else
4346#define INIT_GETRESID
4347#endif
4348
4349#if SANITIZER_INTERCEPT_GETIFADDRS
4350// As long as getifaddrs()/freeifaddrs() use calloc()/free(), we don't need to
4351// intercept freeifaddrs(). If that ceases to be the case, we might need to
4352// intercept it to poison the memory again.
4353INTERCEPTOR(int, getifaddrs, __sanitizer_ifaddrs **ifap) {
4354 void *ctx;
4355 COMMON_INTERCEPTOR_ENTER(ctx, getifaddrs, ifap);
92a42be0
SL
4356 // FIXME: under ASan the call below may write to freed memory and corrupt
4357 // its metadata. See
4358 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
4359 int res = REAL(getifaddrs)(ifap);
4360 if (res == 0 && ifap) {
4361 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifap, sizeof(void *));
4362 __sanitizer_ifaddrs *p = *ifap;
4363 while (p) {
4364 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(__sanitizer_ifaddrs));
4365 if (p->ifa_name)
4366 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_name,
4367 REAL(strlen)(p->ifa_name) + 1);
4368 if (p->ifa_addr)
4369 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_addr, struct_sockaddr_sz);
4370 if (p->ifa_netmask)
4371 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_netmask, struct_sockaddr_sz);
4372 // On Linux this is a union, but the other member also points to a
4373 // struct sockaddr, so the following is sufficient.
4374 if (p->ifa_dstaddr)
4375 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_dstaddr, struct_sockaddr_sz);
4376 // FIXME(smatveev): Unpoison p->ifa_data as well.
4377 p = p->ifa_next;
4378 }
4379 }
4380 return res;
4381}
4382#define INIT_GETIFADDRS \
4383 COMMON_INTERCEPT_FUNCTION(getifaddrs);
4384#else
4385#define INIT_GETIFADDRS
4386#endif
4387
4388#if SANITIZER_INTERCEPT_IF_INDEXTONAME
4389INTERCEPTOR(char *, if_indextoname, unsigned int ifindex, char* ifname) {
4390 void *ctx;
4391 COMMON_INTERCEPTOR_ENTER(ctx, if_indextoname, ifindex, ifname);
92a42be0
SL
4392 // FIXME: under ASan the call below may write to freed memory and corrupt
4393 // its metadata. See
4394 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
4395 char *res = REAL(if_indextoname)(ifindex, ifname);
4396 if (res && ifname)
4397 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifname, REAL(strlen)(ifname) + 1);
4398 return res;
4399}
4400INTERCEPTOR(unsigned int, if_nametoindex, const char* ifname) {
4401 void *ctx;
4402 COMMON_INTERCEPTOR_ENTER(ctx, if_nametoindex, ifname);
4403 if (ifname)
4404 COMMON_INTERCEPTOR_READ_RANGE(ctx, ifname, REAL(strlen)(ifname) + 1);
4405 return REAL(if_nametoindex)(ifname);
4406}
4407#define INIT_IF_INDEXTONAME \
4408 COMMON_INTERCEPT_FUNCTION(if_indextoname); \
4409 COMMON_INTERCEPT_FUNCTION(if_nametoindex);
4410#else
4411#define INIT_IF_INDEXTONAME
4412#endif
4413
4414#if SANITIZER_INTERCEPT_CAPGET
4415INTERCEPTOR(int, capget, void *hdrp, void *datap) {
4416 void *ctx;
4417 COMMON_INTERCEPTOR_ENTER(ctx, capget, hdrp, datap);
4418 if (hdrp)
4419 COMMON_INTERCEPTOR_READ_RANGE(ctx, hdrp, __user_cap_header_struct_sz);
92a42be0
SL
4420 // FIXME: under ASan the call below may write to freed memory and corrupt
4421 // its metadata. See
4422 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
4423 int res = REAL(capget)(hdrp, datap);
4424 if (res == 0 && datap)
4425 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, datap, __user_cap_data_struct_sz);
4426 // We can also return -1 and write to hdrp->version if the version passed in
4427 // hdrp->version is unsupported. But that's not a trivial condition to check,
4428 // and anyway COMMON_INTERCEPTOR_READ_RANGE protects us to some extent.
4429 return res;
4430}
4431INTERCEPTOR(int, capset, void *hdrp, const void *datap) {
4432 void *ctx;
4433 COMMON_INTERCEPTOR_ENTER(ctx, capset, hdrp, datap);
4434 if (hdrp)
4435 COMMON_INTERCEPTOR_READ_RANGE(ctx, hdrp, __user_cap_header_struct_sz);
4436 if (datap)
4437 COMMON_INTERCEPTOR_READ_RANGE(ctx, datap, __user_cap_data_struct_sz);
4438 return REAL(capset)(hdrp, datap);
4439}
4440#define INIT_CAPGET \
4441 COMMON_INTERCEPT_FUNCTION(capget); \
4442 COMMON_INTERCEPT_FUNCTION(capset);
4443#else
4444#define INIT_CAPGET
4445#endif
4446
4447#if SANITIZER_INTERCEPT_AEABI_MEM
92a42be0
SL
4448DECLARE_REAL_AND_INTERCEPTOR(void *, memmove, void *, const void *, uptr)
4449DECLARE_REAL_AND_INTERCEPTOR(void *, memcpy, void *, const void *, uptr)
4450DECLARE_REAL_AND_INTERCEPTOR(void *, memset, void *, int, uptr)
1a4d82fc
JJ
4451
4452INTERCEPTOR(void *, __aeabi_memmove, void *to, const void *from, uptr size) {
4453 return WRAP(memmove)(to, from, size);
4454}
4455INTERCEPTOR(void *, __aeabi_memmove4, void *to, const void *from, uptr size) {
4456 return WRAP(memmove)(to, from, size);
4457}
4458INTERCEPTOR(void *, __aeabi_memmove8, void *to, const void *from, uptr size) {
4459 return WRAP(memmove)(to, from, size);
4460}
4461INTERCEPTOR(void *, __aeabi_memcpy, void *to, const void *from, uptr size) {
4462 return WRAP(memcpy)(to, from, size);
4463}
4464INTERCEPTOR(void *, __aeabi_memcpy4, void *to, const void *from, uptr size) {
4465 return WRAP(memcpy)(to, from, size);
4466}
4467INTERCEPTOR(void *, __aeabi_memcpy8, void *to, const void *from, uptr size) {
4468 return WRAP(memcpy)(to, from, size);
4469}
4470// Note the argument order.
4471INTERCEPTOR(void *, __aeabi_memset, void *block, uptr size, int c) {
4472 return WRAP(memset)(block, c, size);
4473}
4474INTERCEPTOR(void *, __aeabi_memset4, void *block, uptr size, int c) {
4475 return WRAP(memset)(block, c, size);
4476}
4477INTERCEPTOR(void *, __aeabi_memset8, void *block, uptr size, int c) {
4478 return WRAP(memset)(block, c, size);
4479}
4480INTERCEPTOR(void *, __aeabi_memclr, void *block, uptr size) {
4481 return WRAP(memset)(block, 0, size);
4482}
4483INTERCEPTOR(void *, __aeabi_memclr4, void *block, uptr size) {
4484 return WRAP(memset)(block, 0, size);
4485}
4486INTERCEPTOR(void *, __aeabi_memclr8, void *block, uptr size) {
4487 return WRAP(memset)(block, 0, size);
4488}
4489#define INIT_AEABI_MEM \
4490 COMMON_INTERCEPT_FUNCTION(__aeabi_memmove); \
4491 COMMON_INTERCEPT_FUNCTION(__aeabi_memmove4); \
4492 COMMON_INTERCEPT_FUNCTION(__aeabi_memmove8); \
4493 COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy); \
4494 COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy4); \
4495 COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy8); \
4496 COMMON_INTERCEPT_FUNCTION(__aeabi_memset); \
4497 COMMON_INTERCEPT_FUNCTION(__aeabi_memset4); \
4498 COMMON_INTERCEPT_FUNCTION(__aeabi_memset8); \
4499 COMMON_INTERCEPT_FUNCTION(__aeabi_memclr); \
4500 COMMON_INTERCEPT_FUNCTION(__aeabi_memclr4); \
4501 COMMON_INTERCEPT_FUNCTION(__aeabi_memclr8);
4502#else
4503#define INIT_AEABI_MEM
4504#endif // SANITIZER_INTERCEPT_AEABI_MEM
4505
4506#if SANITIZER_INTERCEPT___BZERO
4507DECLARE_REAL_AND_INTERCEPTOR(void *, memset, void *, int, uptr);
4508
4509INTERCEPTOR(void *, __bzero, void *block, uptr size) {
4510 return WRAP(memset)(block, 0, size);
4511}
4512#define INIT___BZERO COMMON_INTERCEPT_FUNCTION(__bzero);
4513#else
4514#define INIT___BZERO
4515#endif // SANITIZER_INTERCEPT___BZERO
4516
4517#if SANITIZER_INTERCEPT_FTIME
4518INTERCEPTOR(int, ftime, __sanitizer_timeb *tp) {
4519 void *ctx;
4520 COMMON_INTERCEPTOR_ENTER(ctx, ftime, tp);
92a42be0
SL
4521 // FIXME: under ASan the call below may write to freed memory and corrupt
4522 // its metadata. See
4523 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
4524 int res = REAL(ftime)(tp);
4525 if (tp)
4526 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, sizeof(*tp));
4527 return res;
4528}
4529#define INIT_FTIME COMMON_INTERCEPT_FUNCTION(ftime);
4530#else
4531#define INIT_FTIME
4532#endif // SANITIZER_INTERCEPT_FTIME
4533
4534#if SANITIZER_INTERCEPT_XDR
4535INTERCEPTOR(void, xdrmem_create, __sanitizer_XDR *xdrs, uptr addr,
4536 unsigned size, int op) {
4537 void *ctx;
4538 COMMON_INTERCEPTOR_ENTER(ctx, xdrmem_create, xdrs, addr, size, op);
92a42be0
SL
4539 // FIXME: under ASan the call below may write to freed memory and corrupt
4540 // its metadata. See
4541 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
4542 REAL(xdrmem_create)(xdrs, addr, size, op);
4543 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdrs, sizeof(*xdrs));
1a4d82fc
JJ
4544 if (op == __sanitizer_XDR_ENCODE) {
4545 // It's not obvious how much data individual xdr_ routines write.
4546 // Simply unpoison the entire target buffer in advance.
4547 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (void *)addr, size);
4548 }
4549}
4550
4551INTERCEPTOR(void, xdrstdio_create, __sanitizer_XDR *xdrs, void *file, int op) {
4552 void *ctx;
4553 COMMON_INTERCEPTOR_ENTER(ctx, xdrstdio_create, xdrs, file, op);
92a42be0
SL
4554 // FIXME: under ASan the call below may write to freed memory and corrupt
4555 // its metadata. See
4556 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
4557 REAL(xdrstdio_create)(xdrs, file, op);
4558 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdrs, sizeof(*xdrs));
1a4d82fc
JJ
4559}
4560
92a42be0
SL
4561// FIXME: under ASan the call below may write to freed memory and corrupt
4562// its metadata. See
4563// https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
4564#define XDR_INTERCEPTOR(F, T) \
4565 INTERCEPTOR(int, F, __sanitizer_XDR *xdrs, T *p) { \
4566 void *ctx; \
4567 COMMON_INTERCEPTOR_ENTER(ctx, F, xdrs, p); \
4568 if (p && xdrs->x_op == __sanitizer_XDR_ENCODE) \
4569 COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p)); \
4570 int res = REAL(F)(xdrs, p); \
4571 if (res && p && xdrs->x_op == __sanitizer_XDR_DECODE) \
4572 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); \
4573 return res; \
4574 }
4575
4576XDR_INTERCEPTOR(xdr_short, short)
4577XDR_INTERCEPTOR(xdr_u_short, unsigned short)
4578XDR_INTERCEPTOR(xdr_int, int)
4579XDR_INTERCEPTOR(xdr_u_int, unsigned)
4580XDR_INTERCEPTOR(xdr_long, long)
4581XDR_INTERCEPTOR(xdr_u_long, unsigned long)
4582XDR_INTERCEPTOR(xdr_hyper, long long)
4583XDR_INTERCEPTOR(xdr_u_hyper, unsigned long long)
4584XDR_INTERCEPTOR(xdr_longlong_t, long long)
4585XDR_INTERCEPTOR(xdr_u_longlong_t, unsigned long long)
4586XDR_INTERCEPTOR(xdr_int8_t, u8)
4587XDR_INTERCEPTOR(xdr_uint8_t, u8)
4588XDR_INTERCEPTOR(xdr_int16_t, u16)
4589XDR_INTERCEPTOR(xdr_uint16_t, u16)
4590XDR_INTERCEPTOR(xdr_int32_t, u32)
4591XDR_INTERCEPTOR(xdr_uint32_t, u32)
4592XDR_INTERCEPTOR(xdr_int64_t, u64)
4593XDR_INTERCEPTOR(xdr_uint64_t, u64)
4594XDR_INTERCEPTOR(xdr_quad_t, long long)
4595XDR_INTERCEPTOR(xdr_u_quad_t, unsigned long long)
4596XDR_INTERCEPTOR(xdr_bool, bool)
4597XDR_INTERCEPTOR(xdr_enum, int)
4598XDR_INTERCEPTOR(xdr_char, char)
4599XDR_INTERCEPTOR(xdr_u_char, unsigned char)
4600XDR_INTERCEPTOR(xdr_float, float)
4601XDR_INTERCEPTOR(xdr_double, double)
4602
4603// FIXME: intercept xdr_array, opaque, union, vector, reference, pointer,
4604// wrapstring, sizeof
4605
4606INTERCEPTOR(int, xdr_bytes, __sanitizer_XDR *xdrs, char **p, unsigned *sizep,
4607 unsigned maxsize) {
4608 void *ctx;
4609 COMMON_INTERCEPTOR_ENTER(ctx, xdr_bytes, xdrs, p, sizep, maxsize);
4610 if (p && sizep && xdrs->x_op == __sanitizer_XDR_ENCODE) {
4611 COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p));
4612 COMMON_INTERCEPTOR_READ_RANGE(ctx, sizep, sizeof(*sizep));
4613 COMMON_INTERCEPTOR_READ_RANGE(ctx, *p, *sizep);
4614 }
92a42be0
SL
4615 // FIXME: under ASan the call below may write to freed memory and corrupt
4616 // its metadata. See
4617 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
4618 int res = REAL(xdr_bytes)(xdrs, p, sizep, maxsize);
4619 if (p && sizep && xdrs->x_op == __sanitizer_XDR_DECODE) {
4620 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
4621 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizep, sizeof(*sizep));
4622 if (res && *p && *sizep) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, *sizep);
4623 }
4624 return res;
4625}
4626
4627INTERCEPTOR(int, xdr_string, __sanitizer_XDR *xdrs, char **p,
4628 unsigned maxsize) {
4629 void *ctx;
4630 COMMON_INTERCEPTOR_ENTER(ctx, xdr_string, xdrs, p, maxsize);
4631 if (p && xdrs->x_op == __sanitizer_XDR_ENCODE) {
4632 COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p));
4633 COMMON_INTERCEPTOR_READ_RANGE(ctx, *p, REAL(strlen)(*p) + 1);
4634 }
92a42be0
SL
4635 // FIXME: under ASan the call below may write to freed memory and corrupt
4636 // its metadata. See
4637 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
4638 int res = REAL(xdr_string)(xdrs, p, maxsize);
4639 if (p && xdrs->x_op == __sanitizer_XDR_DECODE) {
4640 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
4641 if (res && *p)
4642 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1);
4643 }
4644 return res;
4645}
4646
4647#define INIT_XDR \
4648 COMMON_INTERCEPT_FUNCTION(xdrmem_create); \
4649 COMMON_INTERCEPT_FUNCTION(xdrstdio_create); \
4650 COMMON_INTERCEPT_FUNCTION(xdr_short); \
4651 COMMON_INTERCEPT_FUNCTION(xdr_u_short); \
4652 COMMON_INTERCEPT_FUNCTION(xdr_int); \
4653 COMMON_INTERCEPT_FUNCTION(xdr_u_int); \
4654 COMMON_INTERCEPT_FUNCTION(xdr_long); \
4655 COMMON_INTERCEPT_FUNCTION(xdr_u_long); \
4656 COMMON_INTERCEPT_FUNCTION(xdr_hyper); \
4657 COMMON_INTERCEPT_FUNCTION(xdr_u_hyper); \
4658 COMMON_INTERCEPT_FUNCTION(xdr_longlong_t); \
4659 COMMON_INTERCEPT_FUNCTION(xdr_u_longlong_t); \
4660 COMMON_INTERCEPT_FUNCTION(xdr_int8_t); \
4661 COMMON_INTERCEPT_FUNCTION(xdr_uint8_t); \
4662 COMMON_INTERCEPT_FUNCTION(xdr_int16_t); \
4663 COMMON_INTERCEPT_FUNCTION(xdr_uint16_t); \
4664 COMMON_INTERCEPT_FUNCTION(xdr_int32_t); \
4665 COMMON_INTERCEPT_FUNCTION(xdr_uint32_t); \
4666 COMMON_INTERCEPT_FUNCTION(xdr_int64_t); \
4667 COMMON_INTERCEPT_FUNCTION(xdr_uint64_t); \
4668 COMMON_INTERCEPT_FUNCTION(xdr_quad_t); \
4669 COMMON_INTERCEPT_FUNCTION(xdr_u_quad_t); \
4670 COMMON_INTERCEPT_FUNCTION(xdr_bool); \
4671 COMMON_INTERCEPT_FUNCTION(xdr_enum); \
4672 COMMON_INTERCEPT_FUNCTION(xdr_char); \
4673 COMMON_INTERCEPT_FUNCTION(xdr_u_char); \
4674 COMMON_INTERCEPT_FUNCTION(xdr_float); \
4675 COMMON_INTERCEPT_FUNCTION(xdr_double); \
4676 COMMON_INTERCEPT_FUNCTION(xdr_bytes); \
4677 COMMON_INTERCEPT_FUNCTION(xdr_string);
4678#else
4679#define INIT_XDR
4680#endif // SANITIZER_INTERCEPT_XDR
4681
4682#if SANITIZER_INTERCEPT_TSEARCH
4683INTERCEPTOR(void *, tsearch, void *key, void **rootp,
4684 int (*compar)(const void *, const void *)) {
4685 void *ctx;
4686 COMMON_INTERCEPTOR_ENTER(ctx, tsearch, key, rootp, compar);
92a42be0
SL
4687 // FIXME: under ASan the call below may write to freed memory and corrupt
4688 // its metadata. See
4689 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
4690 void *res = REAL(tsearch)(key, rootp, compar);
4691 if (res && *(void **)res == key)
4692 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(void *));
4693 return res;
4694}
4695#define INIT_TSEARCH COMMON_INTERCEPT_FUNCTION(tsearch);
4696#else
4697#define INIT_TSEARCH
4698#endif
4699
4700#if SANITIZER_INTERCEPT_LIBIO_INTERNALS || SANITIZER_INTERCEPT_FOPEN || \
4701 SANITIZER_INTERCEPT_OPEN_MEMSTREAM
4702void unpoison_file(__sanitizer_FILE *fp) {
92a42be0 4703#if SANITIZER_HAS_STRUCT_FILE
1a4d82fc
JJ
4704 COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp, sizeof(*fp));
4705 if (fp->_IO_read_base && fp->_IO_read_base < fp->_IO_read_end)
4706 COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp->_IO_read_base,
4707 fp->_IO_read_end - fp->_IO_read_base);
92a42be0 4708#endif // SANITIZER_HAS_STRUCT_FILE
1a4d82fc
JJ
4709}
4710#endif
4711
4712#if SANITIZER_INTERCEPT_LIBIO_INTERNALS
4713// These guys are called when a .c source is built with -O2.
4714INTERCEPTOR(int, __uflow, __sanitizer_FILE *fp) {
4715 void *ctx;
4716 COMMON_INTERCEPTOR_ENTER(ctx, __uflow, fp);
4717 int res = REAL(__uflow)(fp);
4718 unpoison_file(fp);
4719 return res;
4720}
4721INTERCEPTOR(int, __underflow, __sanitizer_FILE *fp) {
4722 void *ctx;
4723 COMMON_INTERCEPTOR_ENTER(ctx, __underflow, fp);
4724 int res = REAL(__underflow)(fp);
4725 unpoison_file(fp);
4726 return res;
4727}
4728INTERCEPTOR(int, __overflow, __sanitizer_FILE *fp, int ch) {
4729 void *ctx;
4730 COMMON_INTERCEPTOR_ENTER(ctx, __overflow, fp, ch);
4731 int res = REAL(__overflow)(fp, ch);
4732 unpoison_file(fp);
4733 return res;
4734}
4735INTERCEPTOR(int, __wuflow, __sanitizer_FILE *fp) {
4736 void *ctx;
4737 COMMON_INTERCEPTOR_ENTER(ctx, __wuflow, fp);
4738 int res = REAL(__wuflow)(fp);
4739 unpoison_file(fp);
4740 return res;
4741}
4742INTERCEPTOR(int, __wunderflow, __sanitizer_FILE *fp) {
4743 void *ctx;
4744 COMMON_INTERCEPTOR_ENTER(ctx, __wunderflow, fp);
4745 int res = REAL(__wunderflow)(fp);
4746 unpoison_file(fp);
4747 return res;
4748}
4749INTERCEPTOR(int, __woverflow, __sanitizer_FILE *fp, int ch) {
4750 void *ctx;
4751 COMMON_INTERCEPTOR_ENTER(ctx, __woverflow, fp, ch);
4752 int res = REAL(__woverflow)(fp, ch);
4753 unpoison_file(fp);
4754 return res;
4755}
4756#define INIT_LIBIO_INTERNALS \
4757 COMMON_INTERCEPT_FUNCTION(__uflow); \
4758 COMMON_INTERCEPT_FUNCTION(__underflow); \
4759 COMMON_INTERCEPT_FUNCTION(__overflow); \
4760 COMMON_INTERCEPT_FUNCTION(__wuflow); \
4761 COMMON_INTERCEPT_FUNCTION(__wunderflow); \
4762 COMMON_INTERCEPT_FUNCTION(__woverflow);
4763#else
4764#define INIT_LIBIO_INTERNALS
4765#endif
4766
4767#if SANITIZER_INTERCEPT_FOPEN
4768INTERCEPTOR(__sanitizer_FILE *, fopen, const char *path, const char *mode) {
4769 void *ctx;
4770 COMMON_INTERCEPTOR_ENTER(ctx, fopen, path, mode);
4771 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
4772 COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
4773 __sanitizer_FILE *res = REAL(fopen)(path, mode);
4774 COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
4775 if (res) unpoison_file(res);
4776 return res;
4777}
1a4d82fc
JJ
4778INTERCEPTOR(__sanitizer_FILE *, fdopen, int fd, const char *mode) {
4779 void *ctx;
4780 COMMON_INTERCEPTOR_ENTER(ctx, fdopen, fd, mode);
4781 COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
4782 __sanitizer_FILE *res = REAL(fdopen)(fd, mode);
4783 if (res) unpoison_file(res);
4784 return res;
4785}
4786INTERCEPTOR(__sanitizer_FILE *, freopen, const char *path, const char *mode,
4787 __sanitizer_FILE *fp) {
4788 void *ctx;
4789 COMMON_INTERCEPTOR_ENTER(ctx, freopen, path, mode, fp);
92a42be0 4790 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
1a4d82fc
JJ
4791 COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
4792 COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
4793 __sanitizer_FILE *res = REAL(freopen)(path, mode, fp);
4794 COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
4795 if (res) unpoison_file(res);
4796 return res;
4797}
92a42be0
SL
4798#define INIT_FOPEN \
4799 COMMON_INTERCEPT_FUNCTION(fopen); \
4800 COMMON_INTERCEPT_FUNCTION(fdopen); \
4801 COMMON_INTERCEPT_FUNCTION(freopen);
4802#else
4803#define INIT_FOPEN
4804#endif
4805
4806#if SANITIZER_INTERCEPT_FOPEN64
4807INTERCEPTOR(__sanitizer_FILE *, fopen64, const char *path, const char *mode) {
4808 void *ctx;
4809 COMMON_INTERCEPTOR_ENTER(ctx, fopen64, path, mode);
4810 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
4811 COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
4812 __sanitizer_FILE *res = REAL(fopen64)(path, mode);
4813 COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
4814 if (res) unpoison_file(res);
4815 return res;
4816}
1a4d82fc
JJ
4817INTERCEPTOR(__sanitizer_FILE *, freopen64, const char *path, const char *mode,
4818 __sanitizer_FILE *fp) {
4819 void *ctx;
4820 COMMON_INTERCEPTOR_ENTER(ctx, freopen64, path, mode, fp);
92a42be0 4821 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
1a4d82fc
JJ
4822 COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
4823 COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
4824 __sanitizer_FILE *res = REAL(freopen64)(path, mode, fp);
4825 COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
4826 if (res) unpoison_file(res);
4827 return res;
4828}
92a42be0 4829#define INIT_FOPEN64 \
1a4d82fc 4830 COMMON_INTERCEPT_FUNCTION(fopen64); \
1a4d82fc
JJ
4831 COMMON_INTERCEPT_FUNCTION(freopen64);
4832#else
92a42be0 4833#define INIT_FOPEN64
1a4d82fc
JJ
4834#endif
4835
4836#if SANITIZER_INTERCEPT_OPEN_MEMSTREAM
4837INTERCEPTOR(__sanitizer_FILE *, open_memstream, char **ptr, SIZE_T *sizeloc) {
4838 void *ctx;
4839 COMMON_INTERCEPTOR_ENTER(ctx, open_memstream, ptr, sizeloc);
92a42be0
SL
4840 // FIXME: under ASan the call below may write to freed memory and corrupt
4841 // its metadata. See
4842 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
4843 __sanitizer_FILE *res = REAL(open_memstream)(ptr, sizeloc);
4844 if (res) {
4845 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, sizeof(*ptr));
4846 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizeloc, sizeof(*sizeloc));
4847 unpoison_file(res);
92a42be0
SL
4848 FileMetadata file = {ptr, sizeloc};
4849 SetInterceptorMetadata(res, file);
1a4d82fc
JJ
4850 }
4851 return res;
4852}
4853INTERCEPTOR(__sanitizer_FILE *, open_wmemstream, wchar_t **ptr,
4854 SIZE_T *sizeloc) {
4855 void *ctx;
4856 COMMON_INTERCEPTOR_ENTER(ctx, open_wmemstream, ptr, sizeloc);
4857 __sanitizer_FILE *res = REAL(open_wmemstream)(ptr, sizeloc);
4858 if (res) {
4859 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, sizeof(*ptr));
4860 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizeloc, sizeof(*sizeloc));
4861 unpoison_file(res);
92a42be0
SL
4862 FileMetadata file = {(char **)ptr, sizeloc};
4863 SetInterceptorMetadata(res, file);
1a4d82fc
JJ
4864 }
4865 return res;
4866}
4867INTERCEPTOR(__sanitizer_FILE *, fmemopen, void *buf, SIZE_T size,
4868 const char *mode) {
4869 void *ctx;
4870 COMMON_INTERCEPTOR_ENTER(ctx, fmemopen, buf, size, mode);
92a42be0
SL
4871 // FIXME: under ASan the call below may write to freed memory and corrupt
4872 // its metadata. See
4873 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1a4d82fc
JJ
4874 __sanitizer_FILE *res = REAL(fmemopen)(buf, size, mode);
4875 if (res) unpoison_file(res);
4876 return res;
4877}
4878#define INIT_OPEN_MEMSTREAM \
4879 COMMON_INTERCEPT_FUNCTION(open_memstream); \
4880 COMMON_INTERCEPT_FUNCTION(open_wmemstream); \
4881 COMMON_INTERCEPT_FUNCTION(fmemopen);
4882#else
4883#define INIT_OPEN_MEMSTREAM
4884#endif
4885
92a42be0
SL
4886#if SANITIZER_INTERCEPT_OBSTACK
4887static void initialize_obstack(__sanitizer_obstack *obstack) {
4888 COMMON_INTERCEPTOR_INITIALIZE_RANGE(obstack, sizeof(*obstack));
4889 if (obstack->chunk)
4890 COMMON_INTERCEPTOR_INITIALIZE_RANGE(obstack->chunk,
4891 sizeof(*obstack->chunk));
4892}
4893
4894INTERCEPTOR(int, _obstack_begin_1, __sanitizer_obstack *obstack, int sz,
4895 int align, void *(*alloc_fn)(uptr arg, uptr sz),
4896 void (*free_fn)(uptr arg, void *p)) {
4897 void *ctx;
4898 COMMON_INTERCEPTOR_ENTER(ctx, _obstack_begin_1, obstack, sz, align, alloc_fn,
4899 free_fn);
4900 int res = REAL(_obstack_begin_1)(obstack, sz, align, alloc_fn, free_fn);
4901 if (res) initialize_obstack(obstack);
4902 return res;
4903}
4904INTERCEPTOR(int, _obstack_begin, __sanitizer_obstack *obstack, int sz,
4905 int align, void *(*alloc_fn)(uptr sz), void (*free_fn)(void *p)) {
4906 void *ctx;
4907 COMMON_INTERCEPTOR_ENTER(ctx, _obstack_begin, obstack, sz, align, alloc_fn,
4908 free_fn);
4909 int res = REAL(_obstack_begin)(obstack, sz, align, alloc_fn, free_fn);
4910 if (res) initialize_obstack(obstack);
4911 return res;
4912}
4913INTERCEPTOR(void, _obstack_newchunk, __sanitizer_obstack *obstack, int length) {
4914 void *ctx;
4915 COMMON_INTERCEPTOR_ENTER(ctx, _obstack_newchunk, obstack, length);
4916 REAL(_obstack_newchunk)(obstack, length);
4917 if (obstack->chunk)
4918 COMMON_INTERCEPTOR_INITIALIZE_RANGE(
4919 obstack->chunk, obstack->next_free - (char *)obstack->chunk);
4920}
4921#define INIT_OBSTACK \
4922 COMMON_INTERCEPT_FUNCTION(_obstack_begin_1); \
4923 COMMON_INTERCEPT_FUNCTION(_obstack_begin); \
4924 COMMON_INTERCEPT_FUNCTION(_obstack_newchunk);
4925#else
4926#define INIT_OBSTACK
4927#endif
4928
4929#if SANITIZER_INTERCEPT_FFLUSH
4930INTERCEPTOR(int, fflush, __sanitizer_FILE *fp) {
4931 void *ctx;
4932 COMMON_INTERCEPTOR_ENTER(ctx, fflush, fp);
4933 int res = REAL(fflush)(fp);
4934 // FIXME: handle fp == NULL
4935 if (fp) {
4936 const FileMetadata *m = GetInterceptorMetadata(fp);
4937 if (m) COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);
4938 }
4939 return res;
4940}
4941#define INIT_FFLUSH COMMON_INTERCEPT_FUNCTION(fflush);
4942#else
4943#define INIT_FFLUSH
4944#endif
4945
4946#if SANITIZER_INTERCEPT_FCLOSE
4947INTERCEPTOR(int, fclose, __sanitizer_FILE *fp) {
4948 void *ctx;
4949 COMMON_INTERCEPTOR_ENTER(ctx, fclose, fp);
4950 COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
4951 const FileMetadata *m = GetInterceptorMetadata(fp);
4952 int res = REAL(fclose)(fp);
4953 if (m) {
4954 COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);
4955 DeleteInterceptorMetadata(fp);
4956 }
4957 return res;
4958}
4959#define INIT_FCLOSE COMMON_INTERCEPT_FUNCTION(fclose);
4960#else
4961#define INIT_FCLOSE
4962#endif
4963
4964#if SANITIZER_INTERCEPT_DLOPEN_DLCLOSE
4965INTERCEPTOR(void*, dlopen, const char *filename, int flag) {
4966 void *ctx;
4967 COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlopen, filename, flag);
4968 if (filename) COMMON_INTERCEPTOR_READ_STRING(ctx, filename, 0);
4969 COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag);
4970 void *res = REAL(dlopen)(filename, flag);
4971 COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, res);
4972 return res;
4973}
4974
4975INTERCEPTOR(int, dlclose, void *handle) {
4976 void *ctx;
4977 COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlclose, handle);
4978 int res = REAL(dlclose)(handle);
4979 COMMON_INTERCEPTOR_LIBRARY_UNLOADED();
4980 return res;
4981}
4982#define INIT_DLOPEN_DLCLOSE \
4983 COMMON_INTERCEPT_FUNCTION(dlopen); \
4984 COMMON_INTERCEPT_FUNCTION(dlclose);
4985#else
4986#define INIT_DLOPEN_DLCLOSE
4987#endif
4988
4989#if SANITIZER_INTERCEPT_GETPASS
4990INTERCEPTOR(char *, getpass, const char *prompt) {
4991 void *ctx;
4992 COMMON_INTERCEPTOR_ENTER(ctx, getpass, prompt);
4993 if (prompt)
4994 COMMON_INTERCEPTOR_READ_RANGE(ctx, prompt, REAL(strlen)(prompt)+1);
4995 char *res = REAL(getpass)(prompt);
4996 if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res)+1);
4997 return res;
4998}
4999
5000#define INIT_GETPASS COMMON_INTERCEPT_FUNCTION(getpass);
5001#else
5002#define INIT_GETPASS
5003#endif
5004
5005#if SANITIZER_INTERCEPT_TIMERFD
5006INTERCEPTOR(int, timerfd_settime, int fd, int flags, void *new_value,
5007 void *old_value) {
5008 void *ctx;
5009 COMMON_INTERCEPTOR_ENTER(ctx, timerfd_settime, fd, flags, new_value,
5010 old_value);
5011 COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerspec_sz);
5012 int res = REAL(timerfd_settime)(fd, flags, new_value, old_value);
5013 if (res != -1 && old_value)
5014 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerspec_sz);
5015 return res;
5016}
5017
5018INTERCEPTOR(int, timerfd_gettime, int fd, void *curr_value) {
5019 void *ctx;
5020 COMMON_INTERCEPTOR_ENTER(ctx, timerfd_gettime, fd, curr_value);
5021 int res = REAL(timerfd_gettime)(fd, curr_value);
5022 if (res != -1 && curr_value)
5023 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerspec_sz);
5024 return res;
5025}
5026#define INIT_TIMERFD \
5027 COMMON_INTERCEPT_FUNCTION(timerfd_settime); \
5028 COMMON_INTERCEPT_FUNCTION(timerfd_gettime);
5029#else
5030#define INIT_TIMERFD
5031#endif
5032
5033#if SANITIZER_INTERCEPT_MLOCKX
5034// Linux kernel has a bug that leads to kernel deadlock if a process
5035// maps TBs of memory and then calls mlock().
5036static void MlockIsUnsupported() {
5037 static atomic_uint8_t printed;
5038 if (atomic_exchange(&printed, 1, memory_order_relaxed))
5039 return;
5040 VPrintf(1, "%s ignores mlock/mlockall/munlock/munlockall\n",
5041 SanitizerToolName);
5042}
5043
5044INTERCEPTOR(int, mlock, const void *addr, uptr len) {
5045 MlockIsUnsupported();
5046 return 0;
5047}
5048
5049INTERCEPTOR(int, munlock, const void *addr, uptr len) {
5050 MlockIsUnsupported();
5051 return 0;
5052}
5053
5054INTERCEPTOR(int, mlockall, int flags) {
5055 MlockIsUnsupported();
5056 return 0;
5057}
5058
5059INTERCEPTOR(int, munlockall, void) {
5060 MlockIsUnsupported();
5061 return 0;
5062}
5063
5064#define INIT_MLOCKX \
5065 COMMON_INTERCEPT_FUNCTION(mlock); \
5066 COMMON_INTERCEPT_FUNCTION(munlock); \
5067 COMMON_INTERCEPT_FUNCTION(mlockall); \
5068 COMMON_INTERCEPT_FUNCTION(munlockall);
5069
5070#else
5071#define INIT_MLOCKX
5072#endif // SANITIZER_INTERCEPT_MLOCKX
5073
5074#if SANITIZER_INTERCEPT_FOPENCOOKIE
5075struct WrappedCookie {
5076 void *real_cookie;
5077 __sanitizer_cookie_io_functions_t real_io_funcs;
5078};
5079
5080static uptr wrapped_read(void *cookie, char *buf, uptr size) {
5081 COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
5082 WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;
5083 __sanitizer_cookie_io_read real_read = wrapped_cookie->real_io_funcs.read;
5084 return real_read ? real_read(wrapped_cookie->real_cookie, buf, size) : 0;
5085}
5086
5087static uptr wrapped_write(void *cookie, const char *buf, uptr size) {
5088 COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
5089 WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;
5090 __sanitizer_cookie_io_write real_write = wrapped_cookie->real_io_funcs.write;
5091 return real_write ? real_write(wrapped_cookie->real_cookie, buf, size) : size;
5092}
5093
5094static int wrapped_seek(void *cookie, u64 *offset, int whence) {
5095 COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
5096 COMMON_INTERCEPTOR_INITIALIZE_RANGE(offset, sizeof(*offset));
5097 WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;
5098 __sanitizer_cookie_io_seek real_seek = wrapped_cookie->real_io_funcs.seek;
5099 return real_seek ? real_seek(wrapped_cookie->real_cookie, offset, whence)
5100 : -1;
5101}
5102
5103static int wrapped_close(void *cookie) {
5104 COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
5105 WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;
5106 __sanitizer_cookie_io_close real_close = wrapped_cookie->real_io_funcs.close;
5107 int res = real_close ? real_close(wrapped_cookie->real_cookie) : 0;
5108 InternalFree(wrapped_cookie);
5109 return res;
5110}
5111
5112INTERCEPTOR(__sanitizer_FILE *, fopencookie, void *cookie, const char *mode,
5113 __sanitizer_cookie_io_functions_t io_funcs) {
5114 void *ctx;
5115 COMMON_INTERCEPTOR_ENTER(ctx, fopencookie, cookie, mode, io_funcs);
5116 WrappedCookie *wrapped_cookie =
5117 (WrappedCookie *)InternalAlloc(sizeof(WrappedCookie));
5118 wrapped_cookie->real_cookie = cookie;
5119 wrapped_cookie->real_io_funcs = io_funcs;
5120 __sanitizer_FILE *res =
5121 REAL(fopencookie)(wrapped_cookie, mode, {wrapped_read, wrapped_write,
5122 wrapped_seek, wrapped_close});
5123 return res;
5124}
5125
5126#define INIT_FOPENCOOKIE COMMON_INTERCEPT_FUNCTION(fopencookie);
5127#else
5128#define INIT_FOPENCOOKIE
5129#endif // SANITIZER_INTERCEPT_FOPENCOOKIE
5130
5131#if SANITIZER_INTERCEPT_SEM
5132INTERCEPTOR(int, sem_init, __sanitizer_sem_t *s, int pshared, unsigned value) {
5133 void *ctx;
5134 COMMON_INTERCEPTOR_ENTER(ctx, sem_init, s, pshared, value);
5135 // Workaround a bug in glibc's "old" semaphore implementation by
5136 // zero-initializing the sem_t contents. This has to be done here because
5137 // interceptors bind to the lowest symbols version by default, hitting the
5138 // buggy code path while the non-sanitized build of the same code works fine.
5139 REAL(memset)(s, 0, sizeof(*s));
5140 int res = REAL(sem_init)(s, pshared, value);
5141 return res;
5142}
5143
5144INTERCEPTOR(int, sem_destroy, __sanitizer_sem_t *s) {
5145 void *ctx;
5146 COMMON_INTERCEPTOR_ENTER(ctx, sem_destroy, s);
5147 int res = REAL(sem_destroy)(s);
5148 return res;
5149}
5150
5151INTERCEPTOR(int, sem_wait, __sanitizer_sem_t *s) {
5152 void *ctx;
5153 COMMON_INTERCEPTOR_ENTER(ctx, sem_wait, s);
5154 int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_wait)(s);
5155 if (res == 0) {
5156 COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);
5157 }
5158 return res;
5159}
5160
5161INTERCEPTOR(int, sem_trywait, __sanitizer_sem_t *s) {
5162 void *ctx;
5163 COMMON_INTERCEPTOR_ENTER(ctx, sem_trywait, s);
5164 int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_trywait)(s);
5165 if (res == 0) {
5166 COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);
5167 }
5168 return res;
5169}
5170
5171INTERCEPTOR(int, sem_timedwait, __sanitizer_sem_t *s, void *abstime) {
5172 void *ctx;
5173 COMMON_INTERCEPTOR_ENTER(ctx, sem_timedwait, s, abstime);
5174 COMMON_INTERCEPTOR_READ_RANGE(ctx, abstime, struct_timespec_sz);
5175 int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_timedwait)(s, abstime);
5176 if (res == 0) {
5177 COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);
5178 }
5179 return res;
5180}
5181
5182INTERCEPTOR(int, sem_post, __sanitizer_sem_t *s) {
5183 void *ctx;
5184 COMMON_INTERCEPTOR_ENTER(ctx, sem_post, s);
5185 COMMON_INTERCEPTOR_RELEASE(ctx, (uptr)s);
5186 int res = REAL(sem_post)(s);
5187 return res;
5188}
5189
5190INTERCEPTOR(int, sem_getvalue, __sanitizer_sem_t *s, int *sval) {
5191 void *ctx;
5192 COMMON_INTERCEPTOR_ENTER(ctx, sem_getvalue, s, sval);
5193 int res = REAL(sem_getvalue)(s, sval);
5194 if (res == 0) {
5195 COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);
5196 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sval, sizeof(*sval));
5197 }
5198 return res;
5199}
5200#define INIT_SEM \
5201 COMMON_INTERCEPT_FUNCTION(sem_init); \
5202 COMMON_INTERCEPT_FUNCTION(sem_destroy); \
5203 COMMON_INTERCEPT_FUNCTION(sem_wait); \
5204 COMMON_INTERCEPT_FUNCTION(sem_trywait); \
5205 COMMON_INTERCEPT_FUNCTION(sem_timedwait); \
5206 COMMON_INTERCEPT_FUNCTION(sem_post); \
5207 COMMON_INTERCEPT_FUNCTION(sem_getvalue);
5208#else
5209#define INIT_SEM
5210#endif // SANITIZER_INTERCEPT_SEM
5211
5212#if SANITIZER_INTERCEPT_PTHREAD_SETCANCEL
5213INTERCEPTOR(int, pthread_setcancelstate, int state, int *oldstate) {
5214 void *ctx;
5215 COMMON_INTERCEPTOR_ENTER(ctx, pthread_setcancelstate, state, oldstate);
5216 int res = REAL(pthread_setcancelstate)(state, oldstate);
5217 if (res == 0)
5218 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldstate, sizeof(*oldstate));
5219 return res;
5220}
5221
5222INTERCEPTOR(int, pthread_setcanceltype, int type, int *oldtype) {
5223 void *ctx;
5224 COMMON_INTERCEPTOR_ENTER(ctx, pthread_setcanceltype, type, oldtype);
5225 int res = REAL(pthread_setcanceltype)(type, oldtype);
5226 if (res == 0)
5227 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldtype, sizeof(*oldtype));
5228 return res;
5229}
5230#define INIT_PTHREAD_SETCANCEL \
5231 COMMON_INTERCEPT_FUNCTION(pthread_setcancelstate); \
5232 COMMON_INTERCEPT_FUNCTION(pthread_setcanceltype);
5233#else
5234#define INIT_PTHREAD_SETCANCEL
5235#endif
5236
5237#if SANITIZER_INTERCEPT_MINCORE
5238INTERCEPTOR(int, mincore, void *addr, uptr length, unsigned char *vec) {
5239 void *ctx;
5240 COMMON_INTERCEPTOR_ENTER(ctx, mincore, addr, length, vec);
5241 int res = REAL(mincore)(addr, length, vec);
5242 if (res == 0) {
5243 uptr page_size = GetPageSizeCached();
5244 uptr vec_size = ((length + page_size - 1) & (~(page_size - 1))) / page_size;
5245 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, vec, vec_size);
5246 }
5247 return res;
5248}
5249#define INIT_MINCORE COMMON_INTERCEPT_FUNCTION(mincore);
5250#else
5251#define INIT_MINCORE
5252#endif
5253
5254#if SANITIZER_INTERCEPT_PROCESS_VM_READV
5255INTERCEPTOR(SSIZE_T, process_vm_readv, int pid, __sanitizer_iovec *local_iov,
5256 uptr liovcnt, __sanitizer_iovec *remote_iov, uptr riovcnt,
5257 uptr flags) {
5258 void *ctx;
5259 COMMON_INTERCEPTOR_ENTER(ctx, process_vm_readv, pid, local_iov, liovcnt,
5260 remote_iov, riovcnt, flags);
5261 SSIZE_T res = REAL(process_vm_readv)(pid, local_iov, liovcnt, remote_iov,
5262 riovcnt, flags);
5263 if (res > 0)
5264 write_iovec(ctx, local_iov, liovcnt, res);
5265 return res;
5266}
5267
5268INTERCEPTOR(SSIZE_T, process_vm_writev, int pid, __sanitizer_iovec *local_iov,
5269 uptr liovcnt, __sanitizer_iovec *remote_iov, uptr riovcnt,
5270 uptr flags) {
5271 void *ctx;
5272 COMMON_INTERCEPTOR_ENTER(ctx, process_vm_writev, pid, local_iov, liovcnt,
5273 remote_iov, riovcnt, flags);
5274 SSIZE_T res = REAL(process_vm_writev)(pid, local_iov, liovcnt, remote_iov,
5275 riovcnt, flags);
5276 if (res > 0)
5277 read_iovec(ctx, local_iov, liovcnt, res);
5278 return res;
5279}
5280#define INIT_PROCESS_VM_READV \
5281 COMMON_INTERCEPT_FUNCTION(process_vm_readv); \
5282 COMMON_INTERCEPT_FUNCTION(process_vm_writev);
5283#else
5284#define INIT_PROCESS_VM_READV
5285#endif
5286
5287static void InitializeCommonInterceptors() {
5288 static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1];
5289 interceptor_metadata_map = new((void *)&metadata_mem) MetadataHashMap();
5290
5291 INIT_TEXTDOMAIN;
5292 INIT_STRCMP;
5293 INIT_STRNCMP;
5294 INIT_STRCASECMP;
5295 INIT_STRNCASECMP;
5296 INIT_STRSTR;
5297 INIT_STRCASESTR;
5298 INIT_STRSPN;
5299 INIT_STRPBRK;
5300 INIT_MEMCHR;
5301 INIT_MEMCMP;
5302 INIT_MEMRCHR;
5303 INIT_READ;
5304 INIT_PREAD;
5305 INIT_PREAD64;
5306 INIT_READV;
5307 INIT_PREADV;
5308 INIT_PREADV64;
5309 INIT_WRITE;
5310 INIT_PWRITE;
5311 INIT_PWRITE64;
5312 INIT_WRITEV;
5313 INIT_PWRITEV;
5314 INIT_PWRITEV64;
5315 INIT_PRCTL;
5316 INIT_LOCALTIME_AND_FRIENDS;
5317 INIT_STRPTIME;
5318 INIT_SCANF;
5319 INIT_ISOC99_SCANF;
5320 INIT_PRINTF;
5321 INIT_PRINTF_L;
5322 INIT_ISOC99_PRINTF;
5323 INIT_FREXP;
5324 INIT_FREXPF_FREXPL;
5325 INIT_GETPWNAM_AND_FRIENDS;
5326 INIT_GETPWNAM_R_AND_FRIENDS;
5327 INIT_GETPWENT;
5328 INIT_FGETPWENT;
5329 INIT_GETPWENT_R;
5330 INIT_SETPWENT;
5331 INIT_CLOCK_GETTIME;
5332 INIT_GETITIMER;
5333 INIT_TIME;
5334 INIT_GLOB;
5335 INIT_WAIT;
5336 INIT_WAIT4;
5337 INIT_INET;
5338 INIT_PTHREAD_GETSCHEDPARAM;
5339 INIT_GETADDRINFO;
5340 INIT_GETNAMEINFO;
5341 INIT_GETSOCKNAME;
5342 INIT_GETHOSTBYNAME;
5343 INIT_GETHOSTBYNAME_R;
5344 INIT_GETHOSTBYNAME2_R;
5345 INIT_GETHOSTBYADDR_R;
5346 INIT_GETHOSTENT_R;
5347 INIT_GETSOCKOPT;
5348 INIT_ACCEPT;
5349 INIT_ACCEPT4;
5350 INIT_MODF;
5351 INIT_RECVMSG;
5352 INIT_GETPEERNAME;
5353 INIT_IOCTL;
5354 INIT_INET_ATON;
5355 INIT_SYSINFO;
5356 INIT_READDIR;
5357 INIT_READDIR64;
5358 INIT_PTRACE;
5359 INIT_SETLOCALE;
5360 INIT_GETCWD;
5361 INIT_GET_CURRENT_DIR_NAME;
5362 INIT_STRTOIMAX;
5363 INIT_MBSTOWCS;
5364 INIT_MBSNRTOWCS;
5365 INIT_WCSTOMBS;
5366 INIT_WCSNRTOMBS;
5367 INIT_WCRTOMB;
5368 INIT_TCGETATTR;
5369 INIT_REALPATH;
5370 INIT_CANONICALIZE_FILE_NAME;
5371 INIT_CONFSTR;
5372 INIT_SCHED_GETAFFINITY;
5373 INIT_SCHED_GETPARAM;
5374 INIT_STRERROR;
5375 INIT_STRERROR_R;
5376 INIT_XPG_STRERROR_R;
5377 INIT_SCANDIR;
5378 INIT_SCANDIR64;
5379 INIT_GETGROUPS;
5380 INIT_POLL;
5381 INIT_PPOLL;
5382 INIT_WORDEXP;
5383 INIT_SIGWAIT;
5384 INIT_SIGWAITINFO;
5385 INIT_SIGTIMEDWAIT;
5386 INIT_SIGSETOPS;
5387 INIT_SIGPENDING;
5388 INIT_SIGPROCMASK;
5389 INIT_BACKTRACE;
5390 INIT__EXIT;
5391 INIT_PTHREAD_MUTEX_LOCK;
5392 INIT_PTHREAD_MUTEX_UNLOCK;
5393 INIT_GETMNTENT;
5394 INIT_GETMNTENT_R;
5395 INIT_STATFS;
5396 INIT_STATFS64;
5397 INIT_STATVFS;
5398 INIT_STATVFS64;
5399 INIT_INITGROUPS;
5400 INIT_ETHER_NTOA_ATON;
5401 INIT_ETHER_HOST;
5402 INIT_ETHER_R;
5403 INIT_SHMCTL;
5404 INIT_RANDOM_R;
5405 INIT_PTHREAD_ATTR_GET;
5406 INIT_PTHREAD_ATTR_GETINHERITSCHED;
5407 INIT_PTHREAD_ATTR_GETAFFINITY_NP;
5408 INIT_PTHREAD_MUTEXATTR_GETPSHARED;
5409 INIT_PTHREAD_MUTEXATTR_GETTYPE;
5410 INIT_PTHREAD_MUTEXATTR_GETPROTOCOL;
5411 INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING;
5412 INIT_PTHREAD_MUTEXATTR_GETROBUST;
5413 INIT_PTHREAD_MUTEXATTR_GETROBUST_NP;
5414 INIT_PTHREAD_RWLOCKATTR_GETPSHARED;
5415 INIT_PTHREAD_RWLOCKATTR_GETKIND_NP;
5416 INIT_PTHREAD_CONDATTR_GETPSHARED;
5417 INIT_PTHREAD_CONDATTR_GETCLOCK;
5418 INIT_PTHREAD_BARRIERATTR_GETPSHARED;
5419 INIT_TMPNAM;
5420 INIT_TMPNAM_R;
5421 INIT_TEMPNAM;
5422 INIT_PTHREAD_SETNAME_NP;
5423 INIT_SINCOS;
5424 INIT_REMQUO;
5425 INIT_LGAMMA;
5426 INIT_LGAMMA_R;
5427 INIT_LGAMMAL_R;
5428 INIT_DRAND48_R;
5429 INIT_RAND_R;
5430 INIT_GETLINE;
5431 INIT_ICONV;
5432 INIT_TIMES;
5433 INIT_TLS_GET_ADDR;
5434 INIT_LISTXATTR;
5435 INIT_GETXATTR;
5436 INIT_GETRESID;
5437 INIT_GETIFADDRS;
5438 INIT_IF_INDEXTONAME;
5439 INIT_CAPGET;
5440 INIT_AEABI_MEM;
5441 INIT___BZERO;
5442 INIT_FTIME;
5443 INIT_XDR;
5444 INIT_TSEARCH;
5445 INIT_LIBIO_INTERNALS;
5446 INIT_FOPEN;
5447 INIT_FOPEN64;
1a4d82fc 5448 INIT_OPEN_MEMSTREAM;
92a42be0
SL
5449 INIT_OBSTACK;
5450 INIT_FFLUSH;
5451 INIT_FCLOSE;
5452 INIT_DLOPEN_DLCLOSE;
5453 INIT_GETPASS;
5454 INIT_TIMERFD;
5455 INIT_MLOCKX;
5456 INIT_FOPENCOOKIE;
5457 INIT_SEM;
5458 INIT_PTHREAD_SETCANCEL;
5459 INIT_MINCORE;
5460 INIT_PROCESS_VM_READV;
5461}