msan_interceptors.cc revision e18e3f07802c420eb4b2da407e148084b75cecc9
1//===-- msan_interceptors.cc ----------------------------------------------===//
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// This file is a part of MemorySanitizer.
11//
12// Interceptors for standard library functions.
13//
14// FIXME: move as many interceptors as possible into
15// sanitizer_common/sanitizer_common_interceptors.h
16//===----------------------------------------------------------------------===//
17
18#include "interception/interception.h"
19#include "msan.h"
20#include "sanitizer_common/sanitizer_platform_limits_posix.h"
21#include "sanitizer_common/sanitizer_allocator.h"
22#include "sanitizer_common/sanitizer_common.h"
23#include "sanitizer_common/sanitizer_stackdepot.h"
24#include "sanitizer_common/sanitizer_libc.h"
25#include "sanitizer_common/sanitizer_linux.h"
26
27#include <stdarg.h>
28// ACHTUNG! No other system header includes in this file.
29// Ideally, we should get rid of stdarg.h as well.
30
31using namespace __msan;
32
33// True if this is a nested interceptor.
34static THREADLOCAL int in_interceptor_scope;
35
36struct InterceptorScope {
37  InterceptorScope() { ++in_interceptor_scope; }
38  ~InterceptorScope() { --in_interceptor_scope; }
39};
40
41bool IsInInterceptorScope() {
42  return in_interceptor_scope;
43}
44
45#define ENSURE_MSAN_INITED() do { \
46  CHECK(!msan_init_is_running); \
47  if (!msan_inited) { \
48    __msan_init(); \
49  } \
50} while (0)
51
52// Check that [x, x+n) range is unpoisoned.
53#define CHECK_UNPOISONED_0(x, n)                                             \
54  do {                                                                       \
55    sptr offset = __msan_test_shadow(x, n);                                  \
56    if (__msan::IsInSymbolizer()) break;                                     \
57    if (offset >= 0 && __msan::flags()->report_umrs) {                       \
58      GET_CALLER_PC_BP_SP;                                                   \
59      (void) sp;                                                             \
60      Printf("UMR in %s at offset %d inside [%p, +%d) \n", __FUNCTION__,     \
61             offset, x, n);                                                  \
62      __msan::PrintWarningWithOrigin(pc, bp,                                 \
63                                     __msan_get_origin((char *)x + offset)); \
64      if (!__msan::flags()->keep_going) {                                    \
65        Printf("Exiting\n");                                                 \
66        Die();                                                               \
67      }                                                                      \
68    }                                                                        \
69  } while (0)
70
71// Check that [x, x+n) range is unpoisoned unless we are in a nested
72// interceptor.
73#define CHECK_UNPOISONED(x, n)                             \
74  do {                                                     \
75    if (!IsInInterceptorScope()) CHECK_UNPOISONED_0(x, n); \
76  } while (0);
77
78static void *fast_memset(void *ptr, int c, SIZE_T n);
79static void *fast_memcpy(void *dst, const void *src, SIZE_T n);
80
81INTERCEPTOR(SIZE_T, fread, void *ptr, SIZE_T size, SIZE_T nmemb, void *file) {
82  ENSURE_MSAN_INITED();
83  SIZE_T res = REAL(fread)(ptr, size, nmemb, file);
84  if (res > 0)
85    __msan_unpoison(ptr, res *size);
86  return res;
87}
88
89INTERCEPTOR(SIZE_T, fread_unlocked, void *ptr, SIZE_T size, SIZE_T nmemb,
90            void *file) {
91  ENSURE_MSAN_INITED();
92  SIZE_T res = REAL(fread_unlocked)(ptr, size, nmemb, file);
93  if (res > 0)
94    __msan_unpoison(ptr, res *size);
95  return res;
96}
97
98INTERCEPTOR(SSIZE_T, readlink, const char *path, char *buf, SIZE_T bufsiz) {
99  ENSURE_MSAN_INITED();
100  SSIZE_T res = REAL(readlink)(path, buf, bufsiz);
101  if (res > 0)
102    __msan_unpoison(buf, res);
103  return res;
104}
105
106INTERCEPTOR(void *, memcpy, void *dest, const void *src, SIZE_T n) {
107  return __msan_memcpy(dest, src, n);
108}
109
110INTERCEPTOR(void *, mempcpy, void *dest, const void *src, SIZE_T n) {
111  return (char *)__msan_memcpy(dest, src, n) + n;
112}
113
114INTERCEPTOR(void *, memmove, void *dest, const void *src, SIZE_T n) {
115  return __msan_memmove(dest, src, n);
116}
117
118INTERCEPTOR(void *, memset, void *s, int c, SIZE_T n) {
119  return __msan_memset(s, c, n);
120}
121
122INTERCEPTOR(void *, bcopy, const void *src, void *dest, SIZE_T n) {
123  return __msan_memmove(dest, src, n);
124}
125
126INTERCEPTOR(int, posix_memalign, void **memptr, SIZE_T alignment, SIZE_T size) {
127  GET_MALLOC_STACK_TRACE;
128  CHECK_EQ(alignment & (alignment - 1), 0);
129  CHECK_NE(memptr, 0);
130  *memptr = MsanReallocate(&stack, 0, size, alignment, false);
131  CHECK_NE(*memptr, 0);
132  __msan_unpoison(memptr, sizeof(*memptr));
133  return 0;
134}
135
136INTERCEPTOR(void, free, void *ptr) {
137  ENSURE_MSAN_INITED();
138  if (ptr == 0) return;
139  MsanDeallocate(ptr);
140}
141
142INTERCEPTOR(SIZE_T, strlen, const char *s) {
143  ENSURE_MSAN_INITED();
144  SIZE_T res = REAL(strlen)(s);
145  CHECK_UNPOISONED(s, res + 1);
146  return res;
147}
148
149INTERCEPTOR(SIZE_T, strnlen, const char *s, SIZE_T n) {
150  ENSURE_MSAN_INITED();
151  SIZE_T res = REAL(strnlen)(s, n);
152  SIZE_T scan_size = (res == n) ? res : res + 1;
153  CHECK_UNPOISONED(s, scan_size);
154  return res;
155}
156
157// FIXME: Add stricter shadow checks in str* interceptors (ex.: strcpy should
158// check the shadow of the terminating \0 byte).
159
160INTERCEPTOR(char *, strcpy, char *dest, const char *src) {  // NOLINT
161  ENSURE_MSAN_INITED();
162  SIZE_T n = REAL(strlen)(src);
163  char *res = REAL(strcpy)(dest, src);  // NOLINT
164  __msan_copy_poison(dest, src, n + 1);
165  return res;
166}
167
168INTERCEPTOR(char *, strncpy, char *dest, const char *src, SIZE_T n) {  // NOLINT
169  ENSURE_MSAN_INITED();
170  SIZE_T copy_size = REAL(strnlen)(src, n);
171  if (copy_size < n)
172    copy_size++;  // trailing \0
173  char *res = REAL(strncpy)(dest, src, n);  // NOLINT
174  __msan_copy_poison(dest, src, copy_size);
175  return res;
176}
177
178INTERCEPTOR(char *, stpcpy, char *dest, const char *src) {  // NOLINT
179  ENSURE_MSAN_INITED();
180  SIZE_T n = REAL(strlen)(src);
181  char *res = REAL(stpcpy)(dest, src);  // NOLINT
182  __msan_copy_poison(dest, src, n + 1);
183  return res;
184}
185
186INTERCEPTOR(char *, strdup, char *src) {
187  ENSURE_MSAN_INITED();
188  SIZE_T n = REAL(strlen)(src);
189  char *res = REAL(strdup)(src);
190  __msan_copy_poison(res, src, n + 1);
191  return res;
192}
193
194INTERCEPTOR(char *, __strdup, char *src) {
195  ENSURE_MSAN_INITED();
196  SIZE_T n = REAL(strlen)(src);
197  char *res = REAL(__strdup)(src);
198  __msan_copy_poison(res, src, n + 1);
199  return res;
200}
201
202INTERCEPTOR(char *, strndup, char *src, SIZE_T n) {
203  ENSURE_MSAN_INITED();
204  SIZE_T copy_size = REAL(strnlen)(src, n);
205  char *res = REAL(strndup)(src, n);
206  __msan_copy_poison(res, src, copy_size);
207  __msan_unpoison(res + copy_size, 1); // \0
208  return res;
209}
210
211INTERCEPTOR(char *, __strndup, char *src, SIZE_T n) {
212  ENSURE_MSAN_INITED();
213  SIZE_T copy_size = REAL(strnlen)(src, n);
214  char *res = REAL(__strndup)(src, n);
215  __msan_copy_poison(res, src, copy_size);
216  __msan_unpoison(res + copy_size, 1); // \0
217  return res;
218}
219
220INTERCEPTOR(char *, gcvt, double number, SIZE_T ndigit, char *buf) {
221  ENSURE_MSAN_INITED();
222  char *res = REAL(gcvt)(number, ndigit, buf);
223  // DynamoRio tool will take care of unpoisoning gcvt result for us.
224  if (!__msan_has_dynamic_component()) {
225    SIZE_T n = REAL(strlen)(buf);
226    __msan_unpoison(buf, n + 1);
227  }
228  return res;
229}
230
231INTERCEPTOR(char *, strcat, char *dest, const char *src) {  // NOLINT
232  ENSURE_MSAN_INITED();
233  SIZE_T src_size = REAL(strlen)(src);
234  SIZE_T dest_size = REAL(strlen)(dest);
235  char *res = REAL(strcat)(dest, src);  // NOLINT
236  __msan_copy_poison(dest + dest_size, src, src_size + 1);
237  return res;
238}
239
240INTERCEPTOR(char *, strncat, char *dest, const char *src, SIZE_T n) {  // NOLINT
241  ENSURE_MSAN_INITED();
242  SIZE_T dest_size = REAL(strlen)(dest);
243  SIZE_T copy_size = REAL(strlen)(src);
244  if (copy_size < n)
245    copy_size++;  // trailing \0
246  char *res = REAL(strncat)(dest, src, n);  // NOLINT
247  __msan_copy_poison(dest + dest_size, src, copy_size);
248  return res;
249}
250
251INTERCEPTOR(long, strtol, const char *nptr, char **endptr,  // NOLINT
252            int base) {
253  ENSURE_MSAN_INITED();
254  long res = REAL(strtol)(nptr, endptr, base);  // NOLINT
255  if (!__msan_has_dynamic_component()) {
256    __msan_unpoison(endptr, sizeof(*endptr));
257  }
258  return res;
259}
260
261INTERCEPTOR(long long, strtoll, const char *nptr, char **endptr,  // NOLINT
262            int base) {
263  ENSURE_MSAN_INITED();
264  long res = REAL(strtoll)(nptr, endptr, base);  //NOLINT
265  if (!__msan_has_dynamic_component()) {
266    __msan_unpoison(endptr, sizeof(*endptr));
267  }
268  return res;
269}
270
271INTERCEPTOR(unsigned long, strtoul, const char *nptr, char **endptr,  // NOLINT
272            int base) {
273  ENSURE_MSAN_INITED();
274  unsigned long res = REAL(strtoul)(nptr, endptr, base);  // NOLINT
275  if (!__msan_has_dynamic_component()) {
276    __msan_unpoison(endptr, sizeof(*endptr));
277  }
278  return res;
279}
280
281INTERCEPTOR(unsigned long long, strtoull, const char *nptr,  // NOLINT
282            char **endptr, int base) {
283  ENSURE_MSAN_INITED();
284  unsigned long res = REAL(strtoull)(nptr, endptr, base);  // NOLINT
285  if (!__msan_has_dynamic_component()) {
286    __msan_unpoison(endptr, sizeof(*endptr));
287  }
288  return res;
289}
290
291INTERCEPTOR(double, strtod, const char *nptr, char **endptr) {  // NOLINT
292  ENSURE_MSAN_INITED();
293  double res = REAL(strtod)(nptr, endptr);  // NOLINT
294  if (!__msan_has_dynamic_component()) {
295    __msan_unpoison(endptr, sizeof(*endptr));
296  }
297  return res;
298}
299
300INTERCEPTOR(float, strtof, const char *nptr, char **endptr) {  // NOLINT
301  ENSURE_MSAN_INITED();
302  float res = REAL(strtof)(nptr, endptr);  // NOLINT
303  if (!__msan_has_dynamic_component()) {
304    __msan_unpoison(endptr, sizeof(*endptr));
305  }
306  return res;
307}
308
309INTERCEPTOR(long double, strtold, const char *nptr, char **endptr) {  // NOLINT
310  ENSURE_MSAN_INITED();
311  long double res = REAL(strtold)(nptr, endptr);  // NOLINT
312  if (!__msan_has_dynamic_component()) {
313    __msan_unpoison(endptr, sizeof(*endptr));
314  }
315  return res;
316}
317
318INTERCEPTOR(int, vasprintf, char **strp, const char *format, va_list ap) {
319  ENSURE_MSAN_INITED();
320  int res = REAL(vasprintf)(strp, format, ap);
321  if (res >= 0 && !__msan_has_dynamic_component()) {
322    __msan_unpoison(strp, sizeof(*strp));
323    __msan_unpoison(*strp, res + 1);
324  }
325  return res;
326}
327
328INTERCEPTOR(int, asprintf, char **strp, const char *format, ...) {  // NOLINT
329  ENSURE_MSAN_INITED();
330  va_list ap;
331  va_start(ap, format);
332  int res = vasprintf(strp, format, ap);  // NOLINT
333  va_end(ap);
334  return res;
335}
336
337INTERCEPTOR(int, vsnprintf, char *str, uptr size,
338            const char *format, va_list ap) {
339  ENSURE_MSAN_INITED();
340  int res = REAL(vsnprintf)(str, size, format, ap);
341  if (res >= 0 && !__msan_has_dynamic_component()) {
342    __msan_unpoison(str, res + 1);
343  }
344  return res;
345}
346
347INTERCEPTOR(int, vsprintf, char *str, const char *format, va_list ap) {
348  ENSURE_MSAN_INITED();
349  int res = REAL(vsprintf)(str, format, ap);
350  if (res >= 0 && !__msan_has_dynamic_component()) {
351    __msan_unpoison(str, res + 1);
352  }
353  return res;
354}
355
356INTERCEPTOR(int, vswprintf, void *str, uptr size, void *format, va_list ap) {
357  ENSURE_MSAN_INITED();
358  int res = REAL(vswprintf)(str, size, format, ap);
359  if (res >= 0 && !__msan_has_dynamic_component()) {
360    __msan_unpoison(str, 4 * (res + 1));
361  }
362  return res;
363}
364
365INTERCEPTOR(int, sprintf, char *str, const char *format, ...) {  // NOLINT
366  ENSURE_MSAN_INITED();
367  va_list ap;
368  va_start(ap, format);
369  int res = vsprintf(str, format, ap);  // NOLINT
370  va_end(ap);
371  return res;
372}
373
374INTERCEPTOR(int, snprintf, char *str, uptr size, const char *format, ...) {
375  ENSURE_MSAN_INITED();
376  va_list ap;
377  va_start(ap, format);
378  int res = vsnprintf(str, size, format, ap);
379  va_end(ap);
380  return res;
381}
382
383INTERCEPTOR(int, swprintf, void *str, uptr size, void *format, ...) {
384  ENSURE_MSAN_INITED();
385  va_list ap;
386  va_start(ap, format);
387  int res = vswprintf(str, size, format, ap);
388  va_end(ap);
389  return res;
390}
391
392// SIZE_T strftime(char *s, SIZE_T max, const char *format,const struct tm *tm);
393INTERCEPTOR(SIZE_T, strftime, char *s, SIZE_T max, const char *format,
394            void *tm) {
395  ENSURE_MSAN_INITED();
396  SIZE_T res = REAL(strftime)(s, max, format, tm);
397  if (res) __msan_unpoison(s, res + 1);
398  return res;
399}
400
401INTERCEPTOR(int, mbtowc, wchar_t *dest, const char *src, SIZE_T n) {
402  ENSURE_MSAN_INITED();
403  int res = REAL(mbtowc)(dest, src, n);
404  if (res != -1 && dest) __msan_unpoison(dest, sizeof(wchar_t));
405  return res;
406}
407
408INTERCEPTOR(int, mbrtowc, wchar_t *dest, const char *src, SIZE_T n, void *ps) {
409  ENSURE_MSAN_INITED();
410  SIZE_T res = REAL(mbrtowc)(dest, src, n, ps);
411  if (res != (SIZE_T)-1 && dest) __msan_unpoison(dest, sizeof(wchar_t));
412  return res;
413}
414
415INTERCEPTOR(SIZE_T, wcslen, const wchar_t *s) {
416  ENSURE_MSAN_INITED();
417  SIZE_T res = REAL(wcslen)(s);
418  CHECK_UNPOISONED(s, sizeof(wchar_t) * (res + 1));
419  return res;
420}
421
422// wchar_t *wcschr(const wchar_t *wcs, wchar_t wc);
423INTERCEPTOR(wchar_t *, wcschr, void *s, wchar_t wc, void *ps) {
424  ENSURE_MSAN_INITED();
425  wchar_t *res = REAL(wcschr)(s, wc, ps);
426  return res;
427}
428
429// wchar_t *wcscpy(wchar_t *dest, const wchar_t *src);
430INTERCEPTOR(wchar_t *, wcscpy, wchar_t *dest, const wchar_t *src) {
431  ENSURE_MSAN_INITED();
432  wchar_t *res = REAL(wcscpy)(dest, src);
433  __msan_copy_poison(dest, src, sizeof(wchar_t) * (REAL(wcslen)(src) + 1));
434  return res;
435}
436
437// wchar_t *wmemcpy(wchar_t *dest, const wchar_t *src, SIZE_T n);
438INTERCEPTOR(wchar_t *, wmemcpy, wchar_t *dest, const wchar_t *src, SIZE_T n) {
439  ENSURE_MSAN_INITED();
440  wchar_t *res = REAL(wmemcpy)(dest, src, n);
441  __msan_copy_poison(dest, src, n * sizeof(wchar_t));
442  return res;
443}
444
445INTERCEPTOR(wchar_t *, wmempcpy, wchar_t *dest, const wchar_t *src, SIZE_T n) {
446  ENSURE_MSAN_INITED();
447  wchar_t *res = REAL(wmempcpy)(dest, src, n);
448  __msan_copy_poison(dest, src, n * sizeof(wchar_t));
449  return res;
450}
451
452INTERCEPTOR(wchar_t *, wmemset, wchar_t *s, wchar_t c, SIZE_T n) {
453  CHECK(MEM_IS_APP(s));
454  ENSURE_MSAN_INITED();
455  wchar_t *res = (wchar_t *)fast_memset(s, c, n * sizeof(wchar_t));
456  __msan_unpoison(s, n * sizeof(wchar_t));
457  return res;
458}
459
460INTERCEPTOR(wchar_t *, wmemmove, wchar_t *dest, const wchar_t *src, SIZE_T n) {
461  ENSURE_MSAN_INITED();
462  wchar_t *res = REAL(wmemmove)(dest, src, n);
463  __msan_move_poison(dest, src, n * sizeof(wchar_t));
464  return res;
465}
466
467INTERCEPTOR(int, wcscmp, const wchar_t *s1, const wchar_t *s2) {
468  ENSURE_MSAN_INITED();
469  int res = REAL(wcscmp)(s1, s2);
470  return res;
471}
472
473INTERCEPTOR(double, wcstod, const wchar_t *nptr, wchar_t **endptr) {
474  ENSURE_MSAN_INITED();
475  double res = REAL(wcstod)(nptr, endptr);
476  __msan_unpoison(endptr, sizeof(*endptr));
477  return res;
478}
479
480// #define UNSUPPORTED(name) \
481//   INTERCEPTOR(void, name, void) {                     \
482//     Printf("MSAN: Unsupported %s\n", __FUNCTION__);   \
483//     Die();                                            \
484//   }
485
486// FIXME: intercept the following functions:
487// Note, they only matter when running without a dynamic tool.
488// UNSUPPORTED(wcscoll_l)
489// UNSUPPORTED(wcsnrtombs)
490// UNSUPPORTED(wcstol)
491// UNSUPPORTED(wcstoll)
492// UNSUPPORTED(wcstold)
493// UNSUPPORTED(wcstoul)
494// UNSUPPORTED(wcstoull)
495// UNSUPPORTED(wcsxfrm_l)
496// UNSUPPORTED(wcsdup)
497// UNSUPPORTED(wcsftime)
498// UNSUPPORTED(wcsstr)
499// UNSUPPORTED(wcsrchr)
500// UNSUPPORTED(wctob)
501
502INTERCEPTOR(int, gettimeofday, void *tv, void *tz) {
503  ENSURE_MSAN_INITED();
504  int res = REAL(gettimeofday)(tv, tz);
505  if (tv)
506    __msan_unpoison(tv, 16);
507  if (tz)
508    __msan_unpoison(tz, 8);
509  return res;
510}
511
512INTERCEPTOR(char *, fcvt, double x, int a, int *b, int *c) {
513  ENSURE_MSAN_INITED();
514  char *res = REAL(fcvt)(x, a, b, c);
515  if (!__msan_has_dynamic_component()) {
516    __msan_unpoison(b, sizeof(*b));
517    __msan_unpoison(c, sizeof(*c));
518  }
519  return res;
520}
521
522INTERCEPTOR(char *, getenv, char *name) {
523  ENSURE_MSAN_INITED();
524  char *res = REAL(getenv)(name);
525  if (!__msan_has_dynamic_component()) {
526    if (res)
527      __msan_unpoison(res, REAL(strlen)(res) + 1);
528  }
529  return res;
530}
531
532extern char **environ;
533
534static void UnpoisonEnviron() {
535  char **envp = environ;
536  for (; *envp; ++envp) {
537    __msan_unpoison(envp, sizeof(*envp));
538    __msan_unpoison(*envp, REAL(strlen)(*envp) + 1);
539  }
540  // Trailing NULL pointer.
541  __msan_unpoison(envp, sizeof(*envp));
542}
543
544INTERCEPTOR(int, setenv, const char *name, const char *value, int overwrite) {
545  ENSURE_MSAN_INITED();
546  int res = REAL(setenv)(name, value, overwrite);
547  if (!res) UnpoisonEnviron();
548  return res;
549}
550
551INTERCEPTOR(int, putenv, char *string) {
552  ENSURE_MSAN_INITED();
553  int res = REAL(putenv)(string);
554  if (!res) UnpoisonEnviron();
555  return res;
556}
557
558INTERCEPTOR(int, __fxstat, int magic, int fd, void *buf) {
559  ENSURE_MSAN_INITED();
560  int res = REAL(__fxstat)(magic, fd, buf);
561  if (!res)
562    __msan_unpoison(buf, __sanitizer::struct_stat_sz);
563  return res;
564}
565
566INTERCEPTOR(int, __fxstat64, int magic, int fd, void *buf) {
567  ENSURE_MSAN_INITED();
568  int res = REAL(__fxstat64)(magic, fd, buf);
569  if (!res)
570    __msan_unpoison(buf, __sanitizer::struct_stat64_sz);
571  return res;
572}
573
574INTERCEPTOR(int, __xstat, int magic, char *path, void *buf) {
575  ENSURE_MSAN_INITED();
576  int res = REAL(__xstat)(magic, path, buf);
577  if (!res)
578    __msan_unpoison(buf, __sanitizer::struct_stat_sz);
579  return res;
580}
581
582INTERCEPTOR(int, __xstat64, int magic, char *path, void *buf) {
583  ENSURE_MSAN_INITED();
584  int res = REAL(__xstat64)(magic, path, buf);
585  if (!res)
586    __msan_unpoison(buf, __sanitizer::struct_stat64_sz);
587  return res;
588}
589
590INTERCEPTOR(int, __lxstat, int magic, char *path, void *buf) {
591  ENSURE_MSAN_INITED();
592  int res = REAL(__lxstat)(magic, path, buf);
593  if (!res)
594    __msan_unpoison(buf, __sanitizer::struct_stat_sz);
595  return res;
596}
597
598INTERCEPTOR(int, __lxstat64, int magic, char *path, void *buf) {
599  ENSURE_MSAN_INITED();
600  int res = REAL(__lxstat64)(magic, path, buf);
601  if (!res)
602    __msan_unpoison(buf, __sanitizer::struct_stat64_sz);
603  return res;
604}
605
606INTERCEPTOR(int, pipe, int pipefd[2]) {
607  if (msan_init_is_running)
608    return REAL(pipe)(pipefd);
609  ENSURE_MSAN_INITED();
610  int res = REAL(pipe)(pipefd);
611  if (!res)
612    __msan_unpoison(pipefd, sizeof(int[2]));
613  return res;
614}
615
616INTERCEPTOR(int, pipe2, int pipefd[2], int flags) {
617  ENSURE_MSAN_INITED();
618  int res = REAL(pipe2)(pipefd, flags);
619  if (!res)
620    __msan_unpoison(pipefd, sizeof(int[2]));
621  return res;
622}
623
624INTERCEPTOR(int, socketpair, int domain, int type, int protocol, int sv[2]) {
625  ENSURE_MSAN_INITED();
626  int res = REAL(socketpair)(domain, type, protocol, sv);
627  if (!res)
628    __msan_unpoison(sv, sizeof(int[2]));
629  return res;
630}
631
632INTERCEPTOR(char *, fgets, char *s, int size, void *stream) {
633  ENSURE_MSAN_INITED();
634  char *res = REAL(fgets)(s, size, stream);
635  if (res)
636    __msan_unpoison(s, REAL(strlen)(s) + 1);
637  return res;
638}
639
640INTERCEPTOR(char *, fgets_unlocked, char *s, int size, void *stream) {
641  ENSURE_MSAN_INITED();
642  char *res = REAL(fgets_unlocked)(s, size, stream);
643  if (res)
644    __msan_unpoison(s, REAL(strlen)(s) + 1);
645  return res;
646}
647
648INTERCEPTOR(int, getrlimit, int resource, void *rlim) {
649  if (msan_init_is_running)
650    return REAL(getrlimit)(resource, rlim);
651  ENSURE_MSAN_INITED();
652  int res = REAL(getrlimit)(resource, rlim);
653  if (!res)
654    __msan_unpoison(rlim, __sanitizer::struct_rlimit_sz);
655  return res;
656}
657
658INTERCEPTOR(int, getrlimit64, int resource, void *rlim) {
659  if (msan_init_is_running)
660    return REAL(getrlimit64)(resource, rlim);
661  ENSURE_MSAN_INITED();
662  int res = REAL(getrlimit64)(resource, rlim);
663  if (!res)
664    __msan_unpoison(rlim, __sanitizer::struct_rlimit64_sz);
665  return res;
666}
667
668INTERCEPTOR(int, statfs, const char *s, void *buf) {
669  ENSURE_MSAN_INITED();
670  int res = REAL(statfs)(s, buf);
671  if (!res)
672    __msan_unpoison(buf, __sanitizer::struct_statfs_sz);
673  return res;
674}
675
676INTERCEPTOR(int, fstatfs, int fd, void *buf) {
677  ENSURE_MSAN_INITED();
678  int res = REAL(fstatfs)(fd, buf);
679  if (!res)
680    __msan_unpoison(buf, __sanitizer::struct_statfs_sz);
681  return res;
682}
683
684INTERCEPTOR(int, statfs64, const char *s, void *buf) {
685  ENSURE_MSAN_INITED();
686  int res = REAL(statfs64)(s, buf);
687  if (!res)
688    __msan_unpoison(buf, __sanitizer::struct_statfs64_sz);
689  return res;
690}
691
692INTERCEPTOR(int, fstatfs64, int fd, void *buf) {
693  ENSURE_MSAN_INITED();
694  int res = REAL(fstatfs64)(fd, buf);
695  if (!res)
696    __msan_unpoison(buf, __sanitizer::struct_statfs64_sz);
697  return res;
698}
699
700INTERCEPTOR(int, uname, void *utsname) {
701  ENSURE_MSAN_INITED();
702  int res = REAL(uname)(utsname);
703  if (!res) {
704    __msan_unpoison(utsname, __sanitizer::struct_utsname_sz);
705  }
706  return res;
707}
708
709INTERCEPTOR(int, gethostname, char *name, SIZE_T len) {
710  ENSURE_MSAN_INITED();
711  int res = REAL(gethostname)(name, len);
712  if (!res) {
713    SIZE_T real_len = REAL(strnlen)(name, len);
714    if (real_len < len)
715      ++real_len;
716    __msan_unpoison(name, real_len);
717  }
718  return res;
719}
720
721INTERCEPTOR(int, epoll_wait, int epfd, void *events, int maxevents,
722    int timeout) {
723  ENSURE_MSAN_INITED();
724  int res = REAL(epoll_wait)(epfd, events, maxevents, timeout);
725  if (res > 0) {
726    __msan_unpoison(events, __sanitizer::struct_epoll_event_sz * res);
727  }
728  return res;
729}
730
731INTERCEPTOR(int, epoll_pwait, int epfd, void *events, int maxevents,
732    int timeout, void *sigmask) {
733  ENSURE_MSAN_INITED();
734  int res = REAL(epoll_pwait)(epfd, events, maxevents, timeout, sigmask);
735  if (res > 0) {
736    __msan_unpoison(events, __sanitizer::struct_epoll_event_sz * res);
737  }
738  return res;
739}
740
741INTERCEPTOR(SSIZE_T, recv, int fd, void *buf, SIZE_T len, int flags) {
742  ENSURE_MSAN_INITED();
743  SSIZE_T res = REAL(recv)(fd, buf, len, flags);
744  if (res > 0)
745    __msan_unpoison(buf, res);
746  return res;
747}
748
749INTERCEPTOR(SSIZE_T, recvfrom, int fd, void *buf, SIZE_T len, int flags,
750            void *srcaddr, int *addrlen) {
751  ENSURE_MSAN_INITED();
752  SIZE_T srcaddr_sz;
753  if (srcaddr) srcaddr_sz = *addrlen;
754  SSIZE_T res = REAL(recvfrom)(fd, buf, len, flags, srcaddr, addrlen);
755  if (res > 0) {
756    __msan_unpoison(buf, res);
757    if (srcaddr) {
758      SIZE_T sz = *addrlen;
759      __msan_unpoison(srcaddr, (sz < srcaddr_sz) ? sz : srcaddr_sz);
760    }
761  }
762  return res;
763}
764
765INTERCEPTOR(void *, calloc, SIZE_T nmemb, SIZE_T size) {
766  if (CallocShouldReturnNullDueToOverflow(size, nmemb)) return 0;
767  GET_MALLOC_STACK_TRACE;
768  if (!msan_inited) {
769    // Hack: dlsym calls calloc before REAL(calloc) is retrieved from dlsym.
770    const SIZE_T kCallocPoolSize = 1024;
771    static uptr calloc_memory_for_dlsym[kCallocPoolSize];
772    static SIZE_T allocated;
773    SIZE_T size_in_words = ((nmemb * size) + kWordSize - 1) / kWordSize;
774    void *mem = (void*)&calloc_memory_for_dlsym[allocated];
775    allocated += size_in_words;
776    CHECK(allocated < kCallocPoolSize);
777    return mem;
778  }
779  return MsanReallocate(&stack, 0, nmemb * size, sizeof(u64), true);
780}
781
782INTERCEPTOR(void *, realloc, void *ptr, SIZE_T size) {
783  GET_MALLOC_STACK_TRACE;
784  return MsanReallocate(&stack, ptr, size, sizeof(u64), false);
785}
786
787INTERCEPTOR(void *, malloc, SIZE_T size) {
788  GET_MALLOC_STACK_TRACE;
789  return MsanReallocate(&stack, 0, size, sizeof(u64), false);
790}
791
792void __msan_allocated_memory(const void* data, uptr size) {
793  GET_MALLOC_STACK_TRACE;
794  if (flags()->poison_in_malloc)
795    __msan_poison(data, size);
796  if (__msan_get_track_origins()) {
797    u32 stack_id = StackDepotPut(stack.trace, stack.size);
798    CHECK(stack_id);
799    CHECK_EQ((stack_id >> 31), 0);  // Higher bit is occupied by stack origins.
800    __msan_set_origin(data, size, stack_id);
801  }
802}
803
804INTERCEPTOR(void *, mmap, void *addr, SIZE_T length, int prot, int flags,
805            int fd, OFF_T offset) {
806  ENSURE_MSAN_INITED();
807  void *res = REAL(mmap)(addr, length, prot, flags, fd, offset);
808  if (res != (void*)-1)
809    __msan_unpoison(res, RoundUpTo(length, GetPageSize()));
810  return res;
811}
812
813INTERCEPTOR(void *, mmap64, void *addr, SIZE_T length, int prot, int flags,
814            int fd, OFF64_T offset) {
815  ENSURE_MSAN_INITED();
816  void *res = REAL(mmap64)(addr, length, prot, flags, fd, offset);
817  if (res != (void*)-1)
818    __msan_unpoison(res, RoundUpTo(length, GetPageSize()));
819  return res;
820}
821
822struct dlinfo {
823  char *dli_fname;
824  void *dli_fbase;
825  char *dli_sname;
826  void *dli_saddr;
827};
828
829INTERCEPTOR(int, dladdr, void *addr, dlinfo *info) {
830  ENSURE_MSAN_INITED();
831  int res = REAL(dladdr)(addr, info);
832  if (res != 0) {
833    __msan_unpoison(info, sizeof(*info));
834    if (info->dli_fname)
835      __msan_unpoison(info->dli_fname, REAL(strlen)(info->dli_fname) + 1);
836    if (info->dli_sname)
837      __msan_unpoison(info->dli_sname, REAL(strlen)(info->dli_sname) + 1);
838  }
839  return res;
840}
841
842// dlopen() ultimately calls mmap() down inside the loader, which generally
843// doesn't participate in dynamic symbol resolution.  Therefore we won't
844// intercept its calls to mmap, and we have to hook it here.  The loader
845// initializes the module before returning, so without the dynamic component, we
846// won't be able to clear the shadow before the initializers.  Fixing this would
847// require putting our own initializer first to clear the shadow.
848INTERCEPTOR(void *, dlopen, const char *filename, int flag) {
849  ENSURE_MSAN_INITED();
850  EnterLoader();
851  link_map *map = (link_map *)REAL(dlopen)(filename, flag);
852  ExitLoader();
853  if (!__msan_has_dynamic_component() && map) {
854    // If msandr didn't clear the shadow before the initializers ran, we do it
855    // ourselves afterwards.
856    ForEachMappedRegion(map, __msan_unpoison);
857  }
858  return (void *)map;
859}
860
861typedef int (*dl_iterate_phdr_cb)(__sanitizer_dl_phdr_info *info, SIZE_T size,
862                                  void *data);
863struct dl_iterate_phdr_data {
864  dl_iterate_phdr_cb callback;
865  void *data;
866};
867
868static int msan_dl_iterate_phdr_cb(__sanitizer_dl_phdr_info *info, SIZE_T size,
869                                   void *data) {
870  if (info) {
871    __msan_unpoison(info, size);
872    if (info->dlpi_name)
873      __msan_unpoison(info->dlpi_name, REAL(strlen)(info->dlpi_name) + 1);
874  }
875  dl_iterate_phdr_data *cbdata = (dl_iterate_phdr_data *)data;
876  UnpoisonParam(3);
877  return cbdata->callback(info, size, cbdata->data);
878}
879
880INTERCEPTOR(int, dl_iterate_phdr, dl_iterate_phdr_cb callback, void *data) {
881  ENSURE_MSAN_INITED();
882  EnterLoader();
883  dl_iterate_phdr_data cbdata;
884  cbdata.callback = callback;
885  cbdata.data = data;
886  int res = REAL(dl_iterate_phdr)(msan_dl_iterate_phdr_cb, (void *)&cbdata);
887  ExitLoader();
888  return res;
889}
890
891INTERCEPTOR(int, getrusage, int who, void *usage) {
892  ENSURE_MSAN_INITED();
893  int res = REAL(getrusage)(who, usage);
894  if (res == 0) {
895    __msan_unpoison(usage, __sanitizer::struct_rusage_sz);
896  }
897  return res;
898}
899
900const int kMaxSignals = 1024;
901static uptr sigactions[kMaxSignals];
902static StaticSpinMutex sigactions_mu;
903
904static void SignalHandler(int signo) {
905  typedef void (*signal_cb)(int x);
906  signal_cb cb = (signal_cb)sigactions[signo];
907  cb(signo);
908}
909
910static void SignalAction(int signo, void *si, void *uc) {
911  UnpoisonParam(3);
912  __msan_unpoison(si, __sanitizer::struct_sigaction_sz);
913  __msan_unpoison(uc, __sanitizer::ucontext_t_sz);
914
915  typedef void (*sigaction_cb)(int, void *, void *);
916  sigaction_cb cb = (sigaction_cb)sigactions[signo];
917  cb(signo, si, uc);
918}
919
920INTERCEPTOR(int, sigaction, int signo, const __sanitizer_sigaction *act,
921            __sanitizer_sigaction *oldact) {
922  ENSURE_MSAN_INITED();
923  // FIXME: check that *act is unpoisoned.
924  // That requires intercepting all of sigemptyset, sigfillset, etc.
925  int res;
926  if (flags()->wrap_signals) {
927    SpinMutexLock lock(&sigactions_mu);
928    CHECK_LT(signo, kMaxSignals);
929    uptr old_cb = sigactions[signo];
930    __sanitizer_sigaction new_act;
931    __sanitizer_sigaction *pnew_act = act ? &new_act : 0;
932    if (act) {
933      internal_memcpy(pnew_act, act, __sanitizer::struct_sigaction_sz);
934      uptr cb = __sanitizer::__sanitizer_get_sigaction_sa_sigaction(pnew_act);
935      uptr new_cb =
936          __sanitizer::__sanitizer_get_sigaction_sa_siginfo(pnew_act) ?
937          (uptr)SignalAction : (uptr)SignalHandler;
938      if (cb != __sanitizer::sig_ign && cb != __sanitizer::sig_dfl) {
939        sigactions[signo] = cb;
940        __sanitizer::__sanitizer_set_sigaction_sa_sigaction(pnew_act, new_cb);
941      }
942    }
943    res = REAL(sigaction)(signo, pnew_act, oldact);
944    if (res == 0 && oldact) {
945      uptr cb = __sanitizer::__sanitizer_get_sigaction_sa_sigaction(oldact);
946      if (cb != __sanitizer::sig_ign && cb != __sanitizer::sig_dfl) {
947        __sanitizer::__sanitizer_set_sigaction_sa_sigaction(oldact, old_cb);
948      }
949    }
950  } else {
951    res = REAL(sigaction)(signo, act, oldact);
952  }
953
954  if (res == 0 && oldact) {
955    __msan_unpoison(oldact, __sanitizer::struct_sigaction_sz);
956  }
957  return res;
958}
959
960INTERCEPTOR(int, signal, int signo, uptr cb) {
961  ENSURE_MSAN_INITED();
962  if (flags()->wrap_signals) {
963    CHECK_LT(signo, kMaxSignals);
964    SpinMutexLock lock(&sigactions_mu);
965    if (cb != __sanitizer::sig_ign && cb != __sanitizer::sig_dfl) {
966      sigactions[signo] = cb;
967      cb = (uptr) SignalHandler;
968    }
969    return REAL(signal)(signo, cb);
970  } else {
971    return REAL(signal)(signo, cb);
972  }
973}
974
975extern "C" int pthread_attr_init(void *attr);
976extern "C" int pthread_attr_destroy(void *attr);
977extern "C" int pthread_attr_setstacksize(void *attr, uptr stacksize);
978extern "C" int pthread_attr_getstack(void *attr, uptr *stack, uptr *stacksize);
979
980INTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void*),
981            void * param) {
982  ENSURE_MSAN_INITED(); // for GetTlsSize()
983  __sanitizer_pthread_attr_t myattr;
984  if (attr == 0) {
985    pthread_attr_init(&myattr);
986    attr = &myattr;
987  }
988
989  AdjustStackSizeLinux(attr, flags()->verbosity);
990
991  int res = REAL(pthread_create)(th, attr, callback, param);
992  if (attr == &myattr)
993    pthread_attr_destroy(&myattr);
994  if (!res) {
995    __msan_unpoison(th, __sanitizer::pthread_t_sz);
996  }
997  return res;
998}
999
1000INTERCEPTOR(int, pthread_key_create, __sanitizer_pthread_key_t *key,
1001            void (*dtor)(void *value)) {
1002  ENSURE_MSAN_INITED();
1003  int res = REAL(pthread_key_create)(key, dtor);
1004  if (!res && key)
1005    __msan_unpoison(key, sizeof(*key));
1006  return res;
1007}
1008
1009INTERCEPTOR(int, pthread_join, void *th, void **retval) {
1010  ENSURE_MSAN_INITED();
1011  int res = REAL(pthread_join)(th, retval);
1012  if (!res && retval)
1013    __msan_unpoison(retval, sizeof(*retval));
1014  return res;
1015}
1016
1017struct MSanInterceptorContext {
1018  bool in_interceptor_scope;
1019};
1020
1021// A version of CHECK_UNPOISED using a saved scope value. Used in common
1022// interceptors.
1023#define CHECK_UNPOISONED_CTX(ctx, x, n)                         \
1024  do {                                                          \
1025    if (!((MSanInterceptorContext *)ctx)->in_interceptor_scope) \
1026      CHECK_UNPOISONED_0(x, n);                                 \
1027  } while (0)
1028
1029#define COMMON_INTERCEPTOR_UNPOISON_PARAM(ctx, count)  \
1030  UnpoisonParam(count)
1031#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \
1032  __msan_unpoison(ptr, size)
1033#define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \
1034  CHECK_UNPOISONED_CTX(ctx, ptr, size)
1035#define COMMON_INTERCEPTOR_ENTER(ctx, func, ...)              \
1036  if (msan_init_is_running) return REAL(func)(__VA_ARGS__);   \
1037  MSanInterceptorContext msan_ctx = {IsInInterceptorScope()}; \
1038  ctx = (void *)&msan_ctx;                                    \
1039  InterceptorScope interceptor_scope;                         \
1040  ENSURE_MSAN_INITED();
1041#define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \
1042  do {                                         \
1043  } while (false)
1044#define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) \
1045  do {                                         \
1046  } while (false)
1047#define COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, newfd) \
1048  do {                                                      \
1049  } while (false)
1050#define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) \
1051  do {                                                \
1052  } while (false)  // FIXME
1053#define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name)
1054#include "sanitizer_common/sanitizer_common_interceptors.inc"
1055
1056#define COMMON_SYSCALL_PRE_READ_RANGE(p, s) CHECK_UNPOISONED(p, s)
1057#define COMMON_SYSCALL_PRE_WRITE_RANGE(p, s)
1058#define COMMON_SYSCALL_POST_READ_RANGE(p, s)
1059#define COMMON_SYSCALL_POST_WRITE_RANGE(p, s) __msan_unpoison(p, s)
1060#include "sanitizer_common/sanitizer_common_syscalls.inc"
1061
1062// static
1063void *fast_memset(void *ptr, int c, SIZE_T n) {
1064  // hack until we have a really fast internal_memset
1065  if (sizeof(uptr) == 8 &&
1066      (n % 8) == 0 &&
1067      ((uptr)ptr % 8) == 0 &&
1068      (c == 0 || c == -1)) {
1069    // Printf("memset %p %zd %x\n", ptr, n, c);
1070    uptr to_store = c ? -1L : 0L;
1071    uptr *p = (uptr*)ptr;
1072    for (SIZE_T i = 0; i < n / 8; i++)
1073      p[i] = to_store;
1074    return ptr;
1075  }
1076  return internal_memset(ptr, c, n);
1077}
1078
1079// static
1080void *fast_memcpy(void *dst, const void *src, SIZE_T n) {
1081  // Same hack as in fast_memset above.
1082  if (sizeof(uptr) == 8 &&
1083      (n % 8) == 0 &&
1084      ((uptr)dst % 8) == 0 &&
1085      ((uptr)src % 8) == 0) {
1086    uptr *d = (uptr*)dst;
1087    uptr *s = (uptr*)src;
1088    for (SIZE_T i = 0; i < n / 8; i++)
1089      d[i] = s[i];
1090    return dst;
1091  }
1092  return internal_memcpy(dst, src, n);
1093}
1094
1095// These interface functions reside here so that they can use
1096// fast_memset, etc.
1097void __msan_unpoison(const void *a, uptr size) {
1098  if (!MEM_IS_APP(a)) return;
1099  fast_memset((void*)MEM_TO_SHADOW((uptr)a), 0, size);
1100}
1101
1102void __msan_poison(const void *a, uptr size) {
1103  if (!MEM_IS_APP(a)) return;
1104  fast_memset((void*)MEM_TO_SHADOW((uptr)a),
1105              __msan::flags()->poison_heap_with_zeroes ? 0 : -1, size);
1106}
1107
1108void __msan_poison_stack(void *a, uptr size) {
1109  if (!MEM_IS_APP(a)) return;
1110  fast_memset((void*)MEM_TO_SHADOW((uptr)a),
1111              __msan::flags()->poison_stack_with_zeroes ? 0 : -1, size);
1112}
1113
1114void __msan_clear_and_unpoison(void *a, uptr size) {
1115  fast_memset(a, 0, size);
1116  fast_memset((void*)MEM_TO_SHADOW((uptr)a), 0, size);
1117}
1118
1119void __msan_copy_origin(void *dst, const void *src, uptr size) {
1120  if (!__msan_get_track_origins()) return;
1121  if (!MEM_IS_APP(dst) || !MEM_IS_APP(src)) return;
1122  uptr d = MEM_TO_ORIGIN(dst);
1123  uptr s = MEM_TO_ORIGIN(src);
1124  uptr beg = d & ~3UL;  // align down.
1125  uptr end = (d + size + 3) & ~3UL;  // align up.
1126  s = s & ~3UL;  // align down.
1127  fast_memcpy((void*)beg, (void*)s, end - beg);
1128}
1129
1130void __msan_copy_poison(void *dst, const void *src, uptr size) {
1131  if (!MEM_IS_APP(dst)) return;
1132  if (!MEM_IS_APP(src)) return;
1133  fast_memcpy((void*)MEM_TO_SHADOW((uptr)dst),
1134              (void*)MEM_TO_SHADOW((uptr)src), size);
1135  __msan_copy_origin(dst, src, size);
1136}
1137
1138void __msan_move_poison(void *dst, const void *src, uptr size) {
1139  if (!MEM_IS_APP(dst)) return;
1140  if (!MEM_IS_APP(src)) return;
1141  internal_memmove((void*)MEM_TO_SHADOW((uptr)dst),
1142         (void*)MEM_TO_SHADOW((uptr)src), size);
1143  __msan_copy_origin(dst, src, size);
1144}
1145
1146void *__msan_memcpy(void *dest, const void *src, SIZE_T n) {
1147  ENSURE_MSAN_INITED();
1148  void *res = fast_memcpy(dest, src, n);
1149  __msan_copy_poison(dest, src, n);
1150  return res;
1151}
1152
1153void *__msan_memset(void *s, int c, SIZE_T n) {
1154  ENSURE_MSAN_INITED();
1155  void *res = fast_memset(s, c, n);
1156  __msan_unpoison(s, n);
1157  return res;
1158}
1159
1160void *__msan_memmove(void *dest, const void *src, SIZE_T n) {
1161  ENSURE_MSAN_INITED();
1162  void *res = REAL(memmove)(dest, src, n);
1163  __msan_move_poison(dest, src, n);
1164  return res;
1165}
1166
1167namespace __msan {
1168void InitializeInterceptors() {
1169  static int inited = 0;
1170  CHECK_EQ(inited, 0);
1171  SANITIZER_COMMON_INTERCEPTORS_INIT;
1172
1173  INTERCEPT_FUNCTION(mmap);
1174  INTERCEPT_FUNCTION(mmap64);
1175  INTERCEPT_FUNCTION(posix_memalign);
1176  INTERCEPT_FUNCTION(malloc);
1177  INTERCEPT_FUNCTION(calloc);
1178  INTERCEPT_FUNCTION(realloc);
1179  INTERCEPT_FUNCTION(free);
1180  INTERCEPT_FUNCTION(fread);
1181  INTERCEPT_FUNCTION(fread_unlocked);
1182  INTERCEPT_FUNCTION(readlink);
1183  INTERCEPT_FUNCTION(memcpy);
1184  INTERCEPT_FUNCTION(mempcpy);
1185  INTERCEPT_FUNCTION(memset);
1186  INTERCEPT_FUNCTION(memmove);
1187  INTERCEPT_FUNCTION(bcopy);
1188  INTERCEPT_FUNCTION(wmemset);
1189  INTERCEPT_FUNCTION(wmemcpy);
1190  INTERCEPT_FUNCTION(wmempcpy);
1191  INTERCEPT_FUNCTION(wmemmove);
1192  INTERCEPT_FUNCTION(strcpy);  // NOLINT
1193  INTERCEPT_FUNCTION(stpcpy);  // NOLINT
1194  INTERCEPT_FUNCTION(strdup);
1195  INTERCEPT_FUNCTION(__strdup);
1196  INTERCEPT_FUNCTION(strndup);
1197  INTERCEPT_FUNCTION(__strndup);
1198  INTERCEPT_FUNCTION(strncpy);  // NOLINT
1199  INTERCEPT_FUNCTION(strlen);
1200  INTERCEPT_FUNCTION(strnlen);
1201  INTERCEPT_FUNCTION(gcvt);
1202  INTERCEPT_FUNCTION(strcat);  // NOLINT
1203  INTERCEPT_FUNCTION(strncat);  // NOLINT
1204  INTERCEPT_FUNCTION(strtol);
1205  INTERCEPT_FUNCTION(strtoll);
1206  INTERCEPT_FUNCTION(strtoul);
1207  INTERCEPT_FUNCTION(strtoull);
1208  INTERCEPT_FUNCTION(strtod);
1209  INTERCEPT_FUNCTION(strtof);
1210  INTERCEPT_FUNCTION(strtold);
1211  INTERCEPT_FUNCTION(vasprintf);
1212  INTERCEPT_FUNCTION(asprintf);
1213  INTERCEPT_FUNCTION(vsprintf);
1214  INTERCEPT_FUNCTION(vsnprintf);
1215  INTERCEPT_FUNCTION(vswprintf);
1216  INTERCEPT_FUNCTION(sprintf);  // NOLINT
1217  INTERCEPT_FUNCTION(snprintf);
1218  INTERCEPT_FUNCTION(swprintf);
1219  INTERCEPT_FUNCTION(strftime);
1220  INTERCEPT_FUNCTION(mbtowc);
1221  INTERCEPT_FUNCTION(mbrtowc);
1222  INTERCEPT_FUNCTION(wcslen);
1223  INTERCEPT_FUNCTION(wcschr);
1224  INTERCEPT_FUNCTION(wcscpy);
1225  INTERCEPT_FUNCTION(wcscmp);
1226  INTERCEPT_FUNCTION(wcstod);
1227  INTERCEPT_FUNCTION(getenv);
1228  INTERCEPT_FUNCTION(setenv);
1229  INTERCEPT_FUNCTION(putenv);
1230  INTERCEPT_FUNCTION(gettimeofday);
1231  INTERCEPT_FUNCTION(fcvt);
1232  INTERCEPT_FUNCTION(__fxstat);
1233  INTERCEPT_FUNCTION(__xstat);
1234  INTERCEPT_FUNCTION(__lxstat);
1235  INTERCEPT_FUNCTION(__fxstat64);
1236  INTERCEPT_FUNCTION(__xstat64);
1237  INTERCEPT_FUNCTION(__lxstat64);
1238  INTERCEPT_FUNCTION(pipe);
1239  INTERCEPT_FUNCTION(pipe2);
1240  INTERCEPT_FUNCTION(socketpair);
1241  INTERCEPT_FUNCTION(fgets);
1242  INTERCEPT_FUNCTION(fgets_unlocked);
1243  INTERCEPT_FUNCTION(getrlimit);
1244  INTERCEPT_FUNCTION(getrlimit64);
1245  INTERCEPT_FUNCTION(statfs);
1246  INTERCEPT_FUNCTION(fstatfs);
1247  INTERCEPT_FUNCTION(statfs64);
1248  INTERCEPT_FUNCTION(fstatfs64);
1249  INTERCEPT_FUNCTION(uname);
1250  INTERCEPT_FUNCTION(gethostname);
1251  INTERCEPT_FUNCTION(epoll_wait);
1252  INTERCEPT_FUNCTION(epoll_pwait);
1253  INTERCEPT_FUNCTION(recv);
1254  INTERCEPT_FUNCTION(recvfrom);
1255  INTERCEPT_FUNCTION(dladdr);
1256  INTERCEPT_FUNCTION(dlopen);
1257  INTERCEPT_FUNCTION(dl_iterate_phdr);
1258  INTERCEPT_FUNCTION(getrusage);
1259  INTERCEPT_FUNCTION(sigaction);
1260  INTERCEPT_FUNCTION(signal);
1261  INTERCEPT_FUNCTION(pthread_create);
1262  INTERCEPT_FUNCTION(pthread_key_create);
1263  INTERCEPT_FUNCTION(pthread_join);
1264  inited = 1;
1265}
1266}  // namespace __msan
1267