• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
26 #include <stdarg.h>
27 // ACHTUNG! No other system header includes in this file.
28 // Ideally, we should get rid of stdarg.h as well.
29 
30 extern "C" const int __msan_keep_going;
31 
32 using namespace __msan;
33 
34 #define ENSURE_MSAN_INITED() do { \
35   CHECK(!msan_init_is_running); \
36   if (!msan_inited) { \
37     __msan_init(); \
38   } \
39 } while (0)
40 
41 #define CHECK_UNPOISONED(x, n) \
42   do { \
43     sptr offset = __msan_test_shadow(x, n);                 \
44     if (__msan::IsInSymbolizer()) break;                    \
45     if (offset >= 0 && flags()->report_umrs) {              \
46       GET_CALLER_PC_BP_SP;                                  \
47       (void)sp;                                             \
48       Printf("UMR in %s at offset %d inside [%p, +%d) \n",  \
49              __FUNCTION__, offset, x, n);                   \
50       __msan::PrintWarningWithOrigin(                       \
51         pc, bp, __msan_get_origin((char*)x + offset));      \
52       if (!__msan_keep_going) {                             \
53         Printf("Exiting\n");                                \
54         Die();                                              \
55       }                                                     \
56     }                                                       \
57   } while (0)
58 
59 static void *fast_memset(void *ptr, int c, SIZE_T n);
60 static void *fast_memcpy(void *dst, const void *src, SIZE_T n);
61 
INTERCEPTOR(SIZE_T,fread,void * ptr,SIZE_T size,SIZE_T nmemb,void * file)62 INTERCEPTOR(SIZE_T, fread, void *ptr, SIZE_T size, SIZE_T nmemb, void *file) {
63   ENSURE_MSAN_INITED();
64   SIZE_T res = REAL(fread)(ptr, size, nmemb, file);
65   if (res > 0)
66     __msan_unpoison(ptr, res *size);
67   return res;
68 }
69 
INTERCEPTOR(SIZE_T,fread_unlocked,void * ptr,SIZE_T size,SIZE_T nmemb,void * file)70 INTERCEPTOR(SIZE_T, fread_unlocked, void *ptr, SIZE_T size, SIZE_T nmemb,
71             void *file) {
72   ENSURE_MSAN_INITED();
73   SIZE_T res = REAL(fread_unlocked)(ptr, size, nmemb, file);
74   if (res > 0)
75     __msan_unpoison(ptr, res *size);
76   return res;
77 }
78 
INTERCEPTOR(SSIZE_T,readlink,const char * path,char * buf,SIZE_T bufsiz)79 INTERCEPTOR(SSIZE_T, readlink, const char *path, char *buf, SIZE_T bufsiz) {
80   ENSURE_MSAN_INITED();
81   SSIZE_T res = REAL(readlink)(path, buf, bufsiz);
82   if (res > 0)
83     __msan_unpoison(buf, res);
84   return res;
85 }
86 
INTERCEPTOR(void *,readdir,void * a)87 INTERCEPTOR(void *, readdir, void *a) {
88   ENSURE_MSAN_INITED();
89   void *res = REAL(readdir)(a);
90   __msan_unpoison(res, __sanitizer::struct_dirent_sz);
91   return res;
92 }
93 
INTERCEPTOR(void *,readdir64,void * a)94 INTERCEPTOR(void *, readdir64, void *a) {
95   ENSURE_MSAN_INITED();
96   void *res = REAL(readdir)(a);
97   __msan_unpoison(res, __sanitizer::struct_dirent64_sz);
98   return res;
99 }
100 
INTERCEPTOR(void *,memcpy,void * dest,const void * src,SIZE_T n)101 INTERCEPTOR(void *, memcpy, void *dest, const void *src, SIZE_T n) {
102   return __msan_memcpy(dest, src, n);
103 }
104 
INTERCEPTOR(void *,memmove,void * dest,const void * src,SIZE_T n)105 INTERCEPTOR(void *, memmove, void *dest, const void *src, SIZE_T n) {
106   return __msan_memmove(dest, src, n);
107 }
108 
INTERCEPTOR(void *,memset,void * s,int c,SIZE_T n)109 INTERCEPTOR(void *, memset, void *s, int c, SIZE_T n) {
110   return __msan_memset(s, c, n);
111 }
112 
INTERCEPTOR(int,posix_memalign,void ** memptr,SIZE_T alignment,SIZE_T size)113 INTERCEPTOR(int, posix_memalign, void **memptr, SIZE_T alignment, SIZE_T size) {
114   GET_MALLOC_STACK_TRACE;
115   CHECK_EQ(alignment & (alignment - 1), 0);
116   *memptr = MsanReallocate(&stack, 0, size, alignment, false);
117   CHECK_NE(memptr, 0);
118   return 0;
119 }
120 
INTERCEPTOR(void,free,void * ptr)121 INTERCEPTOR(void, free, void *ptr) {
122   ENSURE_MSAN_INITED();
123   if (ptr == 0) return;
124   MsanDeallocate(ptr);
125 }
126 
INTERCEPTOR(SIZE_T,strlen,const char * s)127 INTERCEPTOR(SIZE_T, strlen, const char *s) {
128   ENSURE_MSAN_INITED();
129   SIZE_T res = REAL(strlen)(s);
130   CHECK_UNPOISONED(s, res + 1);
131   return res;
132 }
133 
INTERCEPTOR(SIZE_T,strnlen,const char * s,SIZE_T n)134 INTERCEPTOR(SIZE_T, strnlen, const char *s, SIZE_T n) {
135   ENSURE_MSAN_INITED();
136   SIZE_T res = REAL(strnlen)(s, n);
137   SIZE_T scan_size = (res == n) ? res : res + 1;
138   CHECK_UNPOISONED(s, scan_size);
139   return res;
140 }
141 
142 // FIXME: Add stricter shadow checks in str* interceptors (ex.: strcpy should
143 // check the shadow of the terminating \0 byte).
144 
INTERCEPTOR(char *,strcpy,char * dest,const char * src)145 INTERCEPTOR(char *, strcpy, char *dest, const char *src) {  // NOLINT
146   ENSURE_MSAN_INITED();
147   SIZE_T n = REAL(strlen)(src);
148   char *res = REAL(strcpy)(dest, src);  // NOLINT
149   __msan_copy_poison(dest, src, n + 1);
150   return res;
151 }
152 
INTERCEPTOR(char *,strncpy,char * dest,const char * src,SIZE_T n)153 INTERCEPTOR(char *, strncpy, char *dest, const char *src, SIZE_T n) {  // NOLINT
154   ENSURE_MSAN_INITED();
155   SIZE_T copy_size = REAL(strnlen)(src, n);
156   if (copy_size < n)
157     copy_size++;  // trailing \0
158   char *res = REAL(strncpy)(dest, src, n);  // NOLINT
159   __msan_copy_poison(dest, src, copy_size);
160   return res;
161 }
162 
INTERCEPTOR(char *,strdup,char * src)163 INTERCEPTOR(char *, strdup, char *src) {
164   ENSURE_MSAN_INITED();
165   SIZE_T n = REAL(strlen)(src);
166   char *res = REAL(strdup)(src);
167   __msan_copy_poison(res, src, n + 1);
168   return res;
169 }
170 
INTERCEPTOR(char *,__strdup,char * src)171 INTERCEPTOR(char *, __strdup, char *src) {
172   ENSURE_MSAN_INITED();
173   SIZE_T n = REAL(strlen)(src);
174   char *res = REAL(__strdup)(src);
175   __msan_copy_poison(res, src, n + 1);
176   return res;
177 }
178 
INTERCEPTOR(char *,strndup,char * src,SIZE_T n)179 INTERCEPTOR(char *, strndup, char *src, SIZE_T n) {
180   ENSURE_MSAN_INITED();
181   SIZE_T copy_size = REAL(strnlen)(src, n);
182   char *res = REAL(strndup)(src, n);
183   __msan_copy_poison(res, src, copy_size);
184   __msan_unpoison(res + copy_size, 1); // \0
185   return res;
186 }
187 
INTERCEPTOR(char *,__strndup,char * src,SIZE_T n)188 INTERCEPTOR(char *, __strndup, char *src, SIZE_T n) {
189   ENSURE_MSAN_INITED();
190   SIZE_T copy_size = REAL(strnlen)(src, n);
191   char *res = REAL(__strndup)(src, n);
192   __msan_copy_poison(res, src, copy_size);
193   __msan_unpoison(res + copy_size, 1); // \0
194   return res;
195 }
196 
INTERCEPTOR(char *,gcvt,double number,SIZE_T ndigit,char * buf)197 INTERCEPTOR(char *, gcvt, double number, SIZE_T ndigit, char *buf) {
198   ENSURE_MSAN_INITED();
199   char *res = REAL(gcvt)(number, ndigit, buf);
200   // DynamoRio tool will take care of unpoisoning gcvt result for us.
201   if (!__msan_has_dynamic_component()) {
202     SIZE_T n = REAL(strlen)(buf);
203     __msan_unpoison(buf, n + 1);
204   }
205   return res;
206 }
207 
INTERCEPTOR(char *,strcat,char * dest,const char * src)208 INTERCEPTOR(char *, strcat, char *dest, const char *src) {  // NOLINT
209   ENSURE_MSAN_INITED();
210   SIZE_T src_size = REAL(strlen)(src);
211   SIZE_T dest_size = REAL(strlen)(dest);
212   char *res = REAL(strcat)(dest, src);  // NOLINT
213   __msan_copy_poison(dest + dest_size, src, src_size + 1);
214   return res;
215 }
216 
INTERCEPTOR(char *,strncat,char * dest,const char * src,SIZE_T n)217 INTERCEPTOR(char *, strncat, char *dest, const char *src, SIZE_T n) {  // NOLINT
218   ENSURE_MSAN_INITED();
219   SIZE_T dest_size = REAL(strlen)(dest);
220   SIZE_T copy_size = REAL(strlen)(src);
221   if (copy_size < n)
222     copy_size++;  // trailing \0
223   char *res = REAL(strncat)(dest, src, n);  // NOLINT
224   __msan_copy_poison(dest + dest_size, src, copy_size);
225   return res;
226 }
227 
INTERCEPTOR(long,strtol,const char * nptr,char ** endptr,int base)228 INTERCEPTOR(long, strtol, const char *nptr, char **endptr,  // NOLINT
229             int base) {
230   ENSURE_MSAN_INITED();
231   long res = REAL(strtol)(nptr, endptr, base);  // NOLINT
232   if (!__msan_has_dynamic_component()) {
233     __msan_unpoison(endptr, sizeof(*endptr));
234   }
235   return res;
236 }
237 
INTERCEPTOR(long long,strtoll,const char * nptr,char ** endptr,int base)238 INTERCEPTOR(long long, strtoll, const char *nptr, char **endptr,  // NOLINT
239             int base) {
240   ENSURE_MSAN_INITED();
241   long res = REAL(strtoll)(nptr, endptr, base);  //NOLINT
242   if (!__msan_has_dynamic_component()) {
243     __msan_unpoison(endptr, sizeof(*endptr));
244   }
245   return res;
246 }
247 
INTERCEPTOR(unsigned long,strtoul,const char * nptr,char ** endptr,int base)248 INTERCEPTOR(unsigned long, strtoul, const char *nptr, char **endptr,  // NOLINT
249             int base) {
250   ENSURE_MSAN_INITED();
251   unsigned long res = REAL(strtoul)(nptr, endptr, base);  // NOLINT
252   if (!__msan_has_dynamic_component()) {
253     __msan_unpoison(endptr, sizeof(*endptr));
254   }
255   return res;
256 }
257 
INTERCEPTOR(unsigned long long,strtoull,const char * nptr,char ** endptr,int base)258 INTERCEPTOR(unsigned long long, strtoull, const char *nptr,  // NOLINT
259             char **endptr, int base) {
260   ENSURE_MSAN_INITED();
261   unsigned long res = REAL(strtoull)(nptr, endptr, base);  // NOLINT
262   if (!__msan_has_dynamic_component()) {
263     __msan_unpoison(endptr, sizeof(*endptr));
264   }
265   return res;
266 }
267 
INTERCEPTOR(double,strtod,const char * nptr,char ** endptr)268 INTERCEPTOR(double, strtod, const char *nptr, char **endptr) {  // NOLINT
269   ENSURE_MSAN_INITED();
270   double res = REAL(strtod)(nptr, endptr);  // NOLINT
271   if (!__msan_has_dynamic_component()) {
272     __msan_unpoison(endptr, sizeof(*endptr));
273   }
274   return res;
275 }
276 
INTERCEPTOR(float,strtof,const char * nptr,char ** endptr)277 INTERCEPTOR(float, strtof, const char *nptr, char **endptr) {  // NOLINT
278   ENSURE_MSAN_INITED();
279   float res = REAL(strtof)(nptr, endptr);  // NOLINT
280   if (!__msan_has_dynamic_component()) {
281     __msan_unpoison(endptr, sizeof(*endptr));
282   }
283   return res;
284 }
285 
INTERCEPTOR(long double,strtold,const char * nptr,char ** endptr)286 INTERCEPTOR(long double, strtold, const char *nptr, char **endptr) {  // NOLINT
287   ENSURE_MSAN_INITED();
288   long double res = REAL(strtold)(nptr, endptr);  // NOLINT
289   if (!__msan_has_dynamic_component()) {
290     __msan_unpoison(endptr, sizeof(*endptr));
291   }
292   return res;
293 }
294 
INTERCEPTOR(int,vsnprintf,char * str,uptr size,const char * format,va_list ap)295 INTERCEPTOR(int, vsnprintf, char *str, uptr size,
296             const char *format, va_list ap) {
297   ENSURE_MSAN_INITED();
298   int res = REAL(vsnprintf)(str, size, format, ap);
299   if (!__msan_has_dynamic_component()) {
300     __msan_unpoison(str, res + 1);
301   }
302   return res;
303 }
304 
INTERCEPTOR(int,vsprintf,char * str,const char * format,va_list ap)305 INTERCEPTOR(int, vsprintf, char *str, const char *format, va_list ap) {
306   ENSURE_MSAN_INITED();
307   int res = REAL(vsprintf)(str, format, ap);
308   if (!__msan_has_dynamic_component()) {
309     __msan_unpoison(str, res + 1);
310   }
311   return res;
312 }
313 
INTERCEPTOR(int,vswprintf,void * str,uptr size,void * format,va_list ap)314 INTERCEPTOR(int, vswprintf, void *str, uptr size, void *format, va_list ap) {
315   ENSURE_MSAN_INITED();
316   int res = REAL(vswprintf)(str, size, format, ap);
317   if (!__msan_has_dynamic_component()) {
318     __msan_unpoison(str, 4 * (res + 1));
319   }
320   return res;
321 }
322 
INTERCEPTOR(int,sprintf,char * str,const char * format,...)323 INTERCEPTOR(int, sprintf, char *str, const char *format, ...) {  // NOLINT
324   ENSURE_MSAN_INITED();
325   va_list ap;
326   va_start(ap, format);
327   int res = vsprintf(str, format, ap);  // NOLINT
328   va_end(ap);
329   return res;
330 }
331 
INTERCEPTOR(int,snprintf,char * str,uptr size,const char * format,...)332 INTERCEPTOR(int, snprintf, char *str, uptr size, const char *format, ...) {
333   ENSURE_MSAN_INITED();
334   va_list ap;
335   va_start(ap, format);
336   int res = vsnprintf(str, size, format, ap);
337   va_end(ap);
338   return res;
339 }
340 
INTERCEPTOR(int,swprintf,void * str,uptr size,void * format,...)341 INTERCEPTOR(int, swprintf, void *str, uptr size, void *format, ...) {
342   ENSURE_MSAN_INITED();
343   va_list ap;
344   va_start(ap, format);
345   int res = vswprintf(str, size, format, ap);
346   va_end(ap);
347   return res;
348 }
349 
350 // SIZE_T strftime(char *s, SIZE_T max, const char *format,const struct tm *tm);
INTERCEPTOR(SIZE_T,strftime,char * s,SIZE_T max,const char * format,void * tm)351 INTERCEPTOR(SIZE_T, strftime, char *s, SIZE_T max, const char *format,
352             void *tm) {
353   ENSURE_MSAN_INITED();
354   SIZE_T res = REAL(strftime)(s, max, format, tm);
355   if (res) __msan_unpoison(s, res + 1);
356   return res;
357 }
358 
INTERCEPTOR(SIZE_T,wcstombs,void * dest,void * src,SIZE_T size)359 INTERCEPTOR(SIZE_T, wcstombs, void *dest, void *src, SIZE_T size) {
360   ENSURE_MSAN_INITED();
361   SIZE_T res = REAL(wcstombs)(dest, src, size);
362   if (res != (SIZE_T)-1) __msan_unpoison(dest, res + 1);
363   return res;
364 }
365 
366 // SIZE_T mbstowcs(wchar_t *dest, const char *src, SIZE_T n);
INTERCEPTOR(SIZE_T,mbstowcs,wchar_t * dest,const char * src,SIZE_T n)367 INTERCEPTOR(SIZE_T, mbstowcs, wchar_t *dest, const char *src, SIZE_T n) {
368   ENSURE_MSAN_INITED();
369   SIZE_T res = REAL(mbstowcs)(dest, src, n);
370   if (res != (SIZE_T)-1) __msan_unpoison(dest, (res + 1) * sizeof(wchar_t));
371   return res;
372 }
373 
INTERCEPTOR(SIZE_T,wcslen,const wchar_t * s)374 INTERCEPTOR(SIZE_T, wcslen, const wchar_t *s) {
375   ENSURE_MSAN_INITED();
376   SIZE_T res = REAL(wcslen)(s);
377   CHECK_UNPOISONED(s, sizeof(wchar_t) * (res + 1));
378   return res;
379 }
380 
381 // wchar_t *wcschr(const wchar_t *wcs, wchar_t wc);
INTERCEPTOR(wchar_t *,wcschr,void * s,wchar_t wc,void * ps)382 INTERCEPTOR(wchar_t *, wcschr, void *s, wchar_t wc, void *ps) {
383   ENSURE_MSAN_INITED();
384   wchar_t *res = REAL(wcschr)(s, wc, ps);
385   return res;
386 }
387 
388 // wchar_t *wcscpy(wchar_t *dest, const wchar_t *src);
INTERCEPTOR(wchar_t *,wcscpy,wchar_t * dest,const wchar_t * src)389 INTERCEPTOR(wchar_t *, wcscpy, wchar_t *dest, const wchar_t *src) {
390   ENSURE_MSAN_INITED();
391   wchar_t *res = REAL(wcscpy)(dest, src);
392   __msan_copy_poison(dest, src, sizeof(wchar_t) * (REAL(wcslen)(src) + 1));
393   return res;
394 }
395 
396 // wchar_t *wmemcpy(wchar_t *dest, const wchar_t *src, SIZE_T n);
INTERCEPTOR(wchar_t *,wmemcpy,wchar_t * dest,const wchar_t * src,SIZE_T n)397 INTERCEPTOR(wchar_t *, wmemcpy, wchar_t *dest, const wchar_t *src, SIZE_T n) {
398   ENSURE_MSAN_INITED();
399   wchar_t *res = REAL(wmemcpy)(dest, src, n);
400   __msan_copy_poison(dest, src, n * sizeof(wchar_t));
401   return res;
402 }
403 
INTERCEPTOR(wchar_t *,wmemset,wchar_t * s,wchar_t c,SIZE_T n)404 INTERCEPTOR(wchar_t *, wmemset, wchar_t *s, wchar_t c, SIZE_T n) {
405   CHECK(MEM_IS_APP(s));
406   ENSURE_MSAN_INITED();
407   wchar_t *res = (wchar_t *)fast_memset(s, c, n * sizeof(wchar_t));
408   __msan_unpoison(s, n * sizeof(wchar_t));
409   return res;
410 }
411 
INTERCEPTOR(wchar_t *,wmemmove,wchar_t * dest,const wchar_t * src,SIZE_T n)412 INTERCEPTOR(wchar_t *, wmemmove, wchar_t *dest, const wchar_t *src, SIZE_T n) {
413   ENSURE_MSAN_INITED();
414   wchar_t *res = REAL(wmemmove)(dest, src, n);
415   __msan_move_poison(dest, src, n * sizeof(wchar_t));
416   return res;
417 }
418 
INTERCEPTOR(int,wcscmp,const wchar_t * s1,const wchar_t * s2)419 INTERCEPTOR(int, wcscmp, const wchar_t *s1, const wchar_t *s2) {
420   ENSURE_MSAN_INITED();
421   int res = REAL(wcscmp)(s1, s2);
422   return res;
423 }
424 
INTERCEPTOR(double,wcstod,const wchar_t * nptr,wchar_t ** endptr)425 INTERCEPTOR(double, wcstod, const wchar_t *nptr, wchar_t **endptr) {
426   ENSURE_MSAN_INITED();
427   double res = REAL(wcstod)(nptr, endptr);
428   __msan_unpoison(endptr, sizeof(*endptr));
429   return res;
430 }
431 
432 // #define UNSUPPORTED(name) \
433 //   INTERCEPTOR(void, name, void) {                     \
434 //     Printf("MSAN: Unsupported %s\n", __FUNCTION__);   \
435 //     Die();                                            \
436 //   }
437 
438 // FIXME: intercept the following functions:
439 // Note, they only matter when running without a dynamic tool.
440 // UNSUPPORTED(wcscoll_l)
441 // UNSUPPORTED(wcsnrtombs)
442 // UNSUPPORTED(wcstol)
443 // UNSUPPORTED(wcstoll)
444 // UNSUPPORTED(wcstold)
445 // UNSUPPORTED(wcstoul)
446 // UNSUPPORTED(wcstoull)
447 // UNSUPPORTED(wcsxfrm_l)
448 // UNSUPPORTED(wcsdup)
449 // UNSUPPORTED(wcsftime)
450 // UNSUPPORTED(wcsstr)
451 // UNSUPPORTED(wcsrchr)
452 // UNSUPPORTED(wctob)
453 
INTERCEPTOR(int,gettimeofday,void * tv,void * tz)454 INTERCEPTOR(int, gettimeofday, void *tv, void *tz) {
455   ENSURE_MSAN_INITED();
456   int res = REAL(gettimeofday)(tv, tz);
457   if (tv)
458     __msan_unpoison(tv, 16);
459   if (tz)
460     __msan_unpoison(tz, 8);
461   return res;
462 }
463 
INTERCEPTOR(char *,fcvt,double x,int a,int * b,int * c)464 INTERCEPTOR(char *, fcvt, double x, int a, int *b, int *c) {
465   ENSURE_MSAN_INITED();
466   char *res = REAL(fcvt)(x, a, b, c);
467   if (!__msan_has_dynamic_component()) {
468     __msan_unpoison(b, sizeof(*b));
469     __msan_unpoison(c, sizeof(*c));
470   }
471   return res;
472 }
473 
INTERCEPTOR(char *,getenv,char * name)474 INTERCEPTOR(char *, getenv, char *name) {
475   ENSURE_MSAN_INITED();
476   char *res = REAL(getenv)(name);
477   if (!__msan_has_dynamic_component()) {
478     if (res)
479       __msan_unpoison(res, REAL(strlen)(res) + 1);
480   }
481   return res;
482 }
483 
INTERCEPTOR(int,__fxstat,int magic,int fd,void * buf)484 INTERCEPTOR(int, __fxstat, int magic, int fd, void *buf) {
485   ENSURE_MSAN_INITED();
486   int res = REAL(__fxstat)(magic, fd, buf);
487   if (!res)
488     __msan_unpoison(buf, __sanitizer::struct_stat_sz);
489   return res;
490 }
491 
INTERCEPTOR(int,__fxstat64,int magic,int fd,void * buf)492 INTERCEPTOR(int, __fxstat64, int magic, int fd, void *buf) {
493   ENSURE_MSAN_INITED();
494   int res = REAL(__fxstat64)(magic, fd, buf);
495   if (!res)
496     __msan_unpoison(buf, __sanitizer::struct_stat64_sz);
497   return res;
498 }
499 
INTERCEPTOR(int,__xstat,int magic,char * path,void * buf)500 INTERCEPTOR(int, __xstat, int magic, char *path, void *buf) {
501   ENSURE_MSAN_INITED();
502   int res = REAL(__xstat)(magic, path, buf);
503   if (!res)
504     __msan_unpoison(buf, __sanitizer::struct_stat_sz);
505   return res;
506 }
507 
INTERCEPTOR(int,__xstat64,int magic,char * path,void * buf)508 INTERCEPTOR(int, __xstat64, int magic, char *path, void *buf) {
509   ENSURE_MSAN_INITED();
510   int res = REAL(__xstat64)(magic, path, buf);
511   if (!res)
512     __msan_unpoison(buf, __sanitizer::struct_stat64_sz);
513   return res;
514 }
515 
INTERCEPTOR(int,__lxstat,int magic,char * path,void * buf)516 INTERCEPTOR(int, __lxstat, int magic, char *path, void *buf) {
517   ENSURE_MSAN_INITED();
518   int res = REAL(__lxstat)(magic, path, buf);
519   if (!res)
520     __msan_unpoison(buf, __sanitizer::struct_stat_sz);
521   return res;
522 }
523 
INTERCEPTOR(int,__lxstat64,int magic,char * path,void * buf)524 INTERCEPTOR(int, __lxstat64, int magic, char *path, void *buf) {
525   ENSURE_MSAN_INITED();
526   int res = REAL(__lxstat64)(magic, path, buf);
527   if (!res)
528     __msan_unpoison(buf, __sanitizer::struct_stat64_sz);
529   return res;
530 }
531 
INTERCEPTOR(int,pipe,int pipefd[2])532 INTERCEPTOR(int, pipe, int pipefd[2]) {
533   if (msan_init_is_running)
534     return REAL(pipe)(pipefd);
535   ENSURE_MSAN_INITED();
536   int res = REAL(pipe)(pipefd);
537   if (!res)
538     __msan_unpoison(pipefd, sizeof(int[2]));
539   return res;
540 }
541 
INTERCEPTOR(int,wait,int * status)542 INTERCEPTOR(int, wait, int *status) {
543   ENSURE_MSAN_INITED();
544   int res = REAL(wait)(status);
545   if (status)
546     __msan_unpoison(status, sizeof(*status));
547   return res;
548 }
549 
INTERCEPTOR(int,waitpid,int pid,int * status,int options)550 INTERCEPTOR(int, waitpid, int pid, int *status, int options) {
551   if (msan_init_is_running)
552     return REAL(waitpid)(pid, status, options);
553   ENSURE_MSAN_INITED();
554   int res = REAL(waitpid)(pid, status, options);
555   if (status)
556     __msan_unpoison(status, sizeof(*status));
557   return res;
558 }
559 
INTERCEPTOR(char *,fgets,char * s,int size,void * stream)560 INTERCEPTOR(char *, fgets, char *s, int size, void *stream) {
561   ENSURE_MSAN_INITED();
562   char *res = REAL(fgets)(s, size, stream);
563   if (res)
564     __msan_unpoison(s, REAL(strlen)(s) + 1);
565   return res;
566 }
567 
INTERCEPTOR(char *,fgets_unlocked,char * s,int size,void * stream)568 INTERCEPTOR(char *, fgets_unlocked, char *s, int size, void *stream) {
569   ENSURE_MSAN_INITED();
570   char *res = REAL(fgets_unlocked)(s, size, stream);
571   if (res)
572     __msan_unpoison(s, REAL(strlen)(s) + 1);
573   return res;
574 }
575 
INTERCEPTOR(char *,getcwd,char * buf,SIZE_T size)576 INTERCEPTOR(char *, getcwd, char *buf, SIZE_T size) {
577   ENSURE_MSAN_INITED();
578   char *res = REAL(getcwd)(buf, size);
579   if (res)
580     __msan_unpoison(res, REAL(strlen)(res) + 1);
581   return res;
582 }
583 
INTERCEPTOR(char *,realpath,char * path,char * abspath)584 INTERCEPTOR(char *, realpath, char *path, char *abspath) {
585   ENSURE_MSAN_INITED();
586   char *res = REAL(realpath)(path, abspath);
587   if (res)
588     __msan_unpoison(abspath, REAL(strlen)(abspath) + 1);
589   return res;
590 }
591 
INTERCEPTOR(int,getrlimit,int resource,void * rlim)592 INTERCEPTOR(int, getrlimit, int resource, void *rlim) {
593   if (msan_init_is_running)
594     return REAL(getrlimit)(resource, rlim);
595   ENSURE_MSAN_INITED();
596   int res = REAL(getrlimit)(resource, rlim);
597   if (!res)
598     __msan_unpoison(rlim, __sanitizer::struct_rlimit_sz);
599   return res;
600 }
601 
INTERCEPTOR(int,getrlimit64,int resource,void * rlim)602 INTERCEPTOR(int, getrlimit64, int resource, void *rlim) {
603   if (msan_init_is_running)
604     return REAL(getrlimit64)(resource, rlim);
605   ENSURE_MSAN_INITED();
606   int res = REAL(getrlimit64)(resource, rlim);
607   if (!res)
608     __msan_unpoison(rlim, __sanitizer::struct_rlimit64_sz);
609   return res;
610 }
611 
INTERCEPTOR(int,statfs,const char * s,void * buf)612 INTERCEPTOR(int, statfs, const char *s, void *buf) {
613   ENSURE_MSAN_INITED();
614   int res = REAL(statfs)(s, buf);
615   if (!res)
616     __msan_unpoison(buf, __sanitizer::struct_statfs_sz);
617   return res;
618 }
619 
INTERCEPTOR(int,fstatfs,int fd,void * buf)620 INTERCEPTOR(int, fstatfs, int fd, void *buf) {
621   ENSURE_MSAN_INITED();
622   int res = REAL(fstatfs)(fd, buf);
623   if (!res)
624     __msan_unpoison(buf, __sanitizer::struct_statfs_sz);
625   return res;
626 }
627 
INTERCEPTOR(int,statfs64,const char * s,void * buf)628 INTERCEPTOR(int, statfs64, const char *s, void *buf) {
629   ENSURE_MSAN_INITED();
630   int res = REAL(statfs64)(s, buf);
631   if (!res)
632     __msan_unpoison(buf, __sanitizer::struct_statfs64_sz);
633   return res;
634 }
635 
INTERCEPTOR(int,fstatfs64,int fd,void * buf)636 INTERCEPTOR(int, fstatfs64, int fd, void *buf) {
637   ENSURE_MSAN_INITED();
638   int res = REAL(fstatfs64)(fd, buf);
639   if (!res)
640     __msan_unpoison(buf, __sanitizer::struct_statfs64_sz);
641   return res;
642 }
643 
INTERCEPTOR(int,uname,void * utsname)644 INTERCEPTOR(int, uname, void *utsname) {
645   ENSURE_MSAN_INITED();
646   int res = REAL(uname)(utsname);
647   if (!res) {
648     __msan_unpoison(utsname, __sanitizer::struct_utsname_sz);
649   }
650   return res;
651 }
652 
INTERCEPTOR(int,gethostname,char * name,SIZE_T len)653 INTERCEPTOR(int, gethostname, char *name, SIZE_T len) {
654   ENSURE_MSAN_INITED();
655   int res = REAL(gethostname)(name, len);
656   if (!res) {
657     SIZE_T real_len = REAL(strnlen)(name, len);
658     if (real_len < len)
659       ++real_len;
660     __msan_unpoison(name, real_len);
661   }
662   return res;
663 }
664 
INTERCEPTOR(int,epoll_wait,int epfd,void * events,int maxevents,int timeout)665 INTERCEPTOR(int, epoll_wait, int epfd, void *events, int maxevents,
666     int timeout) {
667   ENSURE_MSAN_INITED();
668   int res = REAL(epoll_wait)(epfd, events, maxevents, timeout);
669   if (res > 0) {
670     __msan_unpoison(events, __sanitizer::struct_epoll_event_sz * res);
671   }
672   return res;
673 }
674 
INTERCEPTOR(int,epoll_pwait,int epfd,void * events,int maxevents,int timeout,void * sigmask)675 INTERCEPTOR(int, epoll_pwait, int epfd, void *events, int maxevents,
676     int timeout, void *sigmask) {
677   ENSURE_MSAN_INITED();
678   int res = REAL(epoll_pwait)(epfd, events, maxevents, timeout, sigmask);
679   if (res > 0) {
680     __msan_unpoison(events, __sanitizer::struct_epoll_event_sz * res);
681   }
682   return res;
683 }
684 
INTERCEPTOR(SSIZE_T,recv,int fd,void * buf,SIZE_T len,int flags)685 INTERCEPTOR(SSIZE_T, recv, int fd, void *buf, SIZE_T len, int flags) {
686   ENSURE_MSAN_INITED();
687   SSIZE_T res = REAL(recv)(fd, buf, len, flags);
688   if (res > 0)
689     __msan_unpoison(buf, res);
690   return res;
691 }
692 
INTERCEPTOR(SSIZE_T,recvfrom,int fd,void * buf,SIZE_T len,int flags,void * srcaddr,void * addrlen)693 INTERCEPTOR(SSIZE_T, recvfrom, int fd, void *buf, SIZE_T len, int flags,
694     void *srcaddr, void *addrlen) {
695   ENSURE_MSAN_INITED();
696   SIZE_T srcaddr_sz;
697   if (srcaddr)
698     srcaddr_sz = __sanitizer_get_socklen_t(addrlen);
699   SSIZE_T res = REAL(recvfrom)(fd, buf, len, flags, srcaddr, addrlen);
700   if (res > 0) {
701     __msan_unpoison(buf, res);
702     if (srcaddr) {
703       SIZE_T sz = __sanitizer_get_socklen_t(addrlen);
704       __msan_unpoison(srcaddr, (sz < srcaddr_sz) ? sz : srcaddr_sz);
705     }
706   }
707   return res;
708 }
709 
INTERCEPTOR(SSIZE_T,recvmsg,int fd,struct msghdr * msg,int flags)710 INTERCEPTOR(SSIZE_T, recvmsg, int fd, struct msghdr *msg, int flags) {
711   ENSURE_MSAN_INITED();
712   SSIZE_T res = REAL(recvmsg)(fd, msg, flags);
713   if (res > 0) {
714     for (SIZE_T i = 0; i < __sanitizer_get_msghdr_iovlen(msg); ++i)
715       __msan_unpoison(__sanitizer_get_msghdr_iov_iov_base(msg, i),
716           __sanitizer_get_msghdr_iov_iov_len(msg, i));
717   }
718   return res;
719 }
720 
INTERCEPTOR(void *,calloc,SIZE_T nmemb,SIZE_T size)721 INTERCEPTOR(void *, calloc, SIZE_T nmemb, SIZE_T size) {
722   if (CallocShouldReturnNullDueToOverflow(size, nmemb)) return 0;
723   GET_MALLOC_STACK_TRACE;
724   if (!msan_inited) {
725     // Hack: dlsym calls calloc before REAL(calloc) is retrieved from dlsym.
726     const SIZE_T kCallocPoolSize = 1024;
727     static uptr calloc_memory_for_dlsym[kCallocPoolSize];
728     static SIZE_T allocated;
729     SIZE_T size_in_words = ((nmemb * size) + kWordSize - 1) / kWordSize;
730     void *mem = (void*)&calloc_memory_for_dlsym[allocated];
731     allocated += size_in_words;
732     CHECK(allocated < kCallocPoolSize);
733     return mem;
734   }
735   return MsanReallocate(&stack, 0, nmemb * size, sizeof(u64), true);
736 }
737 
INTERCEPTOR(void *,realloc,void * ptr,SIZE_T size)738 INTERCEPTOR(void *, realloc, void *ptr, SIZE_T size) {
739   GET_MALLOC_STACK_TRACE;
740   return MsanReallocate(&stack, ptr, size, sizeof(u64), false);
741 }
742 
INTERCEPTOR(void *,malloc,SIZE_T size)743 INTERCEPTOR(void *, malloc, SIZE_T size) {
744   GET_MALLOC_STACK_TRACE;
745   return MsanReallocate(&stack, 0, size, sizeof(u64), false);
746 }
747 
__msan_allocated_memory(void * data,uptr size)748 void __msan_allocated_memory(void* data, uptr size) {
749   GET_MALLOC_STACK_TRACE;
750   if (flags()->poison_in_malloc)
751     __msan_poison(data, size);
752   if (__msan_get_track_origins()) {
753     u32 stack_id = StackDepotPut(stack.trace, stack.size);
754     CHECK(stack_id);
755     CHECK_EQ((stack_id >> 31), 0);  // Higher bit is occupied by stack origins.
756     __msan_set_origin(data, size, stack_id);
757   }
758 }
759 
INTERCEPTOR(void *,mmap,void * addr,SIZE_T length,int prot,int flags,int fd,OFF_T offset)760 INTERCEPTOR(void *, mmap, void *addr, SIZE_T length, int prot, int flags,
761             int fd, OFF_T offset) {
762   ENSURE_MSAN_INITED();
763   void *res = REAL(mmap)(addr, length, prot, flags, fd, offset);
764   if (res != (void*)-1)
765     __msan_unpoison(res, RoundUpTo(length, GetPageSize()));
766   return res;
767 }
768 
INTERCEPTOR(void *,mmap64,void * addr,SIZE_T length,int prot,int flags,int fd,OFF64_T offset)769 INTERCEPTOR(void *, mmap64, void *addr, SIZE_T length, int prot, int flags,
770             int fd, OFF64_T offset) {
771   ENSURE_MSAN_INITED();
772   void *res = REAL(mmap64)(addr, length, prot, flags, fd, offset);
773   if (res != (void*)-1)
774     __msan_unpoison(res, RoundUpTo(length, GetPageSize()));
775   return res;
776 }
777 
778 struct dlinfo {
779   char *dli_fname;
780   void *dli_fbase;
781   char *dli_sname;
782   void *dli_saddr;
783 };
784 
INTERCEPTOR(int,dladdr,void * addr,dlinfo * info)785 INTERCEPTOR(int, dladdr, void *addr, dlinfo *info) {
786   ENSURE_MSAN_INITED();
787   int res = REAL(dladdr)(addr, info);
788   if (res != 0) {
789     __msan_unpoison(info, sizeof(*info));
790     if (info->dli_fname)
791       __msan_unpoison(info->dli_fname, REAL(strlen)(info->dli_fname) + 1);
792     if (info->dli_sname)
793       __msan_unpoison(info->dli_sname, REAL(strlen)(info->dli_sname) + 1);
794   }
795   return res;
796 }
797 
798 // dlopen() ultimately calls mmap() down inside the loader, which generally
799 // doesn't participate in dynamic symbol resolution.  Therefore we won't
800 // intercept its calls to mmap, and we have to hook it here.  The loader
801 // initializes the module before returning, so without the dynamic component, we
802 // won't be able to clear the shadow before the initializers.  Fixing this would
803 // require putting our own initializer first to clear the shadow.
INTERCEPTOR(void *,dlopen,const char * filename,int flag)804 INTERCEPTOR(void *, dlopen, const char *filename, int flag) {
805   ENSURE_MSAN_INITED();
806   EnterLoader();
807   link_map *map = (link_map *)REAL(dlopen)(filename, flag);
808   ExitLoader();
809   if (!__msan_has_dynamic_component()) {
810     // If msandr didn't clear the shadow before the initializers ran, we do it
811     // ourselves afterwards.
812     UnpoisonMappedDSO(map);
813   }
814   return (void *)map;
815 }
816 
INTERCEPTOR(int,getrusage,int who,void * usage)817 INTERCEPTOR(int, getrusage, int who, void *usage) {
818   ENSURE_MSAN_INITED();
819   int res = REAL(getrusage)(who, usage);
820   if (res == 0) {
821     __msan_unpoison(usage, __sanitizer::struct_rusage_sz);
822   }
823   return res;
824 }
825 
826 extern "C" int pthread_attr_init(void *attr);
827 extern "C" int pthread_attr_destroy(void *attr);
828 extern "C" int pthread_attr_setstacksize(void *attr, uptr stacksize);
829 extern "C" int pthread_attr_getstacksize(void *attr, uptr *stacksize);
830 
INTERCEPTOR(int,pthread_create,void * th,void * attr,void * (* callback)(void *),void * param)831 INTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void*),
832             void * param) {
833   ENSURE_MSAN_INITED(); // for GetTlsSize()
834   __sanitizer_pthread_attr_t myattr;
835   if (attr == 0) {
836     pthread_attr_init(&myattr);
837     attr = &myattr;
838   }
839   uptr stacksize = 0;
840   pthread_attr_getstacksize(attr, &stacksize);
841   // We place the huge ThreadState object into TLS, account for that.
842   const uptr minstacksize = GetTlsSize() + 128*1024;
843   if (stacksize < minstacksize) {
844     if (flags()->verbosity)
845       Printf("MemorySanitizer: increasing stacksize %zu->%zu\n", stacksize,
846              minstacksize);
847     pthread_attr_setstacksize(attr, minstacksize);
848   }
849 
850   int res = REAL(pthread_create)(th, attr, callback, param);
851   if (attr == &myattr)
852     pthread_attr_destroy(&myattr);
853   return res;
854 }
855 
856 #define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \
857     __msan_unpoison(ptr, size)
858 #define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) do { } while (false)
859 #define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \
860   do {                                           \
861     ctx = 0;                                     \
862     (void)ctx;                                   \
863     ENSURE_MSAN_INITED();                        \
864   } while (false)
865 #define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) do { } while (false)
866 #define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) do { } while (false)
867 #define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) \
868   do { } while (false)  // FIXME
869 #include "sanitizer_common/sanitizer_common_interceptors.inc"
870 
871 // static
fast_memset(void * ptr,int c,SIZE_T n)872 void *fast_memset(void *ptr, int c, SIZE_T n) {
873   // hack until we have a really fast internal_memset
874   if (sizeof(uptr) == 8 &&
875       (n % 8) == 0 &&
876       ((uptr)ptr % 8) == 0 &&
877       (c == 0 || c == -1)) {
878     // Printf("memset %p %zd %x\n", ptr, n, c);
879     uptr to_store = c ? -1L : 0L;
880     uptr *p = (uptr*)ptr;
881     for (SIZE_T i = 0; i < n / 8; i++)
882       p[i] = to_store;
883     return ptr;
884   }
885   return internal_memset(ptr, c, n);
886 }
887 
888 // static
fast_memcpy(void * dst,const void * src,SIZE_T n)889 void *fast_memcpy(void *dst, const void *src, SIZE_T n) {
890   // Same hack as in fast_memset above.
891   if (sizeof(uptr) == 8 &&
892       (n % 8) == 0 &&
893       ((uptr)dst % 8) == 0 &&
894       ((uptr)src % 8) == 0) {
895     uptr *d = (uptr*)dst;
896     uptr *s = (uptr*)src;
897     for (SIZE_T i = 0; i < n / 8; i++)
898       d[i] = s[i];
899     return dst;
900   }
901   return internal_memcpy(dst, src, n);
902 }
903 
904 // These interface functions reside here so that they can use
905 // fast_memset, etc.
__msan_unpoison(void * a,uptr size)906 void __msan_unpoison(void *a, uptr size) {
907   if (!MEM_IS_APP(a)) return;
908   fast_memset((void*)MEM_TO_SHADOW((uptr)a), 0, size);
909 }
910 
__msan_poison(void * a,uptr size)911 void __msan_poison(void *a, uptr size) {
912   if (!MEM_IS_APP(a)) return;
913   fast_memset((void*)MEM_TO_SHADOW((uptr)a),
914               __msan::flags()->poison_heap_with_zeroes ? 0 : -1, size);
915 }
916 
__msan_poison_stack(void * a,uptr size)917 void __msan_poison_stack(void *a, uptr size) {
918   if (!MEM_IS_APP(a)) return;
919   fast_memset((void*)MEM_TO_SHADOW((uptr)a),
920               __msan::flags()->poison_stack_with_zeroes ? 0 : -1, size);
921 }
922 
__msan_clear_and_unpoison(void * a,uptr size)923 void __msan_clear_and_unpoison(void *a, uptr size) {
924   fast_memset(a, 0, size);
925   fast_memset((void*)MEM_TO_SHADOW((uptr)a), 0, size);
926 }
927 
__msan_copy_origin(void * dst,const void * src,uptr size)928 void __msan_copy_origin(void *dst, const void *src, uptr size) {
929   if (!__msan_get_track_origins()) return;
930   if (!MEM_IS_APP(dst) || !MEM_IS_APP(src)) return;
931   uptr d = MEM_TO_ORIGIN(dst);
932   uptr s = MEM_TO_ORIGIN(src);
933   uptr beg = d & ~3UL;  // align down.
934   uptr end = (d + size + 3) & ~3UL;  // align up.
935   s = s & ~3UL;  // align down.
936   fast_memcpy((void*)beg, (void*)s, end - beg);
937 }
938 
__msan_copy_poison(void * dst,const void * src,uptr size)939 void __msan_copy_poison(void *dst, const void *src, uptr size) {
940   if (!MEM_IS_APP(dst)) return;
941   if (!MEM_IS_APP(src)) return;
942   fast_memcpy((void*)MEM_TO_SHADOW((uptr)dst),
943               (void*)MEM_TO_SHADOW((uptr)src), size);
944   __msan_copy_origin(dst, src, size);
945 }
946 
__msan_move_poison(void * dst,const void * src,uptr size)947 void __msan_move_poison(void *dst, const void *src, uptr size) {
948   if (!MEM_IS_APP(dst)) return;
949   if (!MEM_IS_APP(src)) return;
950   internal_memmove((void*)MEM_TO_SHADOW((uptr)dst),
951          (void*)MEM_TO_SHADOW((uptr)src), size);
952   __msan_copy_origin(dst, src, size);
953 }
954 
__msan_memcpy(void * dest,const void * src,SIZE_T n)955 void *__msan_memcpy(void *dest, const void *src, SIZE_T n) {
956   ENSURE_MSAN_INITED();
957   void *res = fast_memcpy(dest, src, n);
958   __msan_copy_poison(dest, src, n);
959   return res;
960 }
961 
__msan_memset(void * s,int c,SIZE_T n)962 void *__msan_memset(void *s, int c, SIZE_T n) {
963   ENSURE_MSAN_INITED();
964   void *res = fast_memset(s, c, n);
965   __msan_unpoison(s, n);
966   return res;
967 }
968 
__msan_memmove(void * dest,const void * src,SIZE_T n)969 void *__msan_memmove(void *dest, const void *src, SIZE_T n) {
970   ENSURE_MSAN_INITED();
971   void *res = REAL(memmove)(dest, src, n);
972   __msan_move_poison(dest, src, n);
973   return res;
974 }
975 
976 namespace __msan {
InitializeInterceptors()977 void InitializeInterceptors() {
978   static int inited = 0;
979   CHECK_EQ(inited, 0);
980   SANITIZER_COMMON_INTERCEPTORS_INIT;
981 
982   INTERCEPT_FUNCTION(mmap);
983   INTERCEPT_FUNCTION(mmap64);
984   INTERCEPT_FUNCTION(posix_memalign);
985   INTERCEPT_FUNCTION(malloc);
986   INTERCEPT_FUNCTION(calloc);
987   INTERCEPT_FUNCTION(realloc);
988   INTERCEPT_FUNCTION(free);
989   INTERCEPT_FUNCTION(fread);
990   INTERCEPT_FUNCTION(fread_unlocked);
991   INTERCEPT_FUNCTION(readlink);
992   INTERCEPT_FUNCTION(readdir);
993   INTERCEPT_FUNCTION(readdir64);
994   INTERCEPT_FUNCTION(memcpy);
995   INTERCEPT_FUNCTION(memset);
996   INTERCEPT_FUNCTION(memmove);
997   INTERCEPT_FUNCTION(wmemset);
998   INTERCEPT_FUNCTION(wmemcpy);
999   INTERCEPT_FUNCTION(wmemmove);
1000   INTERCEPT_FUNCTION(strcpy);  // NOLINT
1001   INTERCEPT_FUNCTION(strdup);
1002   INTERCEPT_FUNCTION(__strdup);
1003   INTERCEPT_FUNCTION(strndup);
1004   INTERCEPT_FUNCTION(__strndup);
1005   INTERCEPT_FUNCTION(strncpy);  // NOLINT
1006   INTERCEPT_FUNCTION(strlen);
1007   INTERCEPT_FUNCTION(strnlen);
1008   INTERCEPT_FUNCTION(gcvt);
1009   INTERCEPT_FUNCTION(strcat);  // NOLINT
1010   INTERCEPT_FUNCTION(strncat);  // NOLINT
1011   INTERCEPT_FUNCTION(strtol);
1012   INTERCEPT_FUNCTION(strtoll);
1013   INTERCEPT_FUNCTION(strtoul);
1014   INTERCEPT_FUNCTION(strtoull);
1015   INTERCEPT_FUNCTION(strtod);
1016   INTERCEPT_FUNCTION(strtof);
1017   INTERCEPT_FUNCTION(strtold);
1018   INTERCEPT_FUNCTION(vsprintf);
1019   INTERCEPT_FUNCTION(vsnprintf);
1020   INTERCEPT_FUNCTION(vswprintf);
1021   INTERCEPT_FUNCTION(sprintf);  // NOLINT
1022   INTERCEPT_FUNCTION(snprintf);
1023   INTERCEPT_FUNCTION(swprintf);
1024   INTERCEPT_FUNCTION(strftime);
1025   INTERCEPT_FUNCTION(wcstombs);
1026   INTERCEPT_FUNCTION(mbstowcs);
1027   INTERCEPT_FUNCTION(wcslen);
1028   INTERCEPT_FUNCTION(wcschr);
1029   INTERCEPT_FUNCTION(wcscpy);
1030   INTERCEPT_FUNCTION(wcscmp);
1031   INTERCEPT_FUNCTION(wcstod);
1032   INTERCEPT_FUNCTION(getenv);
1033   INTERCEPT_FUNCTION(gettimeofday);
1034   INTERCEPT_FUNCTION(fcvt);
1035   INTERCEPT_FUNCTION(__fxstat);
1036   INTERCEPT_FUNCTION(__xstat);
1037   INTERCEPT_FUNCTION(__lxstat);
1038   INTERCEPT_FUNCTION(__fxstat64);
1039   INTERCEPT_FUNCTION(__xstat64);
1040   INTERCEPT_FUNCTION(__lxstat64);
1041   INTERCEPT_FUNCTION(pipe);
1042   INTERCEPT_FUNCTION(wait);
1043   INTERCEPT_FUNCTION(waitpid);
1044   INTERCEPT_FUNCTION(fgets);
1045   INTERCEPT_FUNCTION(fgets_unlocked);
1046   INTERCEPT_FUNCTION(getcwd);
1047   INTERCEPT_FUNCTION(realpath);
1048   INTERCEPT_FUNCTION(getrlimit);
1049   INTERCEPT_FUNCTION(getrlimit64);
1050   INTERCEPT_FUNCTION(statfs);
1051   INTERCEPT_FUNCTION(fstatfs);
1052   INTERCEPT_FUNCTION(statfs64);
1053   INTERCEPT_FUNCTION(fstatfs64);
1054   INTERCEPT_FUNCTION(uname);
1055   INTERCEPT_FUNCTION(gethostname);
1056   INTERCEPT_FUNCTION(epoll_wait);
1057   INTERCEPT_FUNCTION(epoll_pwait);
1058   INTERCEPT_FUNCTION(recv);
1059   INTERCEPT_FUNCTION(recvfrom);
1060   INTERCEPT_FUNCTION(recvmsg);
1061   INTERCEPT_FUNCTION(dladdr);
1062   INTERCEPT_FUNCTION(dlopen);
1063   INTERCEPT_FUNCTION(getrusage);
1064   INTERCEPT_FUNCTION(pthread_create);
1065   inited = 1;
1066 }
1067 }  // namespace __msan
1068