sanitizer_common_interceptors.inc revision 33b1485c3f1ea5a8089473ab1bb962d7bfb41d72
1//===-- sanitizer_common_interceptors.inc -----------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// Common function interceptors for tools like AddressSanitizer, 11// ThreadSanitizer, MemorySanitizer, etc. 12// 13// This file should be included into the tool's interceptor file, 14// which has to define it's own macros: 15// COMMON_INTERCEPTOR_ENTER 16// COMMON_INTERCEPTOR_READ_RANGE 17// COMMON_INTERCEPTOR_WRITE_RANGE 18// COMMON_INTERCEPTOR_FD_ACQUIRE 19// COMMON_INTERCEPTOR_FD_RELEASE 20// COMMON_INTERCEPTOR_SET_THREAD_NAME 21//===----------------------------------------------------------------------===// 22#include "interception/interception.h" 23#include "sanitizer_platform_interceptors.h" 24 25#include <stdarg.h> 26 27#if SANITIZER_WINDOWS 28#define va_copy(dst, src) ((dst) = (src)) 29#endif // _WIN32 30 31#if SANITIZER_INTERCEPT_STRCASECMP 32static inline int CharCaseCmp(unsigned char c1, unsigned char c2) { 33 int c1_low = ToLower(c1); 34 int c2_low = ToLower(c2); 35 return c1_low - c2_low; 36} 37 38INTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) { 39 void *ctx; 40 COMMON_INTERCEPTOR_ENTER(ctx, strcasecmp, s1, s2); 41 unsigned char c1 = 0, c2 = 0; 42 uptr i; 43 for (i = 0; ; i++) { 44 c1 = (unsigned char)s1[i]; 45 c2 = (unsigned char)s2[i]; 46 if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') 47 break; 48 } 49 COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, i + 1); 50 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, i + 1); 51 return CharCaseCmp(c1, c2); 52} 53 54INTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, SIZE_T n) { 55 void *ctx; 56 COMMON_INTERCEPTOR_ENTER(ctx, strncasecmp, s1, s2, n); 57 unsigned char c1 = 0, c2 = 0; 58 uptr i; 59 for (i = 0; i < n; i++) { 60 c1 = (unsigned char)s1[i]; 61 c2 = (unsigned char)s2[i]; 62 if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') 63 break; 64 } 65 COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, n)); 66 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, n)); 67 return CharCaseCmp(c1, c2); 68} 69 70#define INIT_STRCASECMP INTERCEPT_FUNCTION(strcasecmp) 71#define INIT_STRNCASECMP INTERCEPT_FUNCTION(strncasecmp) 72#else 73#define INIT_STRCASECMP 74#define INIT_STRNCASECMP 75#endif 76 77#if SANITIZER_INTERCEPT_FREXP 78INTERCEPTOR(double, frexp, double x, int *exp) { 79 void *ctx; 80 COMMON_INTERCEPTOR_ENTER(ctx, frexp, x, exp); 81 double res = REAL(frexp)(x, exp); 82 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp)); 83 return res; 84} 85 86#define INIT_FREXP INTERCEPT_FUNCTION(frexp); 87#else 88#define INIT_FREXP 89#endif // SANITIZER_INTERCEPT_FREXP 90 91#if SANITIZER_INTERCEPT_FREXPF_FREXPL 92INTERCEPTOR(float, frexpf, float x, int *exp) { 93 void *ctx; 94 COMMON_INTERCEPTOR_ENTER(ctx, frexpf, x, exp); 95 float res = REAL(frexpf)(x, exp); 96 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp)); 97 return res; 98} 99 100INTERCEPTOR(long double, frexpl, long double x, int *exp) { 101 void *ctx; 102 COMMON_INTERCEPTOR_ENTER(ctx, frexpl, x, exp); 103 long double res = REAL(frexpl)(x, exp); 104 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp)); 105 return res; 106} 107 108#define INIT_FREXPF_FREXPL \ 109 INTERCEPT_FUNCTION(frexpf); \ 110 INTERCEPT_FUNCTION(frexpl) 111#else 112#define INIT_FREXPF_FREXPL 113#endif // SANITIZER_INTERCEPT_FREXPF_FREXPL 114 115#if SANITIZER_INTERCEPT_READ 116INTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) { 117 void *ctx; 118 COMMON_INTERCEPTOR_ENTER(ctx, read, fd, ptr, count); 119 SSIZE_T res = REAL(read)(fd, ptr, count); 120 if (res > 0) 121 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); 122 if (res >= 0 && fd >= 0) 123 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 124 return res; 125} 126#define INIT_READ INTERCEPT_FUNCTION(read) 127#else 128#define INIT_READ 129#endif 130 131#if SANITIZER_INTERCEPT_PREAD 132INTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) { 133 void *ctx; 134 COMMON_INTERCEPTOR_ENTER(ctx, pread, fd, ptr, count, offset); 135 SSIZE_T res = REAL(pread)(fd, ptr, count, offset); 136 if (res > 0) 137 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); 138 if (res >= 0 && fd >= 0) 139 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 140 return res; 141} 142#define INIT_PREAD INTERCEPT_FUNCTION(pread) 143#else 144#define INIT_PREAD 145#endif 146 147#if SANITIZER_INTERCEPT_PREAD64 148INTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) { 149 void *ctx; 150 COMMON_INTERCEPTOR_ENTER(ctx, pread64, fd, ptr, count, offset); 151 SSIZE_T res = REAL(pread64)(fd, ptr, count, offset); 152 if (res > 0) 153 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); 154 if (res >= 0 && fd >= 0) 155 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 156 return res; 157} 158#define INIT_PREAD64 INTERCEPT_FUNCTION(pread64) 159#else 160#define INIT_PREAD64 161#endif 162 163#if SANITIZER_INTERCEPT_WRITE 164INTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) { 165 void *ctx; 166 COMMON_INTERCEPTOR_ENTER(ctx, write, fd, ptr, count); 167 if (fd >= 0) 168 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 169 SSIZE_T res = REAL(write)(fd, ptr, count); 170 if (res > 0) 171 COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); 172 return res; 173} 174#define INIT_WRITE INTERCEPT_FUNCTION(write) 175#else 176#define INIT_WRITE 177#endif 178 179#if SANITIZER_INTERCEPT_PWRITE 180INTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) { 181 void *ctx; 182 COMMON_INTERCEPTOR_ENTER(ctx, pwrite, fd, ptr, count, offset); 183 if (fd >= 0) 184 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 185 SSIZE_T res = REAL(pwrite)(fd, ptr, count, offset); 186 if (res > 0) 187 COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); 188 return res; 189} 190#define INIT_PWRITE INTERCEPT_FUNCTION(pwrite) 191#else 192#define INIT_PWRITE 193#endif 194 195#if SANITIZER_INTERCEPT_PWRITE64 196INTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count, 197 OFF64_T offset) { 198 void *ctx; 199 COMMON_INTERCEPTOR_ENTER(ctx, pwrite64, fd, ptr, count, offset); 200 if (fd >= 0) 201 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 202 SSIZE_T res = REAL(pwrite64)(fd, ptr, count, offset); 203 if (res > 0) 204 COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); 205 return res; 206} 207#define INIT_PWRITE64 INTERCEPT_FUNCTION(pwrite64) 208#else 209#define INIT_PWRITE64 210#endif 211 212#if SANITIZER_INTERCEPT_PRCTL 213INTERCEPTOR(int, prctl, int option, 214 unsigned long arg2, unsigned long arg3, // NOLINT 215 unsigned long arg4, unsigned long arg5) { // NOLINT 216 void *ctx; 217 COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5); 218 static const int PR_SET_NAME = 15; 219 int res = REAL(prctl(option, arg2, arg3, arg4, arg5)); 220 if (option == PR_SET_NAME) { 221 char buff[16]; 222 internal_strncpy(buff, (char *)arg2, 15); 223 buff[15] = 0; 224 COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff); 225 } 226 return res; 227} 228#define INIT_PRCTL INTERCEPT_FUNCTION(prctl) 229#else 230#define INIT_PRCTL 231#endif // SANITIZER_INTERCEPT_PRCTL 232 233 234#if SANITIZER_INTERCEPT_TIME 235INTERCEPTOR(unsigned long, time, unsigned long *t) { 236 void *ctx; 237 COMMON_INTERCEPTOR_ENTER(ctx, time, t); 238 unsigned long res = REAL(time)(t); 239 if (t && res != (unsigned long)-1) { 240 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, t, sizeof(*t)); 241 } 242 return res; 243} 244#define INIT_TIME \ 245 INTERCEPT_FUNCTION(time); 246#else 247#define INIT_TIME 248#endif // SANITIZER_INTERCEPT_TIME 249 250 251#if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS 252INTERCEPTOR(void *, localtime, unsigned long *timep) { 253 void *ctx; 254 COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep); 255 void *res = REAL(localtime)(timep); 256 if (res) { 257 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 258 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz); 259 } 260 return res; 261} 262INTERCEPTOR(void *, localtime_r, unsigned long *timep, void *result) { 263 void *ctx; 264 COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result); 265 void *res = REAL(localtime_r)(timep, result); 266 if (res) { 267 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 268 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz); 269 } 270 return res; 271} 272INTERCEPTOR(void *, gmtime, unsigned long *timep) { 273 void *ctx; 274 COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep); 275 void *res = REAL(gmtime)(timep); 276 if (res) { 277 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 278 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz); 279 } 280 return res; 281} 282INTERCEPTOR(void *, gmtime_r, unsigned long *timep, void *result) { 283 void *ctx; 284 COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result); 285 void *res = REAL(gmtime_r)(timep, result); 286 if (res) { 287 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 288 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz); 289 } 290 return res; 291} 292INTERCEPTOR(char *, ctime, unsigned long *timep) { 293 void *ctx; 294 COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep); 295 char *res = REAL(ctime)(timep); 296 if (res) { 297 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 298 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 299 } 300 return res; 301} 302INTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) { 303 void *ctx; 304 COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result); 305 char *res = REAL(ctime_r)(timep, result); 306 if (res) { 307 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 308 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 309 } 310 return res; 311} 312INTERCEPTOR(char *, asctime, void *tm) { 313 void *ctx; 314 COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm); 315 char *res = REAL(asctime)(tm); 316 if (res) { 317 COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, struct_tm_sz); 318 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 319 } 320 return res; 321} 322INTERCEPTOR(char *, asctime_r, void *tm, char *result) { 323 void *ctx; 324 COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result); 325 char *res = REAL(asctime_r)(tm, result); 326 if (res) { 327 COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, struct_tm_sz); 328 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 329 } 330 return res; 331} 332#define INIT_LOCALTIME_AND_FRIENDS \ 333 INTERCEPT_FUNCTION(localtime); \ 334 INTERCEPT_FUNCTION(localtime_r); \ 335 INTERCEPT_FUNCTION(gmtime); \ 336 INTERCEPT_FUNCTION(gmtime_r); \ 337 INTERCEPT_FUNCTION(ctime); \ 338 INTERCEPT_FUNCTION(ctime_r); \ 339 INTERCEPT_FUNCTION(asctime); \ 340 INTERCEPT_FUNCTION(asctime_r); 341#else 342#define INIT_LOCALTIME_AND_FRIENDS 343#endif // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS 344 345#if SANITIZER_INTERCEPT_SCANF 346 347#include "sanitizer_common_interceptors_scanf.inc" 348 349#define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...) \ 350 { \ 351 void *ctx; \ 352 COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__); \ 353 va_list aq; \ 354 va_copy(aq, ap); \ 355 int res = REAL(vname)(__VA_ARGS__); \ 356 if (res > 0) \ 357 scanf_common(ctx, res, allowGnuMalloc, format, aq); \ 358 va_end(aq); \ 359 return res; \ 360 } 361 362INTERCEPTOR(int, vscanf, const char *format, va_list ap) 363VSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap) 364 365INTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap) 366VSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap) 367 368INTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap) 369VSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap) 370 371#if SANITIZER_INTERCEPT_ISOC99_SCANF 372INTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap) 373VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap) 374 375INTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format, 376 va_list ap) 377VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap) 378 379INTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap) 380VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap) 381#endif // SANITIZER_INTERCEPT_ISOC99_SCANF 382 383#define SCANF_INTERCEPTOR_IMPL(name, vname, ...) \ 384 { \ 385 void *ctx; \ 386 COMMON_INTERCEPTOR_ENTER(ctx, name, __VA_ARGS__); \ 387 va_list ap; \ 388 va_start(ap, format); \ 389 int res = vname(__VA_ARGS__, ap); \ 390 va_end(ap); \ 391 return res; \ 392 } 393 394INTERCEPTOR(int, scanf, const char *format, ...) 395SCANF_INTERCEPTOR_IMPL(scanf, vscanf, format) 396 397INTERCEPTOR(int, fscanf, void *stream, const char *format, ...) 398SCANF_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format) 399 400INTERCEPTOR(int, sscanf, const char *str, const char *format, ...) 401SCANF_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format) 402 403#if SANITIZER_INTERCEPT_ISOC99_SCANF 404INTERCEPTOR(int, __isoc99_scanf, const char *format, ...) 405SCANF_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format) 406 407INTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...) 408SCANF_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format) 409 410INTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...) 411SCANF_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format) 412#endif 413 414#define INIT_SCANF \ 415 INTERCEPT_FUNCTION(scanf); \ 416 INTERCEPT_FUNCTION(sscanf); \ 417 INTERCEPT_FUNCTION(fscanf); \ 418 INTERCEPT_FUNCTION(vscanf); \ 419 INTERCEPT_FUNCTION(vsscanf); \ 420 INTERCEPT_FUNCTION(vfscanf); \ 421 INTERCEPT_FUNCTION(__isoc99_scanf); \ 422 INTERCEPT_FUNCTION(__isoc99_sscanf); \ 423 INTERCEPT_FUNCTION(__isoc99_fscanf); \ 424 INTERCEPT_FUNCTION(__isoc99_vscanf); \ 425 INTERCEPT_FUNCTION(__isoc99_vsscanf); \ 426 INTERCEPT_FUNCTION(__isoc99_vfscanf); 427 428#else 429#define INIT_SCANF 430#endif 431 432#if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS 433INTERCEPTOR(void *, getpwnam, const char *name) { 434 void *ctx; 435 COMMON_INTERCEPTOR_ENTER(ctx, getpwnam, name); 436 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 437 void *res = REAL(getpwnam)(name); 438 if (res != 0) 439 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_passwd_sz); 440 return res; 441} 442INTERCEPTOR(void *, getpwuid, u32 uid) { 443 void *ctx; 444 COMMON_INTERCEPTOR_ENTER(ctx, getpwuid, uid); 445 void *res = REAL(getpwuid)(uid); 446 if (res != 0) 447 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_passwd_sz); 448 return res; 449} 450INTERCEPTOR(void *, getgrnam, const char *name) { 451 void *ctx; 452 COMMON_INTERCEPTOR_ENTER(ctx, getgrnam, name); 453 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 454 void *res = REAL(getgrnam)(name); 455 if (res != 0) 456 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_group_sz); 457 return res; 458} 459INTERCEPTOR(void *, getgrgid, u32 gid) { 460 void *ctx; 461 COMMON_INTERCEPTOR_ENTER(ctx, getgrgid, gid); 462 void *res = REAL(getgrgid)(gid); 463 if (res != 0) 464 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_group_sz); 465 return res; 466} 467#define INIT_GETPWNAM_AND_FRIENDS \ 468 INTERCEPT_FUNCTION(getpwnam); \ 469 INTERCEPT_FUNCTION(getpwuid); \ 470 INTERCEPT_FUNCTION(getgrnam); \ 471 INTERCEPT_FUNCTION(getgrgid); 472#else 473#define INIT_GETPWNAM_AND_FRIENDS 474#endif 475 476 477#if SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS 478INTERCEPTOR(int, getpwnam_r, const char *name, void *pwd, 479 char *buf, SIZE_T buflen, void **result) { 480 void *ctx; 481 COMMON_INTERCEPTOR_ENTER(ctx, getpwnam_r, name, pwd, buf, buflen, result); 482 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 483 int res = REAL(getpwnam_r)(name, pwd, buf, buflen, result); 484 if (!res) { 485 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, struct_passwd_sz); 486 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 487 } 488 return res; 489} 490INTERCEPTOR(int, getpwuid_r, u32 uid, void *pwd, 491 char *buf, SIZE_T buflen, void **result) { 492 void *ctx; 493 COMMON_INTERCEPTOR_ENTER(ctx, getpwuid_r, uid, pwd, buf, buflen, result); 494 int res = REAL(getpwuid_r)(uid, pwd, buf, buflen, result); 495 if (!res) { 496 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, struct_passwd_sz); 497 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 498 } 499 return res; 500} 501INTERCEPTOR(int, getgrnam_r, const char *name, void *grp, 502 char *buf, SIZE_T buflen, void **result) { 503 void *ctx; 504 COMMON_INTERCEPTOR_ENTER(ctx, getgrnam_r, name, grp, buf, buflen, result); 505 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 506 int res = REAL(getgrnam_r)(name, grp, buf, buflen, result); 507 if (!res) { 508 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, struct_group_sz); 509 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 510 } 511 return res; 512} 513INTERCEPTOR(int, getgrgid_r, u32 gid, void *grp, 514 char *buf, SIZE_T buflen, void **result) { 515 void *ctx; 516 COMMON_INTERCEPTOR_ENTER(ctx, getgrgid_r, gid, grp, buf, buflen, result); 517 int res = REAL(getgrgid_r)(gid, grp, buf, buflen, result); 518 if (!res) { 519 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, struct_group_sz); 520 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 521 } 522 return res; 523} 524#define INIT_GETPWNAM_R_AND_FRIENDS \ 525 INTERCEPT_FUNCTION(getpwnam_r); \ 526 INTERCEPT_FUNCTION(getpwuid_r); \ 527 INTERCEPT_FUNCTION(getgrnam_r); \ 528 INTERCEPT_FUNCTION(getgrgid_r); 529#else 530#define INIT_GETPWNAM_R_AND_FRIENDS 531#endif 532 533 534#if SANITIZER_INTERCEPT_CLOCK_GETTIME 535INTERCEPTOR(int, clock_getres, u32 clk_id, void *tp) { 536 void *ctx; 537 COMMON_INTERCEPTOR_ENTER(ctx, clock_getres, clk_id, tp); 538 int res = REAL(clock_getres)(clk_id, tp); 539 if (!res && tp) { 540 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz); 541 } 542 return res; 543} 544INTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) { 545 void *ctx; 546 COMMON_INTERCEPTOR_ENTER(ctx, clock_gettime, clk_id, tp); 547 int res = REAL(clock_gettime)(clk_id, tp); 548 if (!res) { 549 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz); 550 } 551 return res; 552} 553INTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) { 554 void *ctx; 555 COMMON_INTERCEPTOR_ENTER(ctx, clock_settime, clk_id, tp); 556 COMMON_INTERCEPTOR_READ_RANGE(ctx, tp, struct_timespec_sz); 557 return REAL(clock_settime)(clk_id, tp); 558} 559#define INIT_CLOCK_GETTIME \ 560 INTERCEPT_FUNCTION(clock_getres); \ 561 INTERCEPT_FUNCTION(clock_gettime); \ 562 INTERCEPT_FUNCTION(clock_settime); 563#else 564#define INIT_CLOCK_GETTIME 565#endif 566 567 568#if SANITIZER_INTERCEPT_GETITIMER 569INTERCEPTOR(int, getitimer, int which, void *curr_value) { 570 void *ctx; 571 COMMON_INTERCEPTOR_ENTER(ctx, getitimer, which, curr_value); 572 int res = REAL(getitimer)(which, curr_value); 573 if (!res) { 574 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerval_sz); 575 } 576 return res; 577} 578INTERCEPTOR(int, setitimer, int which, const void *new_value, void *old_value) { 579 void *ctx; 580 COMMON_INTERCEPTOR_ENTER(ctx, setitimer, which, new_value, old_value); 581 COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerval_sz); 582 int res = REAL(setitimer)(which, new_value, old_value); 583 if (!res && old_value) { 584 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerval_sz); 585 } 586 return res; 587} 588#define INIT_GETITIMER \ 589 INTERCEPT_FUNCTION(getitimer); \ 590 INTERCEPT_FUNCTION(setitimer); 591#else 592#define INIT_GETITIMER 593#endif 594 595 596#if SANITIZER_INTERCEPT_GLOB 597struct sanitizer_glob_t { 598 SIZE_T gl_pathc; 599 char **gl_pathv; 600}; 601 602static void unpoison_glob_t(void *ctx, sanitizer_glob_t *pglob) { 603 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob)); 604 // +1 for NULL pointer at the end. 605 COMMON_INTERCEPTOR_WRITE_RANGE( 606 ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv)); 607 for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) { 608 char *p = pglob->gl_pathv[i]; 609 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, REAL(strlen)(p) + 1); 610 } 611} 612 613INTERCEPTOR(int, glob, const char *pattern, int flags, 614 int (*errfunc)(const char *epath, int eerrno), 615 sanitizer_glob_t *pglob) { 616 void *ctx; 617 COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob); 618 int res = REAL(glob)(pattern, flags, errfunc, pglob); 619 if (res == 0) 620 unpoison_glob_t(ctx, pglob); 621 return res; 622} 623 624INTERCEPTOR(int, glob64, const char *pattern, int flags, 625 int (*errfunc)(const char *epath, int eerrno), 626 sanitizer_glob_t *pglob) { 627 void *ctx; 628 COMMON_INTERCEPTOR_ENTER(ctx, glob64, pattern, flags, errfunc, pglob); 629 int res = REAL(glob64)(pattern, flags, errfunc, pglob); 630 if (res == 0) 631 unpoison_glob_t(ctx, pglob); 632 return res; 633} 634#define INIT_GLOB \ 635 INTERCEPT_FUNCTION(glob); \ 636 INTERCEPT_FUNCTION(glob64); 637#else // SANITIZER_INTERCEPT_GLOB 638#define INIT_GLOB 639#endif // SANITIZER_INTERCEPT_GLOB 640 641 642#if SANITIZER_INTERCEPT_WAIT 643// According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version 644// suffixes on Darwin. See the declaration of INTERCEPTOR_WITH_SUFFIX for 645// details. 646INTERCEPTOR_WITH_SUFFIX(int, wait, int *status) { 647 void *ctx; 648 COMMON_INTERCEPTOR_ENTER(ctx, wait, status); 649 int res = REAL(wait)(status); 650 if (res != -1 && status) 651 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 652 return res; 653} 654INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, int id, void *infop, 655 int options) { 656 void *ctx; 657 COMMON_INTERCEPTOR_ENTER(ctx, waitid, idtype, id, infop, options); 658 int res = REAL(waitid)(idtype, id, infop, options); 659 if (res != -1 && infop) 660 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, infop, siginfo_t_sz); 661 return res; 662} 663INTERCEPTOR_WITH_SUFFIX(int, waitpid, int pid, int *status, int options) { 664 void *ctx; 665 COMMON_INTERCEPTOR_ENTER(ctx, waitpid, pid, status, options); 666 int res = REAL(waitpid)(pid, status, options); 667 if (res != -1 && status) 668 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 669 return res; 670} 671INTERCEPTOR(int, wait3, int *status, int options, void *rusage) { 672 void *ctx; 673 COMMON_INTERCEPTOR_ENTER(ctx, wait3, status, options, rusage); 674 int res = REAL(wait3)(status, options, rusage); 675 if (res != -1) { 676 if (status) 677 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 678 if (rusage) 679 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz); 680 } 681 return res; 682} 683INTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) { 684 void *ctx; 685 COMMON_INTERCEPTOR_ENTER(ctx, wait4, pid, status, options, rusage); 686 int res = REAL(wait4)(pid, status, options, rusage); 687 if (res != -1) { 688 if (status) 689 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 690 if (rusage) 691 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz); 692 } 693 return res; 694} 695#define INIT_WAIT \ 696 INTERCEPT_FUNCTION(wait); \ 697 INTERCEPT_FUNCTION(waitid); \ 698 INTERCEPT_FUNCTION(waitpid); \ 699 INTERCEPT_FUNCTION(wait3); \ 700 INTERCEPT_FUNCTION(wait4); 701#else 702#define INIT_WAIT 703#endif 704 705#if SANITIZER_INTERCEPT_INET 706INTERCEPTOR(char *, inet_ntop, int af, const void *src, char *dst, u32 size) { 707 void *ctx; 708 COMMON_INTERCEPTOR_ENTER(ctx, inet_ntop, af, src, dst, size); 709 uptr sz = __sanitizer_in_addr_sz(af); 710 if (sz) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sz); 711 // FIXME: figure out read size based on the address family. 712 char *res = REAL(inet_ntop)(af, src, dst, size); 713 if (res) 714 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 715 return res; 716} 717INTERCEPTOR(int, inet_pton, int af, const char *src, void *dst) { 718 void *ctx; 719 COMMON_INTERCEPTOR_ENTER(ctx, inet_pton, af, src, dst); 720 // FIXME: figure out read size based on the address family. 721 int res = REAL(inet_pton)(af, src, dst); 722 if (res == 1) { 723 uptr sz = __sanitizer_in_addr_sz(af); 724 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz); 725 } 726 return res; 727} 728#define INIT_INET \ 729 INTERCEPT_FUNCTION(inet_ntop); \ 730 INTERCEPT_FUNCTION(inet_pton); 731#else 732#define INIT_INET 733#endif 734 735#if SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM 736INTERCEPTOR(int, pthread_getschedparam, uptr thread, int *policy, int *param) { 737 void *ctx; 738 COMMON_INTERCEPTOR_ENTER(ctx, pthread_getschedparam, thread, policy, param); 739 int res = REAL(pthread_getschedparam)(thread, policy, param); 740 if (res == 0) { 741 if (policy) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, policy, sizeof(*policy)); 742 if (param) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, sizeof(*param)); 743 } 744 return res; 745} 746#define INIT_PTHREAD_GETSCHEDPARAM INTERCEPT_FUNCTION(pthread_getschedparam); 747#else 748#define INIT_PTHREAD_GETSCHEDPARAM 749#endif 750 751#if SANITIZER_INTERCEPT_GETADDRINFO 752INTERCEPTOR(int, getaddrinfo, char *node, char *service, 753 struct __sanitizer_addrinfo *hints, 754 struct __sanitizer_addrinfo **out) { 755 void *ctx; 756 COMMON_INTERCEPTOR_ENTER(ctx, getaddrinfo, node, service, hints, out); 757 if (node) COMMON_INTERCEPTOR_READ_RANGE(ctx, node, REAL(strlen)(node) + 1); 758 if (service) 759 COMMON_INTERCEPTOR_READ_RANGE(ctx, service, REAL(strlen)(service) + 1); 760 if (hints) 761 COMMON_INTERCEPTOR_READ_RANGE(ctx, hints, sizeof(__sanitizer_addrinfo)); 762 int res = REAL(getaddrinfo)(node, service, hints, out); 763 if (res == 0) { 764 struct __sanitizer_addrinfo *p = *out; 765 while (p) { 766 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(__sanitizer_addrinfo)); 767 if (p->ai_addr) 768 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_addr, struct_sockaddr_sz); 769 if (p->ai_canonname) 770 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_canonname, 771 REAL(strlen)(p->ai_canonname) + 1); 772 p = p->ai_next; 773 } 774 } 775 return res; 776} 777#define INIT_GETADDRINFO INTERCEPT_FUNCTION(getaddrinfo); 778#else 779#define INIT_GETADDRINFO 780#endif 781 782#if SANITIZER_INTERCEPT_GETSOCKNAME 783INTERCEPTOR(int, getsockname, int sock_fd, void *addr, int *addrlen) { 784 void *ctx; 785 COMMON_INTERCEPTOR_ENTER(ctx, getsockname, sock_fd, addr, addrlen); 786 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 787 int addrlen_in = *addrlen; 788 int res = REAL(getsockname)(sock_fd, addr, addrlen); 789 if (res == 0) { 790 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addrlen_in, *addrlen)); 791 } 792 return res; 793} 794#define INIT_GETSOCKNAME INTERCEPT_FUNCTION(getsockname); 795#else 796#define INIT_GETSOCKNAME 797#endif 798 799#if SANITIZER_INTERCEPT_GETHOSTBYNAME || SANITIZER_INTERCEPT_GETHOSTBYNAME_R 800static void write_hostent(void *ctx, struct __sanitizer_hostent *h) { 801 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h, sizeof(__sanitizer_hostent)); 802 if (h->h_name) 803 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h->h_name, REAL(strlen)(h->h_name) + 1); 804 char **p = h->h_aliases; 805 while (*p) { 806 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1); 807 ++p; 808 } 809 COMMON_INTERCEPTOR_WRITE_RANGE( 810 ctx, h->h_aliases, (p - h->h_aliases + 1) * sizeof(*h->h_aliases)); 811 p = h->h_addr_list; 812 while (*p) { 813 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, h->h_length); 814 ++p; 815 } 816 COMMON_INTERCEPTOR_WRITE_RANGE( 817 ctx, h->h_addr_list, (p - h->h_addr_list + 1) * sizeof(*h->h_addr_list)); 818} 819#endif 820 821#if SANITIZER_INTERCEPT_GETHOSTBYNAME 822INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname, char *name) { 823 void *ctx; 824 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname, name); 825 struct __sanitizer_hostent *res = REAL(gethostbyname)(name); 826 if (res) write_hostent(ctx, res); 827 return res; 828} 829 830INTERCEPTOR(struct __sanitizer_hostent *, gethostbyaddr, void *addr, int len, 831 int type) { 832 void *ctx; 833 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr, addr, len, type); 834 COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len); 835 struct __sanitizer_hostent *res = REAL(gethostbyaddr)(addr, len, type); 836 if (res) write_hostent(ctx, res); 837 return res; 838} 839 840INTERCEPTOR(struct __sanitizer_hostent *, gethostent) { 841 void *ctx; 842 COMMON_INTERCEPTOR_ENTER(ctx, gethostent); 843 struct __sanitizer_hostent *res = REAL(gethostent)(); 844 if (res) write_hostent(ctx, res); 845 return res; 846} 847 848INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname2, char *name, int af) { 849 void *ctx; 850 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2, name, af); 851 struct __sanitizer_hostent *res = REAL(gethostbyname2)(name, af); 852 if (res) write_hostent(ctx, res); 853 return res; 854} 855#define INIT_GETHOSTBYNAME \ 856 INTERCEPT_FUNCTION(gethostent); \ 857 INTERCEPT_FUNCTION(gethostbyaddr); \ 858 INTERCEPT_FUNCTION(gethostbyname); \ 859 INTERCEPT_FUNCTION(gethostbyname2); 860#else 861#define INIT_GETHOSTBYNAME 862#endif 863 864#if SANITIZER_INTERCEPT_GETHOSTBYNAME_R 865INTERCEPTOR(int, gethostent_r, struct __sanitizer_hostent *ret, char *buf, 866 SIZE_T buflen, __sanitizer_hostent **result, int *h_errnop) { 867 void *ctx; 868 COMMON_INTERCEPTOR_ENTER(ctx, gethostent_r, ret, buf, buflen, result, 869 h_errnop); 870 int res = REAL(gethostent_r)(ret, buf, buflen, result, h_errnop); 871 if (res == 0) { 872 if (result) { 873 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 874 if (*result) write_hostent(ctx, *result); 875 } 876 if (h_errnop) 877 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 878 } 879 return res; 880} 881 882INTERCEPTOR(int, gethostbyaddr_r, void *addr, int len, int type, 883 struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen, 884 __sanitizer_hostent **result, int *h_errnop) { 885 void *ctx; 886 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr_r, addr, len, type, ret, buf, 887 buflen, result, h_errnop); 888 COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len); 889 int res = REAL(gethostbyaddr_r)(addr, len, type, ret, buf, buflen, result, 890 h_errnop); 891 if (res == 0) { 892 if (result) { 893 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 894 if (*result) write_hostent(ctx, *result); 895 } 896 if (h_errnop) 897 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 898 } 899 return res; 900} 901 902INTERCEPTOR(int, gethostbyname_r, char *name, struct __sanitizer_hostent *ret, 903 char *buf, SIZE_T buflen, __sanitizer_hostent **result, 904 int *h_errnop) { 905 void *ctx; 906 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname_r, name, ret, buf, buflen, result, 907 h_errnop); 908 int res = REAL(gethostbyname_r)(name, ret, buf, buflen, result, h_errnop); 909 if (res == 0) { 910 if (result) { 911 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 912 if (*result) write_hostent(ctx, *result); 913 } 914 if (h_errnop) 915 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 916 } 917 return res; 918} 919 920INTERCEPTOR(int, gethostbyname2_r, char *name, int af, 921 struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen, 922 __sanitizer_hostent **result, int *h_errnop) { 923 void *ctx; 924 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2_r, name, af, ret, buf, buflen, 925 result, h_errnop); 926 int res = 927 REAL(gethostbyname2_r)(name, af, ret, buf, buflen, result, h_errnop); 928 if (res == 0) { 929 if (result) { 930 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 931 if (*result) write_hostent(ctx, *result); 932 } 933 if (h_errnop) 934 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 935 } 936 return res; 937} 938#define INIT_GETHOSTBYNAME_R \ 939 INTERCEPT_FUNCTION(gethostent_r); \ 940 INTERCEPT_FUNCTION(gethostbyaddr_r); \ 941 INTERCEPT_FUNCTION(gethostbyname_r); \ 942 INTERCEPT_FUNCTION(gethostbyname2_r); 943#else 944#define INIT_GETHOSTBYNAME_R 945#endif 946 947#if SANITIZER_INTERCEPT_GETSOCKOPT 948INTERCEPTOR(int, getsockopt, int sockfd, int level, int optname, void *optval, 949 int *optlen) { 950 void *ctx; 951 COMMON_INTERCEPTOR_ENTER(ctx, getsockopt, sockfd, level, optname, optval, 952 optlen); 953 if (optlen) COMMON_INTERCEPTOR_READ_RANGE(ctx, optlen, sizeof(*optlen)); 954 int res = REAL(getsockopt)(sockfd, level, optname, optval, optlen); 955 if (res == 0) 956 if (optval && optlen) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, optval, *optlen); 957 return res; 958} 959#define INIT_GETSOCKOPT INTERCEPT_FUNCTION(getsockopt); 960#else 961#define INIT_GETSOCKOPT 962#endif 963 964#define SANITIZER_COMMON_INTERCEPTORS_INIT \ 965 INIT_STRCASECMP; \ 966 INIT_STRNCASECMP; \ 967 INIT_READ; \ 968 INIT_PREAD; \ 969 INIT_PREAD64; \ 970 INIT_PRCTL; \ 971 INIT_WRITE; \ 972 INIT_PWRITE; \ 973 INIT_PWRITE64; \ 974 INIT_LOCALTIME_AND_FRIENDS; \ 975 INIT_SCANF; \ 976 INIT_FREXP; \ 977 INIT_FREXPF_FREXPL; \ 978 INIT_GETPWNAM_AND_FRIENDS; \ 979 INIT_GETPWNAM_R_AND_FRIENDS; \ 980 INIT_CLOCK_GETTIME; \ 981 INIT_GETITIMER; \ 982 INIT_TIME; \ 983 INIT_GLOB; \ 984 INIT_WAIT; \ 985 INIT_INET; \ 986 INIT_PTHREAD_GETSCHEDPARAM; \ 987 INIT_GETADDRINFO; \ 988 INIT_GETSOCKNAME; \ 989 INIT_GETHOSTBYNAME; \ 990 INIT_GETHOSTBYNAME_R; \ 991 INIT_GETSOCKOPT; 992