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