sanitizer_common_interceptors.inc revision 12eb79dd701d9d40551759330a9257316601373b
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===-- sanitizer_common_interceptors.inc -----------------------*- C++ -*-===// 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The LLVM Compiler Infrastructure 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// License. See LICENSE.TXT for details. 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 8116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch//===----------------------------------------------------------------------===// 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Common function interceptors for tools like AddressSanitizer, 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ThreadSanitizer, MemorySanitizer, etc. 1290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// 13c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// This file should be included into the tool's interceptor file, 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// which has to define it's own macros: 1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// COMMON_INTERCEPTOR_ENTER 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// COMMON_INTERCEPTOR_READ_RANGE 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// COMMON_INTERCEPTOR_WRITE_RANGE 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// COMMON_INTERCEPTOR_FD_ACQUIRE 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// COMMON_INTERCEPTOR_FD_RELEASE 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// COMMON_INTERCEPTOR_SET_THREAD_NAME 21c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch//===----------------------------------------------------------------------===// 22c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "interception/interception.h" 23c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "sanitizer_platform_interceptors.h" 2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include <stdarg.h> 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#if SANITIZER_WINDOWS 28c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#define va_copy(dst, src) ((dst) = (src)) 29c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#endif // _WIN32 30c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 31c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#if SANITIZER_INTERCEPT_STRCASECMP 32c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochstatic inline int CharCaseCmp(unsigned char c1, unsigned char c2) { 33c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch int c1_low = ToLower(c1); 34c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch int c2_low = ToLower(c2); 35c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return c1_low - c2_low; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)INTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) { 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void *ctx; 401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci COMMON_INTERCEPTOR_ENTER(ctx, strcasecmp, s1, s2); 411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci unsigned char c1 = 0, c2 = 0; 421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci uptr i; 431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (i = 0; ; i++) { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c1 = (unsigned char)s1[i]; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c2 = (unsigned char)s2[i]; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, i + 1); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, i + 1); 513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return CharCaseCmp(c1, c2); 523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)INTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, SIZE_T n) { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *ctx; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMMON_INTERCEPTOR_ENTER(ctx, strncasecmp, s1, s2, n); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char c1 = 0, c2 = 0; 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uptr i; 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (i = 0; i < n; i++) { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c1 = (unsigned char)s1[i]; 611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci c2 = (unsigned char)s2[i]; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') 631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, n)); 66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, n)); 67424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return CharCaseCmp(c1, c2); 68424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#define INIT_STRCASECMP INTERCEPT_FUNCTION(strcasecmp) 71424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#define INIT_STRNCASECMP INTERCEPT_FUNCTION(strncasecmp) 723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#else 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define INIT_STRCASECMP 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define INIT_STRNCASECMP 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if SANITIZER_INTERCEPT_FREXP 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)INTERCEPTOR(double, frexp, double x, int *exp) { 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *ctx; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMMON_INTERCEPTOR_ENTER(ctx, frexp, x, exp); 81424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) double res = REAL(frexp)(x, exp); 82424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp)); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return res; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define INIT_FREXP INTERCEPT_FUNCTION(frexp); 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define INIT_FREXP 891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif // SANITIZER_INTERCEPT_FREXP 901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if SANITIZER_INTERCEPT_FREXPF_FREXPL 921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciINTERCEPTOR(float, frexpf, float x, int *exp) { 931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void *ctx; 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) COMMON_INTERCEPTOR_ENTER(ctx, frexpf, x, exp); 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) float res = REAL(frexpf)(x, exp); 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp)); 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return res; 981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)INTERCEPTOR(long double, frexpl, long double x, int *exp) { 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void *ctx; 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) COMMON_INTERCEPTOR_ENTER(ctx, frexpl, x, exp); 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) long double res = REAL(frexpl)(x, exp); 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp)); 1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return res; 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define INIT_FREXPF_FREXPL \ 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) INTERCEPT_FUNCTION(frexpf); \ 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) INTERCEPT_FUNCTION(frexpl) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define INIT_FREXPF_FREXPL 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // SANITIZER_INTERCEPT_FREXPF_FREXPL 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if SI_NOT_WINDOWS 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void write_iovec(void *ctx, struct __sanitizer_iovec *iovec, 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SIZE_T iovlen, SIZE_T maxlen) { 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (SIZE_T i = 0; i < iovlen && maxlen; ++i) { 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSIZE_T sz = Min(iovec[i].iov_len, maxlen); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec[i].iov_base, sz); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) maxlen -= sz; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)static void read_iovec(void *ctx, struct __sanitizer_iovec *iovec, 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SIZE_T iovlen, SIZE_T maxlen) { 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec) * iovlen); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (SIZE_T i = 0; i < iovlen && maxlen; ++i) { 129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SSIZE_T sz = Min(iovec[i].iov_len, maxlen); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec[i].iov_base, sz); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) maxlen -= sz; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 136116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if SANITIZER_INTERCEPT_READ 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)INTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) { 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *ctx; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMMON_INTERCEPTOR_ENTER(ctx, read, fd, ptr, count); 140c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch SSIZE_T res = REAL(read)(fd, ptr, count); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (res > 0) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (res >= 0 && fd >= 0) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 14590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return res; 14690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 14790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#define INIT_READ INTERCEPT_FUNCTION(read) 14890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#else 14990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#define INIT_READ 15090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#if SANITIZER_INTERCEPT_PREAD 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)INTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) { 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *ctx; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMMON_INTERCEPTOR_ENTER(ctx, pread, fd, ptr, count, offset); 15690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SSIZE_T res = REAL(pread)(fd, ptr, count, offset); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (res > 0) 158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); 159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (res >= 0 && fd >= 0) 160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return res; 16258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 16390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#define INIT_PREAD INTERCEPT_FUNCTION(pread) 16490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#else 16590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#define INIT_PREAD 16690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif 1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if SANITIZER_INTERCEPT_PREAD64 1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciINTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) { 1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void *ctx; 1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci COMMON_INTERCEPTOR_ENTER(ctx, pread64, fd, ptr, count, offset); 1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SSIZE_T res = REAL(pread64)(fd, ptr, count, offset); 1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (res > 0) 17490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); 17590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (res >= 0 && fd >= 0) 17690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 17790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return res; 17890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#define INIT_PREAD64 INTERCEPT_FUNCTION(pread64) 1801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#else 1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#define INIT_PREAD64 1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif 18390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 18490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if SANITIZER_INTERCEPT_READV 1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciINTERCEPTOR_WITH_SUFFIX(SSIZE_T, readv, int fd, __sanitizer_iovec *iov, 1861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int iovcnt) { 1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void *ctx; 1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci COMMON_INTERCEPTOR_ENTER(ctx, readv, fd, iov, iovcnt); 1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SSIZE_T res = REAL(readv)(fd, iov, iovcnt); 1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (res > 0) write_iovec(ctx, iov, iovcnt, res); 1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return res; 1931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#define INIT_READV INTERCEPT_FUNCTION(readv) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#define INIT_READV 1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif 1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if SANITIZER_INTERCEPT_PREADV 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)INTERCEPTOR(SSIZE_T, preadv, int fd, __sanitizer_iovec *iov, int iovcnt, 2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci OFF_T offset) { 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *ctx; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMMON_INTERCEPTOR_ENTER(ctx, preadv, fd, iov, iovcnt, offset); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSIZE_T res = REAL(preadv)(fd, iov, iovcnt, offset); 2051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (res > 0) write_iovec(ctx, iov, iovcnt, res); 2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return res; 2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#define INIT_PREADV INTERCEPT_FUNCTION(preadv) 2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#else 2111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#define INIT_PREADV 2121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif 2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if SANITIZER_INTERCEPT_PREADV64 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)INTERCEPTOR(SSIZE_T, preadv64, int fd, __sanitizer_iovec *iov, int iovcnt, 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OFF64_T offset) { 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *ctx; 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMMON_INTERCEPTOR_ENTER(ctx, preadv64, fd, iov, iovcnt, offset); 219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SSIZE_T res = REAL(preadv64)(fd, iov, iovcnt, offset); 22090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (res > 0) write_iovec(ctx, iov, iovcnt, res); 221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return res; 2231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#define INIT_PREADV64 INTERCEPT_FUNCTION(preadv64) 225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#else 226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#define INIT_PREADV64 227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif 228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 229e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#if SANITIZER_INTERCEPT_WRITE 230cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)INTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) { 231cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void *ctx; 232cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) COMMON_INTERCEPTOR_ENTER(ctx, write, fd, ptr, count); 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (fd >= 0) 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSIZE_T res = REAL(write)(fd, ptr, count); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FIXME: this check should be _before_ the call to REAL(write), not after 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (res > 0) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return res; 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define INIT_WRITE INTERCEPT_FUNCTION(write) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define INIT_WRITE 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if SANITIZER_INTERCEPT_PWRITE 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)INTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) { 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *ctx; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMMON_INTERCEPTOR_ENTER(ctx, pwrite, fd, ptr, count, offset); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (fd >= 0) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSIZE_T res = REAL(pwrite)(fd, ptr, count, offset); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (res > 0) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return res; 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 257#define INIT_PWRITE INTERCEPT_FUNCTION(pwrite) 258#else 259#define INIT_PWRITE 260#endif 261 262#if SANITIZER_INTERCEPT_PWRITE64 263INTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count, 264 OFF64_T offset) { 265 void *ctx; 266 COMMON_INTERCEPTOR_ENTER(ctx, pwrite64, fd, ptr, count, offset); 267 if (fd >= 0) 268 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 269 SSIZE_T res = REAL(pwrite64)(fd, ptr, count, offset); 270 if (res > 0) 271 COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); 272 return res; 273} 274#define INIT_PWRITE64 INTERCEPT_FUNCTION(pwrite64) 275#else 276#define INIT_PWRITE64 277#endif 278 279#if SANITIZER_INTERCEPT_WRITEV 280INTERCEPTOR_WITH_SUFFIX(SSIZE_T, writev, int fd, __sanitizer_iovec *iov, 281 int iovcnt) { 282 void *ctx; 283 COMMON_INTERCEPTOR_ENTER(ctx, writev, fd, iov, iovcnt); 284 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 285 SSIZE_T res = REAL(writev)(fd, iov, iovcnt); 286 if (res > 0) read_iovec(ctx, iov, iovcnt, res); 287 return res; 288} 289#define INIT_WRITEV INTERCEPT_FUNCTION(writev) 290#else 291#define INIT_WRITEV 292#endif 293 294#if SANITIZER_INTERCEPT_PWRITEV 295INTERCEPTOR(SSIZE_T, pwritev, int fd, __sanitizer_iovec *iov, int iovcnt, 296 OFF_T offset) { 297 void *ctx; 298 COMMON_INTERCEPTOR_ENTER(ctx, pwritev, fd, iov, iovcnt, offset); 299 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 300 SSIZE_T res = REAL(pwritev)(fd, iov, iovcnt, offset); 301 if (res > 0) read_iovec(ctx, iov, iovcnt, res); 302 return res; 303} 304#define INIT_PWRITEV INTERCEPT_FUNCTION(pwritev) 305#else 306#define INIT_PWRITEV 307#endif 308 309#if SANITIZER_INTERCEPT_PWRITEV64 310INTERCEPTOR(SSIZE_T, pwritev64, int fd, __sanitizer_iovec *iov, int iovcnt, 311 OFF64_T offset) { 312 void *ctx; 313 COMMON_INTERCEPTOR_ENTER(ctx, pwritev64, fd, iov, iovcnt, offset); 314 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 315 SSIZE_T res = REAL(pwritev64)(fd, iov, iovcnt, offset); 316 if (res > 0) read_iovec(ctx, iov, iovcnt, res); 317 return res; 318} 319#define INIT_PWRITEV64 INTERCEPT_FUNCTION(pwritev64) 320#else 321#define INIT_PWRITEV64 322#endif 323 324#if SANITIZER_INTERCEPT_PRCTL 325INTERCEPTOR(int, prctl, int option, 326 unsigned long arg2, unsigned long arg3, // NOLINT 327 unsigned long arg4, unsigned long arg5) { // NOLINT 328 void *ctx; 329 COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5); 330 static const int PR_SET_NAME = 15; 331 int res = REAL(prctl(option, arg2, arg3, arg4, arg5)); 332 if (option == PR_SET_NAME) { 333 char buff[16]; 334 internal_strncpy(buff, (char *)arg2, 15); 335 buff[15] = 0; 336 COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff); 337 } 338 return res; 339} 340#define INIT_PRCTL INTERCEPT_FUNCTION(prctl) 341#else 342#define INIT_PRCTL 343#endif // SANITIZER_INTERCEPT_PRCTL 344 345 346#if SANITIZER_INTERCEPT_TIME 347INTERCEPTOR(unsigned long, time, unsigned long *t) { 348 void *ctx; 349 COMMON_INTERCEPTOR_ENTER(ctx, time, t); 350 unsigned long res = REAL(time)(t); 351 if (t && res != (unsigned long)-1) { 352 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, t, sizeof(*t)); 353 } 354 return res; 355} 356#define INIT_TIME \ 357 INTERCEPT_FUNCTION(time); 358#else 359#define INIT_TIME 360#endif // SANITIZER_INTERCEPT_TIME 361 362 363#if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS 364INTERCEPTOR(void *, localtime, unsigned long *timep) { 365 void *ctx; 366 COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep); 367 void *res = REAL(localtime)(timep); 368 if (res) { 369 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 370 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz); 371 } 372 return res; 373} 374INTERCEPTOR(void *, localtime_r, unsigned long *timep, void *result) { 375 void *ctx; 376 COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result); 377 void *res = REAL(localtime_r)(timep, result); 378 if (res) { 379 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 380 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz); 381 } 382 return res; 383} 384INTERCEPTOR(void *, gmtime, unsigned long *timep) { 385 void *ctx; 386 COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep); 387 void *res = REAL(gmtime)(timep); 388 if (res) { 389 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 390 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz); 391 } 392 return res; 393} 394INTERCEPTOR(void *, gmtime_r, unsigned long *timep, void *result) { 395 void *ctx; 396 COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result); 397 void *res = REAL(gmtime_r)(timep, result); 398 if (res) { 399 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 400 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz); 401 } 402 return res; 403} 404INTERCEPTOR(char *, ctime, unsigned long *timep) { 405 void *ctx; 406 COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep); 407 char *res = REAL(ctime)(timep); 408 if (res) { 409 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 410 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 411 } 412 return res; 413} 414INTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) { 415 void *ctx; 416 COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result); 417 char *res = REAL(ctime_r)(timep, result); 418 if (res) { 419 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 420 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 421 } 422 return res; 423} 424INTERCEPTOR(char *, asctime, void *tm) { 425 void *ctx; 426 COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm); 427 char *res = REAL(asctime)(tm); 428 if (res) { 429 COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, struct_tm_sz); 430 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 431 } 432 return res; 433} 434INTERCEPTOR(char *, asctime_r, void *tm, char *result) { 435 void *ctx; 436 COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result); 437 char *res = REAL(asctime_r)(tm, result); 438 if (res) { 439 COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, struct_tm_sz); 440 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 441 } 442 return res; 443} 444#define INIT_LOCALTIME_AND_FRIENDS \ 445 INTERCEPT_FUNCTION(localtime); \ 446 INTERCEPT_FUNCTION(localtime_r); \ 447 INTERCEPT_FUNCTION(gmtime); \ 448 INTERCEPT_FUNCTION(gmtime_r); \ 449 INTERCEPT_FUNCTION(ctime); \ 450 INTERCEPT_FUNCTION(ctime_r); \ 451 INTERCEPT_FUNCTION(asctime); \ 452 INTERCEPT_FUNCTION(asctime_r); 453#else 454#define INIT_LOCALTIME_AND_FRIENDS 455#endif // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS 456 457#if SANITIZER_INTERCEPT_SCANF 458 459#include "sanitizer_common_interceptors_scanf.inc" 460 461#define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...) \ 462 { \ 463 void *ctx; \ 464 COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__); \ 465 va_list aq; \ 466 va_copy(aq, ap); \ 467 int res = REAL(vname)(__VA_ARGS__); \ 468 if (res > 0) \ 469 scanf_common(ctx, res, allowGnuMalloc, format, aq); \ 470 va_end(aq); \ 471 return res; \ 472 } 473 474INTERCEPTOR(int, vscanf, const char *format, va_list ap) 475VSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap) 476 477INTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap) 478VSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap) 479 480INTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap) 481VSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap) 482 483#if SANITIZER_INTERCEPT_ISOC99_SCANF 484INTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap) 485VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap) 486 487INTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format, 488 va_list ap) 489VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap) 490 491INTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap) 492VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap) 493#endif // SANITIZER_INTERCEPT_ISOC99_SCANF 494 495#define SCANF_INTERCEPTOR_IMPL(name, vname, ...) \ 496 { \ 497 void *ctx; \ 498 COMMON_INTERCEPTOR_ENTER(ctx, name, __VA_ARGS__); \ 499 va_list ap; \ 500 va_start(ap, format); \ 501 int res = vname(__VA_ARGS__, ap); \ 502 va_end(ap); \ 503 return res; \ 504 } 505 506INTERCEPTOR(int, scanf, const char *format, ...) 507SCANF_INTERCEPTOR_IMPL(scanf, vscanf, format) 508 509INTERCEPTOR(int, fscanf, void *stream, const char *format, ...) 510SCANF_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format) 511 512INTERCEPTOR(int, sscanf, const char *str, const char *format, ...) 513SCANF_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format) 514 515#if SANITIZER_INTERCEPT_ISOC99_SCANF 516INTERCEPTOR(int, __isoc99_scanf, const char *format, ...) 517SCANF_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format) 518 519INTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...) 520SCANF_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format) 521 522INTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...) 523SCANF_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format) 524#endif 525 526#define INIT_SCANF \ 527 INTERCEPT_FUNCTION(scanf); \ 528 INTERCEPT_FUNCTION(sscanf); \ 529 INTERCEPT_FUNCTION(fscanf); \ 530 INTERCEPT_FUNCTION(vscanf); \ 531 INTERCEPT_FUNCTION(vsscanf); \ 532 INTERCEPT_FUNCTION(vfscanf); \ 533 INTERCEPT_FUNCTION(__isoc99_scanf); \ 534 INTERCEPT_FUNCTION(__isoc99_sscanf); \ 535 INTERCEPT_FUNCTION(__isoc99_fscanf); \ 536 INTERCEPT_FUNCTION(__isoc99_vscanf); \ 537 INTERCEPT_FUNCTION(__isoc99_vsscanf); \ 538 INTERCEPT_FUNCTION(__isoc99_vfscanf); 539 540#else 541#define INIT_SCANF 542#endif 543 544 545#if SANITIZER_INTERCEPT_IOCTL 546#include "sanitizer_common_interceptors_ioctl.inc" 547INTERCEPTOR(int, ioctl, int d, unsigned request, void *arg) { 548 void *ctx; 549 COMMON_INTERCEPTOR_ENTER(ctx, ioctl, d, request, arg); 550 551 CHECK(ioctl_initialized); 552 553 // Note: TSan does not use common flags, and they are zero-initialized. 554 // This effectively disables ioctl handling in TSan. 555 if (!common_flags()->handle_ioctl) 556 return REAL(ioctl)(d, request, arg); 557 558 const ioctl_desc *desc = ioctl_lookup(request); 559 if (!desc) 560 Printf("WARNING: unknown ioctl %x\n", request); 561 562 if (desc) 563 ioctl_common_pre(ctx, desc, d, request, arg); 564 int res = REAL(ioctl)(d, request, arg); 565 // FIXME: some ioctls have different return values for success and failure. 566 if (desc && res != -1) 567 ioctl_common_post(ctx, desc, res, d, request, arg); 568 return res; 569} 570#define INIT_IOCTL \ 571 ioctl_init(); \ 572 INTERCEPT_FUNCTION(ioctl); 573#else 574#define INIT_IOCTL 575#endif 576 577 578#if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS 579INTERCEPTOR(void *, getpwnam, const char *name) { 580 void *ctx; 581 COMMON_INTERCEPTOR_ENTER(ctx, getpwnam, name); 582 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 583 void *res = REAL(getpwnam)(name); 584 if (res != 0) 585 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_passwd_sz); 586 return res; 587} 588INTERCEPTOR(void *, getpwuid, u32 uid) { 589 void *ctx; 590 COMMON_INTERCEPTOR_ENTER(ctx, getpwuid, uid); 591 void *res = REAL(getpwuid)(uid); 592 if (res != 0) 593 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_passwd_sz); 594 return res; 595} 596INTERCEPTOR(void *, getgrnam, const char *name) { 597 void *ctx; 598 COMMON_INTERCEPTOR_ENTER(ctx, getgrnam, name); 599 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 600 void *res = REAL(getgrnam)(name); 601 if (res != 0) 602 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_group_sz); 603 return res; 604} 605INTERCEPTOR(void *, getgrgid, u32 gid) { 606 void *ctx; 607 COMMON_INTERCEPTOR_ENTER(ctx, getgrgid, gid); 608 void *res = REAL(getgrgid)(gid); 609 if (res != 0) 610 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_group_sz); 611 return res; 612} 613#define INIT_GETPWNAM_AND_FRIENDS \ 614 INTERCEPT_FUNCTION(getpwnam); \ 615 INTERCEPT_FUNCTION(getpwuid); \ 616 INTERCEPT_FUNCTION(getgrnam); \ 617 INTERCEPT_FUNCTION(getgrgid); 618#else 619#define INIT_GETPWNAM_AND_FRIENDS 620#endif 621 622 623#if SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS 624INTERCEPTOR(int, getpwnam_r, const char *name, void *pwd, 625 char *buf, SIZE_T buflen, void **result) { 626 void *ctx; 627 COMMON_INTERCEPTOR_ENTER(ctx, getpwnam_r, name, pwd, buf, buflen, result); 628 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 629 int res = REAL(getpwnam_r)(name, pwd, buf, buflen, result); 630 if (!res) { 631 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, struct_passwd_sz); 632 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 633 } 634 return res; 635} 636INTERCEPTOR(int, getpwuid_r, u32 uid, void *pwd, 637 char *buf, SIZE_T buflen, void **result) { 638 void *ctx; 639 COMMON_INTERCEPTOR_ENTER(ctx, getpwuid_r, uid, pwd, buf, buflen, result); 640 int res = REAL(getpwuid_r)(uid, pwd, buf, buflen, result); 641 if (!res) { 642 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, struct_passwd_sz); 643 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 644 } 645 return res; 646} 647INTERCEPTOR(int, getgrnam_r, const char *name, void *grp, 648 char *buf, SIZE_T buflen, void **result) { 649 void *ctx; 650 COMMON_INTERCEPTOR_ENTER(ctx, getgrnam_r, name, grp, buf, buflen, result); 651 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 652 int res = REAL(getgrnam_r)(name, grp, buf, buflen, result); 653 if (!res) { 654 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, struct_group_sz); 655 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 656 } 657 return res; 658} 659INTERCEPTOR(int, getgrgid_r, u32 gid, void *grp, 660 char *buf, SIZE_T buflen, void **result) { 661 void *ctx; 662 COMMON_INTERCEPTOR_ENTER(ctx, getgrgid_r, gid, grp, buf, buflen, result); 663 int res = REAL(getgrgid_r)(gid, grp, buf, buflen, result); 664 if (!res) { 665 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, struct_group_sz); 666 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 667 } 668 return res; 669} 670#define INIT_GETPWNAM_R_AND_FRIENDS \ 671 INTERCEPT_FUNCTION(getpwnam_r); \ 672 INTERCEPT_FUNCTION(getpwuid_r); \ 673 INTERCEPT_FUNCTION(getgrnam_r); \ 674 INTERCEPT_FUNCTION(getgrgid_r); 675#else 676#define INIT_GETPWNAM_R_AND_FRIENDS 677#endif 678 679 680#if SANITIZER_INTERCEPT_CLOCK_GETTIME 681INTERCEPTOR(int, clock_getres, u32 clk_id, void *tp) { 682 void *ctx; 683 COMMON_INTERCEPTOR_ENTER(ctx, clock_getres, clk_id, tp); 684 int res = REAL(clock_getres)(clk_id, tp); 685 if (!res && tp) { 686 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz); 687 } 688 return res; 689} 690INTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) { 691 void *ctx; 692 COMMON_INTERCEPTOR_ENTER(ctx, clock_gettime, clk_id, tp); 693 int res = REAL(clock_gettime)(clk_id, tp); 694 if (!res) { 695 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz); 696 } 697 return res; 698} 699INTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) { 700 void *ctx; 701 COMMON_INTERCEPTOR_ENTER(ctx, clock_settime, clk_id, tp); 702 COMMON_INTERCEPTOR_READ_RANGE(ctx, tp, struct_timespec_sz); 703 return REAL(clock_settime)(clk_id, tp); 704} 705#define INIT_CLOCK_GETTIME \ 706 INTERCEPT_FUNCTION(clock_getres); \ 707 INTERCEPT_FUNCTION(clock_gettime); \ 708 INTERCEPT_FUNCTION(clock_settime); 709#else 710#define INIT_CLOCK_GETTIME 711#endif 712 713 714#if SANITIZER_INTERCEPT_GETITIMER 715INTERCEPTOR(int, getitimer, int which, void *curr_value) { 716 void *ctx; 717 COMMON_INTERCEPTOR_ENTER(ctx, getitimer, which, curr_value); 718 int res = REAL(getitimer)(which, curr_value); 719 if (!res) { 720 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerval_sz); 721 } 722 return res; 723} 724INTERCEPTOR(int, setitimer, int which, const void *new_value, void *old_value) { 725 void *ctx; 726 COMMON_INTERCEPTOR_ENTER(ctx, setitimer, which, new_value, old_value); 727 COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerval_sz); 728 int res = REAL(setitimer)(which, new_value, old_value); 729 if (!res && old_value) { 730 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerval_sz); 731 } 732 return res; 733} 734#define INIT_GETITIMER \ 735 INTERCEPT_FUNCTION(getitimer); \ 736 INTERCEPT_FUNCTION(setitimer); 737#else 738#define INIT_GETITIMER 739#endif 740 741#if SANITIZER_INTERCEPT_GLOB 742static void unpoison_glob_t(void *ctx, __sanitizer_glob_t *pglob) { 743 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob)); 744 // +1 for NULL pointer at the end. 745 if (pglob->gl_pathv) 746 COMMON_INTERCEPTOR_WRITE_RANGE( 747 ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv)); 748 for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) { 749 char *p = pglob->gl_pathv[i]; 750 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, REAL(strlen)(p) + 1); 751 } 752} 753 754INTERCEPTOR(int, glob, const char *pattern, int flags, 755 int (*errfunc)(const char *epath, int eerrno), 756 __sanitizer_glob_t *pglob) { 757 void *ctx; 758 COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob); 759 int res = REAL(glob)(pattern, flags, errfunc, pglob); 760 if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob); 761 return res; 762} 763 764INTERCEPTOR(int, glob64, const char *pattern, int flags, 765 int (*errfunc)(const char *epath, int eerrno), 766 __sanitizer_glob_t *pglob) { 767 void *ctx; 768 COMMON_INTERCEPTOR_ENTER(ctx, glob64, pattern, flags, errfunc, pglob); 769 int res = REAL(glob64)(pattern, flags, errfunc, pglob); 770 if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob); 771 return res; 772} 773#define INIT_GLOB \ 774 INTERCEPT_FUNCTION(glob); \ 775 INTERCEPT_FUNCTION(glob64); 776#else // SANITIZER_INTERCEPT_GLOB 777#define INIT_GLOB 778#endif // SANITIZER_INTERCEPT_GLOB 779 780#if SANITIZER_INTERCEPT_WAIT 781// According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version 782// suffixes on Darwin. See the declaration of INTERCEPTOR_WITH_SUFFIX for 783// details. 784INTERCEPTOR_WITH_SUFFIX(int, wait, int *status) { 785 void *ctx; 786 COMMON_INTERCEPTOR_ENTER(ctx, wait, status); 787 int res = REAL(wait)(status); 788 if (res != -1 && status) 789 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 790 return res; 791} 792INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, int id, void *infop, 793 int options) { 794 void *ctx; 795 COMMON_INTERCEPTOR_ENTER(ctx, waitid, idtype, id, infop, options); 796 int res = REAL(waitid)(idtype, id, infop, options); 797 if (res != -1 && infop) 798 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, infop, siginfo_t_sz); 799 return res; 800} 801INTERCEPTOR_WITH_SUFFIX(int, waitpid, int pid, int *status, int options) { 802 void *ctx; 803 COMMON_INTERCEPTOR_ENTER(ctx, waitpid, pid, status, options); 804 int res = REAL(waitpid)(pid, status, options); 805 if (res != -1 && status) 806 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 807 return res; 808} 809INTERCEPTOR(int, wait3, int *status, int options, void *rusage) { 810 void *ctx; 811 COMMON_INTERCEPTOR_ENTER(ctx, wait3, status, options, rusage); 812 int res = REAL(wait3)(status, options, rusage); 813 if (res != -1) { 814 if (status) 815 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 816 if (rusage) 817 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz); 818 } 819 return res; 820} 821INTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) { 822 void *ctx; 823 COMMON_INTERCEPTOR_ENTER(ctx, wait4, pid, status, options, rusage); 824 int res = REAL(wait4)(pid, status, options, rusage); 825 if (res != -1) { 826 if (status) 827 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 828 if (rusage) 829 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz); 830 } 831 return res; 832} 833#define INIT_WAIT \ 834 INTERCEPT_FUNCTION(wait); \ 835 INTERCEPT_FUNCTION(waitid); \ 836 INTERCEPT_FUNCTION(waitpid); \ 837 INTERCEPT_FUNCTION(wait3); \ 838 INTERCEPT_FUNCTION(wait4); 839#else 840#define INIT_WAIT 841#endif 842 843#if SANITIZER_INTERCEPT_INET 844INTERCEPTOR(char *, inet_ntop, int af, const void *src, char *dst, u32 size) { 845 void *ctx; 846 COMMON_INTERCEPTOR_ENTER(ctx, inet_ntop, af, src, dst, size); 847 uptr sz = __sanitizer_in_addr_sz(af); 848 if (sz) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sz); 849 // FIXME: figure out read size based on the address family. 850 char *res = REAL(inet_ntop)(af, src, dst, size); 851 if (res) 852 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 853 return res; 854} 855INTERCEPTOR(int, inet_pton, int af, const char *src, void *dst) { 856 void *ctx; 857 COMMON_INTERCEPTOR_ENTER(ctx, inet_pton, af, src, dst); 858 // FIXME: figure out read size based on the address family. 859 int res = REAL(inet_pton)(af, src, dst); 860 if (res == 1) { 861 uptr sz = __sanitizer_in_addr_sz(af); 862 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz); 863 } 864 return res; 865} 866#define INIT_INET \ 867 INTERCEPT_FUNCTION(inet_ntop); \ 868 INTERCEPT_FUNCTION(inet_pton); 869#else 870#define INIT_INET 871#endif 872 873#if SANITIZER_INTERCEPT_INET 874INTERCEPTOR(int, inet_aton, const char *cp, void *dst) { 875 void *ctx; 876 COMMON_INTERCEPTOR_ENTER(ctx, inet_aton, cp, dst); 877 if (cp) COMMON_INTERCEPTOR_READ_RANGE(ctx, cp, REAL(strlen)(cp) + 1); 878 int res = REAL(inet_aton)(cp, dst); 879 if (res != 0) { 880 uptr sz = __sanitizer_in_addr_sz(af_inet); 881 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz); 882 } 883 return res; 884} 885#define INIT_INET_ATON INTERCEPT_FUNCTION(inet_aton); 886#else 887#define INIT_INET_ATON 888#endif 889 890#if SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM 891INTERCEPTOR(int, pthread_getschedparam, uptr thread, int *policy, int *param) { 892 void *ctx; 893 COMMON_INTERCEPTOR_ENTER(ctx, pthread_getschedparam, thread, policy, param); 894 int res = REAL(pthread_getschedparam)(thread, policy, param); 895 if (res == 0) { 896 if (policy) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, policy, sizeof(*policy)); 897 if (param) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, sizeof(*param)); 898 } 899 return res; 900} 901#define INIT_PTHREAD_GETSCHEDPARAM INTERCEPT_FUNCTION(pthread_getschedparam); 902#else 903#define INIT_PTHREAD_GETSCHEDPARAM 904#endif 905 906#if SANITIZER_INTERCEPT_GETADDRINFO 907INTERCEPTOR(int, getaddrinfo, char *node, char *service, 908 struct __sanitizer_addrinfo *hints, 909 struct __sanitizer_addrinfo **out) { 910 void *ctx; 911 COMMON_INTERCEPTOR_ENTER(ctx, getaddrinfo, node, service, hints, out); 912 if (node) COMMON_INTERCEPTOR_READ_RANGE(ctx, node, REAL(strlen)(node) + 1); 913 if (service) 914 COMMON_INTERCEPTOR_READ_RANGE(ctx, service, REAL(strlen)(service) + 1); 915 if (hints) 916 COMMON_INTERCEPTOR_READ_RANGE(ctx, hints, sizeof(__sanitizer_addrinfo)); 917 int res = REAL(getaddrinfo)(node, service, hints, out); 918 if (res == 0 && out) { 919 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, out, sizeof(*out)); 920 struct __sanitizer_addrinfo *p = *out; 921 while (p) { 922 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); 923 if (p->ai_addr) 924 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_addr, p->ai_addrlen); 925 if (p->ai_canonname) 926 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_canonname, 927 REAL(strlen)(p->ai_canonname) + 1); 928 p = p->ai_next; 929 } 930 } 931 return res; 932} 933#define INIT_GETADDRINFO INTERCEPT_FUNCTION(getaddrinfo); 934#else 935#define INIT_GETADDRINFO 936#endif 937 938#if SANITIZER_INTERCEPT_GETNAMEINFO 939INTERCEPTOR(int, getnameinfo, void *sockaddr, unsigned salen, char *host, 940 unsigned hostlen, char *serv, unsigned servlen, int flags) { 941 void *ctx; 942 COMMON_INTERCEPTOR_ENTER(ctx, getnameinfo, sockaddr, salen, host, hostlen, 943 serv, servlen, flags); 944 // FIXME: consider adding READ_RANGE(sockaddr, salen) 945 // There is padding in in_addr that may make this too noisy 946 int res = 947 REAL(getnameinfo)(sockaddr, salen, host, hostlen, serv, servlen, flags); 948 if (res == 0) { 949 if (host && hostlen) 950 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, host, REAL(strlen)(host) + 1); 951 if (serv && servlen) 952 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, serv, REAL(strlen)(serv) + 1); 953 } 954 return res; 955} 956#define INIT_GETNAMEINFO INTERCEPT_FUNCTION(getnameinfo); 957#else 958#define INIT_GETNAMEINFO 959#endif 960 961#if SANITIZER_INTERCEPT_GETSOCKNAME 962INTERCEPTOR(int, getsockname, int sock_fd, void *addr, int *addrlen) { 963 void *ctx; 964 COMMON_INTERCEPTOR_ENTER(ctx, getsockname, sock_fd, addr, addrlen); 965 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 966 int addrlen_in = *addrlen; 967 int res = REAL(getsockname)(sock_fd, addr, addrlen); 968 if (res == 0) { 969 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addrlen_in, *addrlen)); 970 } 971 return res; 972} 973#define INIT_GETSOCKNAME INTERCEPT_FUNCTION(getsockname); 974#else 975#define INIT_GETSOCKNAME 976#endif 977 978#if SANITIZER_INTERCEPT_GETHOSTBYNAME || SANITIZER_INTERCEPT_GETHOSTBYNAME_R 979static void write_hostent(void *ctx, struct __sanitizer_hostent *h) { 980 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h, sizeof(__sanitizer_hostent)); 981 if (h->h_name) 982 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h->h_name, REAL(strlen)(h->h_name) + 1); 983 char **p = h->h_aliases; 984 while (*p) { 985 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1); 986 ++p; 987 } 988 COMMON_INTERCEPTOR_WRITE_RANGE( 989 ctx, h->h_aliases, (p - h->h_aliases + 1) * sizeof(*h->h_aliases)); 990 p = h->h_addr_list; 991 while (*p) { 992 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, h->h_length); 993 ++p; 994 } 995 COMMON_INTERCEPTOR_WRITE_RANGE( 996 ctx, h->h_addr_list, (p - h->h_addr_list + 1) * sizeof(*h->h_addr_list)); 997} 998#endif 999 1000#if SANITIZER_INTERCEPT_GETHOSTBYNAME 1001INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname, char *name) { 1002 void *ctx; 1003 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname, name); 1004 struct __sanitizer_hostent *res = REAL(gethostbyname)(name); 1005 if (res) write_hostent(ctx, res); 1006 return res; 1007} 1008 1009INTERCEPTOR(struct __sanitizer_hostent *, gethostbyaddr, void *addr, int len, 1010 int type) { 1011 void *ctx; 1012 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr, addr, len, type); 1013 COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len); 1014 struct __sanitizer_hostent *res = REAL(gethostbyaddr)(addr, len, type); 1015 if (res) write_hostent(ctx, res); 1016 return res; 1017} 1018 1019INTERCEPTOR(struct __sanitizer_hostent *, gethostent) { 1020 void *ctx; 1021 COMMON_INTERCEPTOR_ENTER(ctx, gethostent); 1022 struct __sanitizer_hostent *res = REAL(gethostent)(); 1023 if (res) write_hostent(ctx, res); 1024 return res; 1025} 1026 1027INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname2, char *name, int af) { 1028 void *ctx; 1029 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2, name, af); 1030 struct __sanitizer_hostent *res = REAL(gethostbyname2)(name, af); 1031 if (res) write_hostent(ctx, res); 1032 return res; 1033} 1034#define INIT_GETHOSTBYNAME \ 1035 INTERCEPT_FUNCTION(gethostent); \ 1036 INTERCEPT_FUNCTION(gethostbyaddr); \ 1037 INTERCEPT_FUNCTION(gethostbyname); \ 1038 INTERCEPT_FUNCTION(gethostbyname2); 1039#else 1040#define INIT_GETHOSTBYNAME 1041#endif 1042 1043#if SANITIZER_INTERCEPT_GETHOSTBYNAME_R 1044INTERCEPTOR(int, gethostent_r, struct __sanitizer_hostent *ret, char *buf, 1045 SIZE_T buflen, __sanitizer_hostent **result, int *h_errnop) { 1046 void *ctx; 1047 COMMON_INTERCEPTOR_ENTER(ctx, gethostent_r, ret, buf, buflen, result, 1048 h_errnop); 1049 int res = REAL(gethostent_r)(ret, buf, buflen, result, h_errnop); 1050 if (res == 0) { 1051 if (result) { 1052 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1053 if (*result) write_hostent(ctx, *result); 1054 } 1055 if (h_errnop) 1056 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 1057 } 1058 return res; 1059} 1060 1061INTERCEPTOR(int, gethostbyaddr_r, void *addr, int len, int type, 1062 struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen, 1063 __sanitizer_hostent **result, int *h_errnop) { 1064 void *ctx; 1065 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr_r, addr, len, type, ret, buf, 1066 buflen, result, h_errnop); 1067 COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len); 1068 int res = REAL(gethostbyaddr_r)(addr, len, type, ret, buf, buflen, result, 1069 h_errnop); 1070 if (res == 0) { 1071 if (result) { 1072 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1073 if (*result) write_hostent(ctx, *result); 1074 } 1075 if (h_errnop) 1076 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 1077 } 1078 return res; 1079} 1080 1081INTERCEPTOR(int, gethostbyname_r, char *name, struct __sanitizer_hostent *ret, 1082 char *buf, SIZE_T buflen, __sanitizer_hostent **result, 1083 int *h_errnop) { 1084 void *ctx; 1085 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname_r, name, ret, buf, buflen, result, 1086 h_errnop); 1087 int res = REAL(gethostbyname_r)(name, ret, buf, buflen, result, h_errnop); 1088 if (res == 0) { 1089 if (result) { 1090 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1091 if (*result) write_hostent(ctx, *result); 1092 } 1093 if (h_errnop) 1094 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 1095 } 1096 return res; 1097} 1098 1099INTERCEPTOR(int, gethostbyname2_r, char *name, int af, 1100 struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen, 1101 __sanitizer_hostent **result, int *h_errnop) { 1102 void *ctx; 1103 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2_r, name, af, ret, buf, buflen, 1104 result, h_errnop); 1105 int res = 1106 REAL(gethostbyname2_r)(name, af, ret, buf, buflen, result, h_errnop); 1107 if (res == 0) { 1108 if (result) { 1109 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1110 if (*result) write_hostent(ctx, *result); 1111 } 1112 if (h_errnop) 1113 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 1114 } 1115 return res; 1116} 1117#define INIT_GETHOSTBYNAME_R \ 1118 INTERCEPT_FUNCTION(gethostent_r); \ 1119 INTERCEPT_FUNCTION(gethostbyaddr_r); \ 1120 INTERCEPT_FUNCTION(gethostbyname_r); \ 1121 INTERCEPT_FUNCTION(gethostbyname2_r); 1122#else 1123#define INIT_GETHOSTBYNAME_R 1124#endif 1125 1126#if SANITIZER_INTERCEPT_GETSOCKOPT 1127INTERCEPTOR(int, getsockopt, int sockfd, int level, int optname, void *optval, 1128 int *optlen) { 1129 void *ctx; 1130 COMMON_INTERCEPTOR_ENTER(ctx, getsockopt, sockfd, level, optname, optval, 1131 optlen); 1132 if (optlen) COMMON_INTERCEPTOR_READ_RANGE(ctx, optlen, sizeof(*optlen)); 1133 int res = REAL(getsockopt)(sockfd, level, optname, optval, optlen); 1134 if (res == 0) 1135 if (optval && optlen) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, optval, *optlen); 1136 return res; 1137} 1138#define INIT_GETSOCKOPT INTERCEPT_FUNCTION(getsockopt); 1139#else 1140#define INIT_GETSOCKOPT 1141#endif 1142 1143#if SANITIZER_INTERCEPT_ACCEPT 1144INTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) { 1145 void *ctx; 1146 COMMON_INTERCEPTOR_ENTER(ctx, accept, fd, addr, addrlen); 1147 unsigned addrlen0; 1148 if (addrlen) { 1149 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 1150 addrlen0 = *addrlen; 1151 } 1152 int fd2 = REAL(accept)(fd, addr, addrlen); 1153 if (fd2 >= 0) { 1154 if (fd >= 0) 1155 COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2); 1156 if (addr && addrlen) 1157 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0)); 1158 } 1159 return fd2; 1160} 1161#define INIT_ACCEPT INTERCEPT_FUNCTION(accept); 1162#else 1163#define INIT_ACCEPT 1164#endif 1165 1166#if SANITIZER_INTERCEPT_ACCEPT4 1167INTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) { 1168 void *ctx; 1169 COMMON_INTERCEPTOR_ENTER(ctx, accept4, fd, addr, addrlen, f); 1170 unsigned addrlen0; 1171 if (addrlen) { 1172 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 1173 addrlen0 = *addrlen; 1174 } 1175 int fd2 = REAL(accept4)(fd, addr, addrlen, f); 1176 if (fd2 >= 0) { 1177 if (fd >= 0) 1178 COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2); 1179 if (addr && addrlen) 1180 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0)); 1181 } 1182 return fd2; 1183} 1184#define INIT_ACCEPT4 INTERCEPT_FUNCTION(accept4); 1185#else 1186#define INIT_ACCEPT4 1187#endif 1188 1189#if SANITIZER_INTERCEPT_MODF 1190INTERCEPTOR(double, modf, double x, double *iptr) { 1191 void *ctx; 1192 COMMON_INTERCEPTOR_ENTER(ctx, modf, x, iptr); 1193 double res = REAL(modf)(x, iptr); 1194 if (iptr) { 1195 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr)); 1196 } 1197 return res; 1198} 1199INTERCEPTOR(float, modff, float x, float *iptr) { 1200 void *ctx; 1201 COMMON_INTERCEPTOR_ENTER(ctx, modff, x, iptr); 1202 float res = REAL(modff)(x, iptr); 1203 if (iptr) { 1204 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr)); 1205 } 1206 return res; 1207} 1208INTERCEPTOR(long double, modfl, long double x, long double *iptr) { 1209 void *ctx; 1210 COMMON_INTERCEPTOR_ENTER(ctx, modfl, x, iptr); 1211 long double res = REAL(modfl)(x, iptr); 1212 if (iptr) { 1213 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr)); 1214 } 1215 return res; 1216} 1217#define INIT_MODF \ 1218 INTERCEPT_FUNCTION(modf); \ 1219 INTERCEPT_FUNCTION(modff); \ 1220 INTERCEPT_FUNCTION(modfl); 1221#else 1222#define INIT_MODF 1223#endif 1224 1225#if SANITIZER_INTERCEPT_RECVMSG 1226static void write_msghdr(void *ctx, struct __sanitizer_msghdr *msg, 1227 SSIZE_T maxlen) { 1228 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg, sizeof(*msg)); 1229 if (msg->msg_name) 1230 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_name, 1231 REAL(strlen)((char *)msg->msg_name) + 1); 1232 if (msg->msg_iov) 1233 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_iov, 1234 sizeof(*msg->msg_iov) * msg->msg_iovlen); 1235 write_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen); 1236 if (msg->msg_control) 1237 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_control, msg->msg_controllen); 1238} 1239 1240INTERCEPTOR(SSIZE_T, recvmsg, int fd, struct __sanitizer_msghdr *msg, 1241 int flags) { 1242 void *ctx; 1243 COMMON_INTERCEPTOR_ENTER(ctx, recvmsg, fd, msg, flags); 1244 SSIZE_T res = REAL(recvmsg)(fd, msg, flags); 1245 if (res >= 0) { 1246 if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 1247 if (msg) write_msghdr(ctx, msg, res); 1248 } 1249 return res; 1250} 1251#define INIT_RECVMSG INTERCEPT_FUNCTION(recvmsg); 1252#else 1253#define INIT_RECVMSG 1254#endif 1255 1256#if SANITIZER_INTERCEPT_GETPEERNAME 1257INTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) { 1258 void *ctx; 1259 COMMON_INTERCEPTOR_ENTER(ctx, getpeername, sockfd, addr, addrlen); 1260 unsigned addr_sz; 1261 if (addrlen) addr_sz = *addrlen; 1262 int res = REAL(getpeername)(sockfd, addr, addrlen); 1263 if (!res && addr && addrlen) 1264 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen)); 1265 return res; 1266} 1267#define INIT_GETPEERNAME INTERCEPT_FUNCTION(getpeername); 1268#else 1269#define INIT_GETPEERNAME 1270#endif 1271 1272#if SANITIZER_INTERCEPT_SYSINFO 1273INTERCEPTOR(int, sysinfo, void *info) { 1274 void *ctx; 1275 COMMON_INTERCEPTOR_ENTER(ctx, sysinfo, info); 1276 int res = REAL(sysinfo)(info); 1277 if (!res && info) 1278 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, struct_sysinfo_sz); 1279 return res; 1280} 1281#define INIT_SYSINFO INTERCEPT_FUNCTION(sysinfo); 1282#else 1283#define INIT_SYSINFO 1284#endif 1285 1286#if SANITIZER_INTERCEPT_READDIR 1287INTERCEPTOR(__sanitizer_dirent *, readdir, void *dirp) { 1288 void *ctx; 1289 COMMON_INTERCEPTOR_ENTER(ctx, readdir, dirp); 1290 __sanitizer_dirent *res = REAL(readdir)(dirp); 1291 if (res) 1292 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen); 1293 return res; 1294} 1295 1296INTERCEPTOR(int, readdir_r, void *dirp, __sanitizer_dirent *entry, 1297 __sanitizer_dirent **result) { 1298 void *ctx; 1299 COMMON_INTERCEPTOR_ENTER(ctx, readdir_r, dirp, entry, result); 1300 int res = REAL(readdir_r)(dirp, entry, result); 1301 if (!res) { 1302 if (result) 1303 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1304 if (entry) 1305 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, entry, entry->d_reclen); 1306 } 1307 return res; 1308} 1309 1310#define INIT_READDIR \ 1311 INTERCEPT_FUNCTION(readdir); \ 1312 INTERCEPT_FUNCTION(readdir_r); 1313#else 1314#define INIT_READDIR 1315#endif 1316 1317#if SANITIZER_INTERCEPT_READDIR64 1318INTERCEPTOR(__sanitizer_dirent64 *, readdir64, void *dirp) { 1319 void *ctx; 1320 COMMON_INTERCEPTOR_ENTER(ctx, readdir64, dirp); 1321 __sanitizer_dirent64 *res = REAL(readdir64)(dirp); 1322 if (res) 1323 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen); 1324 return res; 1325} 1326 1327INTERCEPTOR(int, readdir64_r, void *dirp, __sanitizer_dirent64 *entry, 1328 __sanitizer_dirent64 **result) { 1329 void *ctx; 1330 COMMON_INTERCEPTOR_ENTER(ctx, readdir64_r, dirp, entry, result); 1331 int res = REAL(readdir64_r)(dirp, entry, result); 1332 if (!res) { 1333 if (result) 1334 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1335 if (entry) 1336 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, entry, entry->d_reclen); 1337 } 1338 return res; 1339} 1340#define INIT_READDIR64 \ 1341 INTERCEPT_FUNCTION(readdir64); \ 1342 INTERCEPT_FUNCTION(readdir64_r); 1343#else 1344#define INIT_READDIR64 1345#endif 1346 1347#if SANITIZER_INTERCEPT_PTRACE 1348INTERCEPTOR(uptr, ptrace, int request, int pid, void *addr, void *data) { 1349 void *ctx; 1350 COMMON_INTERCEPTOR_ENTER(ctx, ptrace, request, pid, addr, data); 1351 1352 if (data) { 1353 if (request == ptrace_setregs) 1354 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_regs_struct_sz); 1355 else if (request == ptrace_setfpregs) 1356 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpregs_struct_sz); 1357 else if (request == ptrace_setfpxregs) 1358 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpxregs_struct_sz); 1359 else if (request == ptrace_setsiginfo) 1360 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, siginfo_t_sz); 1361 else if (request == ptrace_setregset) { 1362 __sanitizer_iovec *iov = (__sanitizer_iovec *)data; 1363 COMMON_INTERCEPTOR_READ_RANGE(ctx, iov->iov_base, iov->iov_len); 1364 } 1365 } 1366 1367 uptr res = REAL(ptrace)(request, pid, addr, data); 1368 1369 if (!res && data) { 1370 // Note that PEEK* requests assing different meaning to the return value. 1371 // This function does not handle them (nor does it need to). 1372 if (request == ptrace_getregs) 1373 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_regs_struct_sz); 1374 else if (request == ptrace_getfpregs) 1375 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpregs_struct_sz); 1376 else if (request == ptrace_getfpxregs) 1377 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpxregs_struct_sz); 1378 else if (request == ptrace_getsiginfo) 1379 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, siginfo_t_sz); 1380 else if (request == ptrace_getregset) { 1381 __sanitizer_iovec *iov = (__sanitizer_iovec *)data; 1382 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iov->iov_base, iov->iov_len); 1383 } 1384 } 1385 return res; 1386} 1387 1388#define INIT_PTRACE \ 1389 INTERCEPT_FUNCTION(ptrace); 1390#else 1391#define INIT_PTRACE 1392#endif 1393 1394#if SANITIZER_INTERCEPT_SETLOCALE 1395INTERCEPTOR(char *, setlocale, int category, char *locale) { 1396 void *ctx; 1397 COMMON_INTERCEPTOR_ENTER(ctx, setlocale, category, locale); 1398 if (locale) 1399 COMMON_INTERCEPTOR_READ_RANGE(ctx, locale, REAL(strlen)(locale) + 1); 1400 char *res = REAL(setlocale)(category, locale); 1401 if (res) 1402 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1403 return res; 1404} 1405 1406#define INIT_SETLOCALE \ 1407 INTERCEPT_FUNCTION(setlocale); 1408#else 1409#define INIT_SETLOCALE 1410#endif 1411 1412#if SANITIZER_INTERCEPT_GETCWD 1413INTERCEPTOR(char *, getcwd, char *buf, SIZE_T size) { 1414 void *ctx; 1415 COMMON_INTERCEPTOR_ENTER(ctx, getcwd, buf, size); 1416 char *res = REAL(getcwd)(buf, size); 1417 if (res) 1418 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1419 return res; 1420} 1421#define INIT_GETCWD \ 1422 INTERCEPT_FUNCTION(getcwd); 1423#else 1424#define INIT_GETCWD 1425#endif 1426 1427#if SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME 1428INTERCEPTOR(char *, get_current_dir_name) { 1429 void *ctx; 1430 COMMON_INTERCEPTOR_ENTER(ctx, get_current_dir_name); 1431 char *res = REAL(get_current_dir_name)(); 1432 if (res) 1433 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1434 return res; 1435} 1436 1437#define INIT_GET_CURRENT_DIR_NAME \ 1438 INTERCEPT_FUNCTION(get_current_dir_name); 1439#else 1440#define INIT_GET_CURRENT_DIR_NAME 1441#endif 1442 1443#if SANITIZER_INTERCEPT_STRTOIMAX 1444INTERCEPTOR(INTMAX_T, strtoimax, const char *nptr, char **endptr, int base) { 1445 void *ctx; 1446 COMMON_INTERCEPTOR_ENTER(ctx, strtoimax, nptr, endptr, base); 1447 INTMAX_T res = REAL(strtoimax)(nptr, endptr, base); 1448 if (endptr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr)); 1449 return res; 1450} 1451 1452INTERCEPTOR(INTMAX_T, strtoumax, const char *nptr, char **endptr, int base) { 1453 void *ctx; 1454 COMMON_INTERCEPTOR_ENTER(ctx, strtoumax, nptr, endptr, base); 1455 INTMAX_T res = REAL(strtoumax)(nptr, endptr, base); 1456 if (endptr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr)); 1457 return res; 1458} 1459 1460#define INIT_STRTOIMAX \ 1461 INTERCEPT_FUNCTION(strtoimax); \ 1462 INTERCEPT_FUNCTION(strtoumax); 1463#else 1464#define INIT_STRTOIMAX 1465#endif 1466 1467#if SANITIZER_INTERCEPT_MBSTOWCS 1468INTERCEPTOR(SIZE_T, mbstowcs, wchar_t *dest, const char *src, SIZE_T len) { 1469 void *ctx; 1470 COMMON_INTERCEPTOR_ENTER(ctx, mbstowcs, dest, src, len); 1471 SIZE_T res = REAL(mbstowcs)(dest, src, len); 1472 if (res != (SIZE_T) - 1 && dest) 1473 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, (res + 1) * sizeof(wchar_t)); 1474 return res; 1475} 1476 1477INTERCEPTOR(SIZE_T, mbsrtowcs, wchar_t *dest, const char **src, SIZE_T len, 1478 void *ps) { 1479 void *ctx; 1480 COMMON_INTERCEPTOR_ENTER(ctx, mbsrtowcs, dest, src, len, ps); 1481 if (src) { 1482 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 1483 } 1484 SIZE_T res = REAL(mbsrtowcs)(dest, src, len, ps); 1485 if (res != (SIZE_T) - 1 && dest) 1486 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, (res + 1) * sizeof(wchar_t)); 1487 return res; 1488} 1489 1490#define INIT_MBSTOWCS \ 1491 INTERCEPT_FUNCTION(mbstowcs); \ 1492 INTERCEPT_FUNCTION(mbsrtowcs); 1493#else 1494#define INIT_MBSTOWCS 1495#endif 1496 1497#if SANITIZER_INTERCEPT_MBSNRTOWCS 1498INTERCEPTOR(SIZE_T, mbsnrtowcs, wchar_t *dest, const char **src, SIZE_T nms, 1499 SIZE_T len, void *ps) { 1500 void *ctx; 1501 COMMON_INTERCEPTOR_ENTER(ctx, mbsnrtowcs, dest, src, nms, len, ps); 1502 if (src) { 1503 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 1504 if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms); 1505 } 1506 SIZE_T res = REAL(mbsnrtowcs)(dest, src, nms, len, ps); 1507 if (res != (SIZE_T) - 1 && dest) 1508 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, (res + 1) * sizeof(wchar_t)); 1509 return res; 1510} 1511 1512#define INIT_MBSNRTOWCS INTERCEPT_FUNCTION(mbsnrtowcs); 1513#else 1514#define INIT_MBSNRTOWCS 1515#endif 1516 1517#if SANITIZER_INTERCEPT_WCSTOMBS 1518INTERCEPTOR(SIZE_T, wcstombs, char *dest, const wchar_t *src, SIZE_T len) { 1519 void *ctx; 1520 COMMON_INTERCEPTOR_ENTER(ctx, wcstombs, dest, src, len); 1521 SIZE_T res = REAL(wcstombs)(dest, src, len); 1522 if (res != (SIZE_T) - 1 && dest) 1523 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res + 1); 1524 return res; 1525} 1526 1527INTERCEPTOR(SIZE_T, wcsrtombs, char *dest, const wchar_t **src, SIZE_T len, 1528 void *ps) { 1529 void *ctx; 1530 COMMON_INTERCEPTOR_ENTER(ctx, wcsrtombs, dest, src, len, ps); 1531 if (src) { 1532 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 1533 } 1534 SIZE_T res = REAL(wcsrtombs)(dest, src, len, ps); 1535 if (res != (SIZE_T) - 1 && dest) 1536 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res + 1); 1537 return res; 1538} 1539 1540#define INIT_WCSTOMBS \ 1541 INTERCEPT_FUNCTION(wcstombs); \ 1542 INTERCEPT_FUNCTION(wcsrtombs); 1543#else 1544#define INIT_WCSTOMBS 1545#endif 1546 1547#if SANITIZER_INTERCEPT_WCSNRTOMBS 1548INTERCEPTOR(SIZE_T, wcsnrtombs, char *dest, const wchar_t **src, SIZE_T nms, 1549 SIZE_T len, void *ps) { 1550 void *ctx; 1551 COMMON_INTERCEPTOR_ENTER(ctx, wcsnrtombs, dest, src, nms, len, ps); 1552 if (src) { 1553 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 1554 if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms); 1555 } 1556 SIZE_T res = REAL(wcsnrtombs)(dest, src, nms, len, ps); 1557 if (res != (SIZE_T) - 1 && dest) 1558 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res + 1); 1559 return res; 1560} 1561 1562#define INIT_WCSNRTOMBS INTERCEPT_FUNCTION(wcsnrtombs); 1563#else 1564#define INIT_WCSNRTOMBS 1565#endif 1566 1567 1568#if SANITIZER_INTERCEPT_TCGETATTR 1569INTERCEPTOR(int, tcgetattr, int fd, void *termios_p) { 1570 void *ctx; 1571 COMMON_INTERCEPTOR_ENTER(ctx, tcgetattr, fd, termios_p); 1572 int res = REAL(tcgetattr)(fd, termios_p); 1573 if (!res && termios_p) 1574 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, termios_p, struct_termios_sz); 1575 return res; 1576} 1577 1578#define INIT_TCGETATTR INTERCEPT_FUNCTION(tcgetattr); 1579#else 1580#define INIT_TCGETATTR 1581#endif 1582 1583 1584#if SANITIZER_INTERCEPT_REALPATH 1585INTERCEPTOR(char *, realpath, const char *path, char *resolved_path) { 1586 void *ctx; 1587 COMMON_INTERCEPTOR_ENTER(ctx, realpath, path, resolved_path); 1588 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 1589 1590 // Workaround a bug in glibc where dlsym(RTLD_NEXT, ...) returns the oldest 1591 // version of a versioned symbol. For realpath(), this gives us something 1592 // (called __old_realpath) that does not handle NULL in the second argument. 1593 // Handle it as part of the interceptor. 1594 char *allocated_path = 0; 1595 if (!resolved_path) 1596 allocated_path = resolved_path = (char *)WRAP(malloc)(path_max + 1); 1597 1598 char *res = REAL(realpath)(path, resolved_path); 1599 if (allocated_path && !res) 1600 WRAP(free)(allocated_path); 1601 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1602 return res; 1603} 1604#define INIT_REALPATH INTERCEPT_FUNCTION(realpath); 1605#else 1606#define INIT_REALPATH 1607#endif 1608 1609#if SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME 1610INTERCEPTOR(char *, canonicalize_file_name, const char *path) { 1611 void *ctx; 1612 COMMON_INTERCEPTOR_ENTER(ctx, canonicalize_file_name, path); 1613 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 1614 char *res = REAL(canonicalize_file_name)(path); 1615 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1616 return res; 1617} 1618#define INIT_CANONICALIZE_FILE_NAME INTERCEPT_FUNCTION(canonicalize_file_name); 1619#else 1620#define INIT_CANONICALIZE_FILE_NAME 1621#endif 1622 1623#define SANITIZER_COMMON_INTERCEPTORS_INIT \ 1624 INIT_STRCASECMP; \ 1625 INIT_STRNCASECMP; \ 1626 INIT_READ; \ 1627 INIT_PREAD; \ 1628 INIT_PREAD64; \ 1629 INIT_READV; \ 1630 INIT_PREADV; \ 1631 INIT_PREADV64; \ 1632 INIT_WRITE; \ 1633 INIT_PWRITE; \ 1634 INIT_PWRITE64; \ 1635 INIT_WRITEV; \ 1636 INIT_PWRITEV; \ 1637 INIT_PWRITEV64; \ 1638 INIT_PRCTL; \ 1639 INIT_LOCALTIME_AND_FRIENDS; \ 1640 INIT_SCANF; \ 1641 INIT_FREXP; \ 1642 INIT_FREXPF_FREXPL; \ 1643 INIT_GETPWNAM_AND_FRIENDS; \ 1644 INIT_GETPWNAM_R_AND_FRIENDS; \ 1645 INIT_CLOCK_GETTIME; \ 1646 INIT_GETITIMER; \ 1647 INIT_TIME; \ 1648 INIT_GLOB; \ 1649 INIT_WAIT; \ 1650 INIT_INET; \ 1651 INIT_PTHREAD_GETSCHEDPARAM; \ 1652 INIT_GETADDRINFO; \ 1653 INIT_GETNAMEINFO; \ 1654 INIT_GETSOCKNAME; \ 1655 INIT_GETHOSTBYNAME; \ 1656 INIT_GETHOSTBYNAME_R; \ 1657 INIT_GETSOCKOPT; \ 1658 INIT_ACCEPT; \ 1659 INIT_ACCEPT4; \ 1660 INIT_MODF; \ 1661 INIT_RECVMSG; \ 1662 INIT_GETPEERNAME; \ 1663 INIT_IOCTL; \ 1664 INIT_INET_ATON; \ 1665 INIT_SYSINFO; \ 1666 INIT_READDIR; \ 1667 INIT_READDIR64; \ 1668 INIT_PTRACE; \ 1669 INIT_SETLOCALE; \ 1670 INIT_GETCWD; \ 1671 INIT_GET_CURRENT_DIR_NAME; \ 1672 INIT_STRTOIMAX; \ 1673 INIT_MBSTOWCS; \ 1674 INIT_MBSNRTOWCS; \ 1675 INIT_WCSTOMBS; \ 1676 INIT_WCSNRTOMBS; \ 1677 INIT_TCGETATTR; \ 1678 INIT_REALPATH; \ 1679 INIT_CANONICALIZE_FILE_NAME; 1680