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