sanitizer_common_interceptors.inc revision 0586dcc3e531d43dca6b5d226bac2d38b5ad64fe
1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//===-- sanitizer_common_interceptors.inc -----------------------*- C++ -*-===// 2868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// 3868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// The LLVM Compiler Infrastructure 4868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// 5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source 6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// License. See LICENSE.TXT for details. 7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//===----------------------------------------------------------------------===// 9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// 10a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Common function interceptors for tools like AddressSanitizer, 11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// ThreadSanitizer, MemorySanitizer, etc. 12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// 13effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// This file should be included into the tool's interceptor file, 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// which has to define it's own macros: 15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// COMMON_INTERCEPTOR_ENTER 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// COMMON_INTERCEPTOR_READ_RANGE 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// COMMON_INTERCEPTOR_WRITE_RANGE 18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// COMMON_INTERCEPTOR_INITIALIZE_RANGE 19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// COMMON_INTERCEPTOR_FD_ACQUIRE 20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// COMMON_INTERCEPTOR_FD_RELEASE 21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// COMMON_INTERCEPTOR_SET_THREAD_NAME 2268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)//===----------------------------------------------------------------------===// 23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "interception/interception.h" 24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "sanitizer_platform_interceptors.h" 25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <stdarg.h> 27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#if SANITIZER_WINDOWS 29558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#define va_copy(dst, src) ((dst) = (src)) 30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif // _WIN32 31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#ifndef COMMON_INTERCEPTOR_INITIALIZE_RANGE 33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)# define COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, p, size) 34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif 35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 36424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#if SANITIZER_INTERCEPT_STRCMP 3768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)static inline int CharCmpX(unsigned char c1, unsigned char c2) { 38424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1; 39868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)INTERCEPTOR(int, strcmp, const char *s1, const char *s2) { 42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void *ctx; 43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) COMMON_INTERCEPTOR_ENTER(ctx, strcmp, s1, s2); 44868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) unsigned char c1, c2; 45a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uptr i; 46868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (i = 0; ; i++) { 47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) c1 = (unsigned char)s1[i]; 48868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) c2 = (unsigned char)s2[i]; 49868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (c1 != c2 || c1 == '\0') break; 50868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 51868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, i + 1); 52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, i + 1); 535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return CharCmpX(c1, c2); 547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)INTERCEPTOR(int, strncmp, const char *s1, const char *s2, uptr size) { 57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void *ctx; 58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) COMMON_INTERCEPTOR_ENTER(ctx, strncmp, s1, s2, size); 59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) unsigned char c1 = 0, c2 = 0; 60effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch uptr i; 61effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch for (i = 0; i < size; i++) { 620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch c1 = (unsigned char)s1[i]; 63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) c2 = (unsigned char)s2[i]; 64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (c1 != c2 || c1 == '\0') break; 65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, size)); 67868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, size)); 68effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return CharCmpX(c1, c2); 690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#define INIT_STRCMP INTERCEPT_FUNCTION(strcmp) 72868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#define INIT_STRNCMP INTERCEPT_FUNCTION(strncmp) 73868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#else 74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#define INIT_STRCMP 75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#define INIT_STRNCMP 76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif 773240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 7868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#if SANITIZER_INTERCEPT_STRCASECMP 793240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochstatic inline int CharCaseCmp(unsigned char c1, unsigned char c2) { 80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int c1_low = ToLower(c1); 81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int c2_low = ToLower(c2); 82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return c1_low - c2_low; 83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)INTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) { 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void *ctx; 87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) COMMON_INTERCEPTOR_ENTER(ctx, strcasecmp, s1, s2); 88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) unsigned char c1 = 0, c2 = 0; 89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) uptr i; 90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (i = 0; ; i++) { 91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) c1 = (unsigned char)s1[i]; 92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) c2 = (unsigned char)s2[i]; 93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') 94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) break; 95868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, i + 1); 97868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, i + 1); 98868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return CharCaseCmp(c1, c2); 99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)INTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, SIZE_T n) { 102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void *ctx; 103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) COMMON_INTERCEPTOR_ENTER(ctx, strncasecmp, s1, s2, n); 104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) unsigned char c1 = 0, c2 = 0; 105868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) uptr i; 106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (i = 0; i < n; i++) { 107 c1 = (unsigned char)s1[i]; 108 c2 = (unsigned char)s2[i]; 109 if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') 110 break; 111 } 112 COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, n)); 113 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, n)); 114 return CharCaseCmp(c1, c2); 115} 116 117#define INIT_STRCASECMP INTERCEPT_FUNCTION(strcasecmp) 118#define INIT_STRNCASECMP INTERCEPT_FUNCTION(strncasecmp) 119#else 120#define INIT_STRCASECMP 121#define INIT_STRNCASECMP 122#endif 123 124#if SANITIZER_INTERCEPT_FREXP 125INTERCEPTOR(double, frexp, double x, int *exp) { 126 void *ctx; 127 COMMON_INTERCEPTOR_ENTER(ctx, frexp, x, exp); 128 double res = REAL(frexp)(x, exp); 129 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp)); 130 return res; 131} 132 133#define INIT_FREXP INTERCEPT_FUNCTION(frexp); 134#else 135#define INIT_FREXP 136#endif // SANITIZER_INTERCEPT_FREXP 137 138#if SANITIZER_INTERCEPT_FREXPF_FREXPL 139INTERCEPTOR(float, frexpf, float x, int *exp) { 140 void *ctx; 141 COMMON_INTERCEPTOR_ENTER(ctx, frexpf, x, exp); 142 float res = REAL(frexpf)(x, exp); 143 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp)); 144 return res; 145} 146 147INTERCEPTOR(long double, frexpl, long double x, int *exp) { 148 void *ctx; 149 COMMON_INTERCEPTOR_ENTER(ctx, frexpl, x, exp); 150 long double res = REAL(frexpl)(x, exp); 151 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp)); 152 return res; 153} 154 155#define INIT_FREXPF_FREXPL \ 156 INTERCEPT_FUNCTION(frexpf); \ 157 INTERCEPT_FUNCTION(frexpl) 158#else 159#define INIT_FREXPF_FREXPL 160#endif // SANITIZER_INTERCEPT_FREXPF_FREXPL 161 162#if SI_NOT_WINDOWS 163static void write_iovec(void *ctx, struct __sanitizer_iovec *iovec, 164 SIZE_T iovlen, SIZE_T maxlen) { 165 for (SIZE_T i = 0; i < iovlen && maxlen; ++i) { 166 SSIZE_T sz = Min(iovec[i].iov_len, maxlen); 167 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec[i].iov_base, sz); 168 maxlen -= sz; 169 } 170} 171 172static void read_iovec(void *ctx, struct __sanitizer_iovec *iovec, 173 SIZE_T iovlen, SIZE_T maxlen) { 174 COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec) * iovlen); 175 for (SIZE_T i = 0; i < iovlen && maxlen; ++i) { 176 SSIZE_T sz = Min(iovec[i].iov_len, maxlen); 177 COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec[i].iov_base, sz); 178 maxlen -= sz; 179 } 180} 181#endif 182 183#if SANITIZER_INTERCEPT_READ 184INTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) { 185 void *ctx; 186 COMMON_INTERCEPTOR_ENTER(ctx, read, fd, ptr, count); 187 SSIZE_T res = REAL(read)(fd, ptr, count); 188 if (res > 0) 189 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); 190 if (res >= 0 && fd >= 0) 191 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 192 return res; 193} 194#define INIT_READ INTERCEPT_FUNCTION(read) 195#else 196#define INIT_READ 197#endif 198 199#if SANITIZER_INTERCEPT_PREAD 200INTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) { 201 void *ctx; 202 COMMON_INTERCEPTOR_ENTER(ctx, pread, fd, ptr, count, offset); 203 SSIZE_T res = REAL(pread)(fd, ptr, count, offset); 204 if (res > 0) 205 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); 206 if (res >= 0 && fd >= 0) 207 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 208 return res; 209} 210#define INIT_PREAD INTERCEPT_FUNCTION(pread) 211#else 212#define INIT_PREAD 213#endif 214 215#if SANITIZER_INTERCEPT_PREAD64 216INTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) { 217 void *ctx; 218 COMMON_INTERCEPTOR_ENTER(ctx, pread64, fd, ptr, count, offset); 219 SSIZE_T res = REAL(pread64)(fd, ptr, count, offset); 220 if (res > 0) 221 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); 222 if (res >= 0 && fd >= 0) 223 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 224 return res; 225} 226#define INIT_PREAD64 INTERCEPT_FUNCTION(pread64) 227#else 228#define INIT_PREAD64 229#endif 230 231#if SANITIZER_INTERCEPT_READV 232INTERCEPTOR_WITH_SUFFIX(SSIZE_T, readv, int fd, __sanitizer_iovec *iov, 233 int iovcnt) { 234 void *ctx; 235 COMMON_INTERCEPTOR_ENTER(ctx, readv, fd, iov, iovcnt); 236 SSIZE_T res = REAL(readv)(fd, iov, iovcnt); 237 if (res > 0) write_iovec(ctx, iov, iovcnt, res); 238 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 239 return res; 240} 241#define INIT_READV INTERCEPT_FUNCTION(readv) 242#else 243#define INIT_READV 244#endif 245 246#if SANITIZER_INTERCEPT_PREADV 247INTERCEPTOR(SSIZE_T, preadv, int fd, __sanitizer_iovec *iov, int iovcnt, 248 OFF_T offset) { 249 void *ctx; 250 COMMON_INTERCEPTOR_ENTER(ctx, preadv, fd, iov, iovcnt, offset); 251 SSIZE_T res = REAL(preadv)(fd, iov, iovcnt, offset); 252 if (res > 0) write_iovec(ctx, iov, iovcnt, res); 253 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 254 return res; 255} 256#define INIT_PREADV INTERCEPT_FUNCTION(preadv) 257#else 258#define INIT_PREADV 259#endif 260 261#if SANITIZER_INTERCEPT_PREADV64 262INTERCEPTOR(SSIZE_T, preadv64, int fd, __sanitizer_iovec *iov, int iovcnt, 263 OFF64_T offset) { 264 void *ctx; 265 COMMON_INTERCEPTOR_ENTER(ctx, preadv64, fd, iov, iovcnt, offset); 266 SSIZE_T res = REAL(preadv64)(fd, iov, iovcnt, offset); 267 if (res > 0) write_iovec(ctx, iov, iovcnt, res); 268 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 269 return res; 270} 271#define INIT_PREADV64 INTERCEPT_FUNCTION(preadv64) 272#else 273#define INIT_PREADV64 274#endif 275 276#if SANITIZER_INTERCEPT_WRITE 277INTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) { 278 void *ctx; 279 COMMON_INTERCEPTOR_ENTER(ctx, write, fd, ptr, count); 280 if (fd >= 0) 281 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 282 SSIZE_T res = REAL(write)(fd, ptr, count); 283 // FIXME: this check should be _before_ the call to REAL(write), not after 284 if (res > 0) 285 COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); 286 return res; 287} 288#define INIT_WRITE INTERCEPT_FUNCTION(write) 289#else 290#define INIT_WRITE 291#endif 292 293#if SANITIZER_INTERCEPT_PWRITE 294INTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) { 295 void *ctx; 296 COMMON_INTERCEPTOR_ENTER(ctx, pwrite, fd, ptr, count, offset); 297 if (fd >= 0) 298 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 299 SSIZE_T res = REAL(pwrite)(fd, ptr, count, offset); 300 if (res > 0) 301 COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); 302 return res; 303} 304#define INIT_PWRITE INTERCEPT_FUNCTION(pwrite) 305#else 306#define INIT_PWRITE 307#endif 308 309#if SANITIZER_INTERCEPT_PWRITE64 310INTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count, 311 OFF64_T offset) { 312 void *ctx; 313 COMMON_INTERCEPTOR_ENTER(ctx, pwrite64, fd, ptr, count, offset); 314 if (fd >= 0) 315 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 316 SSIZE_T res = REAL(pwrite64)(fd, ptr, count, offset); 317 if (res > 0) 318 COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); 319 return res; 320} 321#define INIT_PWRITE64 INTERCEPT_FUNCTION(pwrite64) 322#else 323#define INIT_PWRITE64 324#endif 325 326#if SANITIZER_INTERCEPT_WRITEV 327INTERCEPTOR_WITH_SUFFIX(SSIZE_T, writev, int fd, __sanitizer_iovec *iov, 328 int iovcnt) { 329 void *ctx; 330 COMMON_INTERCEPTOR_ENTER(ctx, writev, fd, iov, iovcnt); 331 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 332 SSIZE_T res = REAL(writev)(fd, iov, iovcnt); 333 if (res > 0) read_iovec(ctx, iov, iovcnt, res); 334 return res; 335} 336#define INIT_WRITEV INTERCEPT_FUNCTION(writev) 337#else 338#define INIT_WRITEV 339#endif 340 341#if SANITIZER_INTERCEPT_PWRITEV 342INTERCEPTOR(SSIZE_T, pwritev, int fd, __sanitizer_iovec *iov, int iovcnt, 343 OFF_T offset) { 344 void *ctx; 345 COMMON_INTERCEPTOR_ENTER(ctx, pwritev, fd, iov, iovcnt, offset); 346 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 347 SSIZE_T res = REAL(pwritev)(fd, iov, iovcnt, offset); 348 if (res > 0) read_iovec(ctx, iov, iovcnt, res); 349 return res; 350} 351#define INIT_PWRITEV INTERCEPT_FUNCTION(pwritev) 352#else 353#define INIT_PWRITEV 354#endif 355 356#if SANITIZER_INTERCEPT_PWRITEV64 357INTERCEPTOR(SSIZE_T, pwritev64, int fd, __sanitizer_iovec *iov, int iovcnt, 358 OFF64_T offset) { 359 void *ctx; 360 COMMON_INTERCEPTOR_ENTER(ctx, pwritev64, fd, iov, iovcnt, offset); 361 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 362 SSIZE_T res = REAL(pwritev64)(fd, iov, iovcnt, offset); 363 if (res > 0) read_iovec(ctx, iov, iovcnt, res); 364 return res; 365} 366#define INIT_PWRITEV64 INTERCEPT_FUNCTION(pwritev64) 367#else 368#define INIT_PWRITEV64 369#endif 370 371#if SANITIZER_INTERCEPT_PRCTL 372INTERCEPTOR(int, prctl, int option, 373 unsigned long arg2, unsigned long arg3, // NOLINT 374 unsigned long arg4, unsigned long arg5) { // NOLINT 375 void *ctx; 376 COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5); 377 static const int PR_SET_NAME = 15; 378 int res = REAL(prctl(option, arg2, arg3, arg4, arg5)); 379 if (option == PR_SET_NAME) { 380 char buff[16]; 381 internal_strncpy(buff, (char *)arg2, 15); 382 buff[15] = 0; 383 COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff); 384 } 385 return res; 386} 387#define INIT_PRCTL INTERCEPT_FUNCTION(prctl) 388#else 389#define INIT_PRCTL 390#endif // SANITIZER_INTERCEPT_PRCTL 391 392 393#if SANITIZER_INTERCEPT_TIME 394INTERCEPTOR(unsigned long, time, unsigned long *t) { 395 void *ctx; 396 COMMON_INTERCEPTOR_ENTER(ctx, time, t); 397 unsigned long res = REAL(time)(t); 398 if (t && res != (unsigned long)-1) { 399 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, t, sizeof(*t)); 400 } 401 return res; 402} 403#define INIT_TIME \ 404 INTERCEPT_FUNCTION(time); 405#else 406#define INIT_TIME 407#endif // SANITIZER_INTERCEPT_TIME 408 409 410#if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS 411static void unpoison_tm(void *ctx, __sanitizer_tm *tm) { 412 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm)); 413 if (tm->tm_zone) { 414 // Can not use COMMON_INTERCEPTOR_WRITE_RANGE here, because tm->tm_zone 415 // can point to shared memory and tsan would report a data race. 416 COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, tm->tm_zone, 417 REAL(strlen(tm->tm_zone)) + 1); 418 } 419} 420 421INTERCEPTOR(__sanitizer_tm *, localtime, unsigned long *timep) { 422 void *ctx; 423 COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep); 424 __sanitizer_tm *res = REAL(localtime)(timep); 425 if (res) { 426 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 427 unpoison_tm(ctx, res); 428 } 429 return res; 430} 431INTERCEPTOR(__sanitizer_tm *, localtime_r, unsigned long *timep, void *result) { 432 void *ctx; 433 COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result); 434 __sanitizer_tm *res = REAL(localtime_r)(timep, result); 435 if (res) { 436 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 437 unpoison_tm(ctx, res); 438 } 439 return res; 440} 441INTERCEPTOR(__sanitizer_tm *, gmtime, unsigned long *timep) { 442 void *ctx; 443 COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep); 444 __sanitizer_tm *res = REAL(gmtime)(timep); 445 if (res) { 446 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 447 unpoison_tm(ctx, res); 448 } 449 return res; 450} 451INTERCEPTOR(__sanitizer_tm *, gmtime_r, unsigned long *timep, void *result) { 452 void *ctx; 453 COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result); 454 __sanitizer_tm *res = REAL(gmtime_r)(timep, result); 455 if (res) { 456 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 457 unpoison_tm(ctx, res); 458 } 459 return res; 460} 461INTERCEPTOR(char *, ctime, unsigned long *timep) { 462 void *ctx; 463 COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep); 464 char *res = REAL(ctime)(timep); 465 if (res) { 466 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 467 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 468 } 469 return res; 470} 471INTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) { 472 void *ctx; 473 COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result); 474 char *res = REAL(ctime_r)(timep, result); 475 if (res) { 476 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 477 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 478 } 479 return res; 480} 481INTERCEPTOR(char *, asctime, __sanitizer_tm *tm) { 482 void *ctx; 483 COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm); 484 char *res = REAL(asctime)(tm); 485 if (res) { 486 COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm)); 487 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 488 } 489 return res; 490} 491INTERCEPTOR(char *, asctime_r, __sanitizer_tm *tm, char *result) { 492 void *ctx; 493 COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result); 494 char *res = REAL(asctime_r)(tm, result); 495 if (res) { 496 COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm)); 497 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 498 } 499 return res; 500} 501#define INIT_LOCALTIME_AND_FRIENDS \ 502 INTERCEPT_FUNCTION(localtime); \ 503 INTERCEPT_FUNCTION(localtime_r); \ 504 INTERCEPT_FUNCTION(gmtime); \ 505 INTERCEPT_FUNCTION(gmtime_r); \ 506 INTERCEPT_FUNCTION(ctime); \ 507 INTERCEPT_FUNCTION(ctime_r); \ 508 INTERCEPT_FUNCTION(asctime); \ 509 INTERCEPT_FUNCTION(asctime_r); 510#else 511#define INIT_LOCALTIME_AND_FRIENDS 512#endif // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS 513 514#if SANITIZER_INTERCEPT_SCANF 515 516#include "sanitizer_common_interceptors_scanf.inc" 517 518#define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...) \ 519 { \ 520 void *ctx; \ 521 COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__); \ 522 va_list aq; \ 523 va_copy(aq, ap); \ 524 int res = REAL(vname)(__VA_ARGS__); \ 525 if (res > 0) \ 526 scanf_common(ctx, res, allowGnuMalloc, format, aq); \ 527 va_end(aq); \ 528 return res; \ 529 } 530 531INTERCEPTOR(int, vscanf, const char *format, va_list ap) 532VSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap) 533 534INTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap) 535VSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap) 536 537INTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap) 538VSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap) 539 540#if SANITIZER_INTERCEPT_ISOC99_SCANF 541INTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap) 542VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap) 543 544INTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format, 545 va_list ap) 546VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap) 547 548INTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap) 549VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap) 550#endif // SANITIZER_INTERCEPT_ISOC99_SCANF 551 552#define SCANF_INTERCEPTOR_IMPL(name, vname, ...) \ 553 { \ 554 void *ctx; \ 555 va_list ap; \ 556 va_start(ap, format); \ 557 COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__, ap); \ 558 int res = vname(__VA_ARGS__, ap); \ 559 va_end(ap); \ 560 return res; \ 561 } 562 563INTERCEPTOR(int, scanf, const char *format, ...) 564SCANF_INTERCEPTOR_IMPL(scanf, vscanf, format) 565 566INTERCEPTOR(int, fscanf, void *stream, const char *format, ...) 567SCANF_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format) 568 569INTERCEPTOR(int, sscanf, const char *str, const char *format, ...) 570SCANF_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format) 571 572#if SANITIZER_INTERCEPT_ISOC99_SCANF 573INTERCEPTOR(int, __isoc99_scanf, const char *format, ...) 574SCANF_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format) 575 576INTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...) 577SCANF_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format) 578 579INTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...) 580SCANF_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format) 581#endif 582 583#endif 584 585#if SANITIZER_INTERCEPT_SCANF 586#define INIT_SCANF \ 587 INTERCEPT_FUNCTION(scanf); \ 588 INTERCEPT_FUNCTION(sscanf); \ 589 INTERCEPT_FUNCTION(fscanf); \ 590 INTERCEPT_FUNCTION(vscanf); \ 591 INTERCEPT_FUNCTION(vsscanf); \ 592 INTERCEPT_FUNCTION(vfscanf); 593#else 594#define INIT_SCANF 595#endif 596 597#if SANITIZER_INTERCEPT_ISOC99_SCANF 598#define INIT_ISOC99_SCANF \ 599 INTERCEPT_FUNCTION(__isoc99_scanf); \ 600 INTERCEPT_FUNCTION(__isoc99_sscanf); \ 601 INTERCEPT_FUNCTION(__isoc99_fscanf); \ 602 INTERCEPT_FUNCTION(__isoc99_vscanf); \ 603 INTERCEPT_FUNCTION(__isoc99_vsscanf); \ 604 INTERCEPT_FUNCTION(__isoc99_vfscanf); 605#else 606#define INIT_ISOC99_SCANF 607#endif 608 609#if SANITIZER_INTERCEPT_IOCTL 610#include "sanitizer_common_interceptors_ioctl.inc" 611INTERCEPTOR(int, ioctl, int d, unsigned request, void *arg) { 612 void *ctx; 613 COMMON_INTERCEPTOR_ENTER(ctx, ioctl, d, request, arg); 614 615 CHECK(ioctl_initialized); 616 617 // Note: TSan does not use common flags, and they are zero-initialized. 618 // This effectively disables ioctl handling in TSan. 619 if (!common_flags()->handle_ioctl) 620 return REAL(ioctl)(d, request, arg); 621 622 const ioctl_desc *desc = ioctl_lookup(request); 623 if (!desc) 624 Printf("WARNING: unknown ioctl %x\n", request); 625 626 if (desc) 627 ioctl_common_pre(ctx, desc, d, request, arg); 628 int res = REAL(ioctl)(d, request, arg); 629 // FIXME: some ioctls have different return values for success and failure. 630 if (desc && res != -1) 631 ioctl_common_post(ctx, desc, res, d, request, arg); 632 return res; 633} 634#define INIT_IOCTL \ 635 ioctl_init(); \ 636 INTERCEPT_FUNCTION(ioctl); 637#else 638#define INIT_IOCTL 639#endif 640 641 642#if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS 643INTERCEPTOR(void *, getpwnam, const char *name) { 644 void *ctx; 645 COMMON_INTERCEPTOR_ENTER(ctx, getpwnam, name); 646 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 647 void *res = REAL(getpwnam)(name); 648 if (res != 0) 649 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_passwd_sz); 650 return res; 651} 652INTERCEPTOR(void *, getpwuid, u32 uid) { 653 void *ctx; 654 COMMON_INTERCEPTOR_ENTER(ctx, getpwuid, uid); 655 void *res = REAL(getpwuid)(uid); 656 if (res != 0) 657 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_passwd_sz); 658 return res; 659} 660INTERCEPTOR(void *, getgrnam, const char *name) { 661 void *ctx; 662 COMMON_INTERCEPTOR_ENTER(ctx, getgrnam, name); 663 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 664 void *res = REAL(getgrnam)(name); 665 if (res != 0) 666 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_group_sz); 667 return res; 668} 669INTERCEPTOR(void *, getgrgid, u32 gid) { 670 void *ctx; 671 COMMON_INTERCEPTOR_ENTER(ctx, getgrgid, gid); 672 void *res = REAL(getgrgid)(gid); 673 if (res != 0) 674 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_group_sz); 675 return res; 676} 677#define INIT_GETPWNAM_AND_FRIENDS \ 678 INTERCEPT_FUNCTION(getpwnam); \ 679 INTERCEPT_FUNCTION(getpwuid); \ 680 INTERCEPT_FUNCTION(getgrnam); \ 681 INTERCEPT_FUNCTION(getgrgid); 682#else 683#define INIT_GETPWNAM_AND_FRIENDS 684#endif 685 686 687#if SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS 688INTERCEPTOR(int, getpwnam_r, const char *name, void *pwd, 689 char *buf, SIZE_T buflen, void **result) { 690 void *ctx; 691 COMMON_INTERCEPTOR_ENTER(ctx, getpwnam_r, name, pwd, buf, buflen, result); 692 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 693 int res = REAL(getpwnam_r)(name, pwd, buf, buflen, result); 694 if (!res) { 695 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, struct_passwd_sz); 696 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 697 } 698 return res; 699} 700INTERCEPTOR(int, getpwuid_r, u32 uid, void *pwd, 701 char *buf, SIZE_T buflen, void **result) { 702 void *ctx; 703 COMMON_INTERCEPTOR_ENTER(ctx, getpwuid_r, uid, pwd, buf, buflen, result); 704 int res = REAL(getpwuid_r)(uid, pwd, buf, buflen, result); 705 if (!res) { 706 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, struct_passwd_sz); 707 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 708 } 709 return res; 710} 711INTERCEPTOR(int, getgrnam_r, const char *name, void *grp, 712 char *buf, SIZE_T buflen, void **result) { 713 void *ctx; 714 COMMON_INTERCEPTOR_ENTER(ctx, getgrnam_r, name, grp, buf, buflen, result); 715 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 716 int res = REAL(getgrnam_r)(name, grp, buf, buflen, result); 717 if (!res) { 718 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, struct_group_sz); 719 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 720 } 721 return res; 722} 723INTERCEPTOR(int, getgrgid_r, u32 gid, void *grp, 724 char *buf, SIZE_T buflen, void **result) { 725 void *ctx; 726 COMMON_INTERCEPTOR_ENTER(ctx, getgrgid_r, gid, grp, buf, buflen, result); 727 int res = REAL(getgrgid_r)(gid, grp, buf, buflen, result); 728 if (!res) { 729 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, struct_group_sz); 730 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 731 } 732 return res; 733} 734#define INIT_GETPWNAM_R_AND_FRIENDS \ 735 INTERCEPT_FUNCTION(getpwnam_r); \ 736 INTERCEPT_FUNCTION(getpwuid_r); \ 737 INTERCEPT_FUNCTION(getgrnam_r); \ 738 INTERCEPT_FUNCTION(getgrgid_r); 739#else 740#define INIT_GETPWNAM_R_AND_FRIENDS 741#endif 742 743 744#if SANITIZER_INTERCEPT_CLOCK_GETTIME 745INTERCEPTOR(int, clock_getres, u32 clk_id, void *tp) { 746 void *ctx; 747 COMMON_INTERCEPTOR_ENTER(ctx, clock_getres, clk_id, tp); 748 int res = REAL(clock_getres)(clk_id, tp); 749 if (!res && tp) { 750 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz); 751 } 752 return res; 753} 754INTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) { 755 void *ctx; 756 COMMON_INTERCEPTOR_ENTER(ctx, clock_gettime, clk_id, tp); 757 int res = REAL(clock_gettime)(clk_id, tp); 758 if (!res) { 759 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz); 760 } 761 return res; 762} 763INTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) { 764 void *ctx; 765 COMMON_INTERCEPTOR_ENTER(ctx, clock_settime, clk_id, tp); 766 COMMON_INTERCEPTOR_READ_RANGE(ctx, tp, struct_timespec_sz); 767 return REAL(clock_settime)(clk_id, tp); 768} 769#define INIT_CLOCK_GETTIME \ 770 INTERCEPT_FUNCTION(clock_getres); \ 771 INTERCEPT_FUNCTION(clock_gettime); \ 772 INTERCEPT_FUNCTION(clock_settime); 773#else 774#define INIT_CLOCK_GETTIME 775#endif 776 777 778#if SANITIZER_INTERCEPT_GETITIMER 779INTERCEPTOR(int, getitimer, int which, void *curr_value) { 780 void *ctx; 781 COMMON_INTERCEPTOR_ENTER(ctx, getitimer, which, curr_value); 782 int res = REAL(getitimer)(which, curr_value); 783 if (!res && curr_value) { 784 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerval_sz); 785 } 786 return res; 787} 788INTERCEPTOR(int, setitimer, int which, const void *new_value, void *old_value) { 789 void *ctx; 790 COMMON_INTERCEPTOR_ENTER(ctx, setitimer, which, new_value, old_value); 791 if (new_value) 792 COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerval_sz); 793 int res = REAL(setitimer)(which, new_value, old_value); 794 if (!res && old_value) { 795 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerval_sz); 796 } 797 return res; 798} 799#define INIT_GETITIMER \ 800 INTERCEPT_FUNCTION(getitimer); \ 801 INTERCEPT_FUNCTION(setitimer); 802#else 803#define INIT_GETITIMER 804#endif 805 806#if SANITIZER_INTERCEPT_GLOB 807static void unpoison_glob_t(void *ctx, __sanitizer_glob_t *pglob) { 808 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob)); 809 // +1 for NULL pointer at the end. 810 if (pglob->gl_pathv) 811 COMMON_INTERCEPTOR_WRITE_RANGE( 812 ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv)); 813 for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) { 814 char *p = pglob->gl_pathv[i]; 815 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, REAL(strlen)(p) + 1); 816 } 817} 818 819static THREADLOCAL __sanitizer_glob_t* pglob_copy; 820static THREADLOCAL void* glob_ctx; 821 822static void wrapped_gl_closedir(void *dir) { 823 COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 1); 824 pglob_copy->gl_closedir(dir); 825} 826 827static void *wrapped_gl_readdir(void *dir) { 828 COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 1); 829 return pglob_copy->gl_readdir(dir); 830} 831 832static void *wrapped_gl_opendir(const char *s) { 833 COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 1); 834 COMMON_INTERCEPTOR_WRITE_RANGE(glob_ctx, s, REAL(strlen)(s) + 1); 835 return pglob_copy->gl_opendir(s); 836} 837 838static int wrapped_gl_lstat(const char *s, void *st) { 839 COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 2); 840 COMMON_INTERCEPTOR_WRITE_RANGE(glob_ctx, s, REAL(strlen)(s) + 1); 841 return pglob_copy->gl_lstat(s, st); 842} 843 844static int wrapped_gl_stat(const char *s, void *st) { 845 COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 2); 846 COMMON_INTERCEPTOR_WRITE_RANGE(glob_ctx, s, REAL(strlen)(s) + 1); 847 return pglob_copy->gl_stat(s, st); 848} 849 850INTERCEPTOR(int, glob, const char *pattern, int flags, 851 int (*errfunc)(const char *epath, int eerrno), 852 __sanitizer_glob_t *pglob) { 853 void *ctx; 854 COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob); 855 __sanitizer_glob_t glob_copy = {0, 0, 0, 0, wrapped_gl_closedir, 856 wrapped_gl_readdir, wrapped_gl_opendir, 857 wrapped_gl_lstat, wrapped_gl_stat}; 858 if (flags & glob_altdirfunc) { 859 Swap(pglob->gl_closedir, glob_copy.gl_closedir); 860 Swap(pglob->gl_readdir, glob_copy.gl_readdir); 861 Swap(pglob->gl_opendir, glob_copy.gl_opendir); 862 Swap(pglob->gl_lstat, glob_copy.gl_lstat); 863 Swap(pglob->gl_stat, glob_copy.gl_stat); 864 pglob_copy = &glob_copy; 865 glob_ctx = ctx; 866 } 867 int res = REAL(glob)(pattern, flags, errfunc, pglob); 868 if (flags & glob_altdirfunc) { 869 Swap(pglob->gl_closedir, glob_copy.gl_closedir); 870 Swap(pglob->gl_readdir, glob_copy.gl_readdir); 871 Swap(pglob->gl_opendir, glob_copy.gl_opendir); 872 Swap(pglob->gl_lstat, glob_copy.gl_lstat); 873 Swap(pglob->gl_stat, glob_copy.gl_stat); 874 } 875 pglob_copy = 0; 876 glob_ctx = 0; 877 if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob); 878 return res; 879} 880 881INTERCEPTOR(int, glob64, const char *pattern, int flags, 882 int (*errfunc)(const char *epath, int eerrno), 883 __sanitizer_glob_t *pglob) { 884 void *ctx; 885 COMMON_INTERCEPTOR_ENTER(ctx, glob64, pattern, flags, errfunc, pglob); 886 __sanitizer_glob_t glob_copy = {0, 0, 0, 0, wrapped_gl_closedir, 887 wrapped_gl_readdir, wrapped_gl_opendir, 888 wrapped_gl_lstat, wrapped_gl_stat}; 889 if (flags & glob_altdirfunc) { 890 Swap(pglob->gl_closedir, glob_copy.gl_closedir); 891 Swap(pglob->gl_readdir, glob_copy.gl_readdir); 892 Swap(pglob->gl_opendir, glob_copy.gl_opendir); 893 Swap(pglob->gl_lstat, glob_copy.gl_lstat); 894 Swap(pglob->gl_stat, glob_copy.gl_stat); 895 pglob_copy = &glob_copy; 896 glob_ctx = ctx; 897 } 898 int res = REAL(glob64)(pattern, flags, errfunc, pglob); 899 if (flags & glob_altdirfunc) { 900 Swap(pglob->gl_closedir, glob_copy.gl_closedir); 901 Swap(pglob->gl_readdir, glob_copy.gl_readdir); 902 Swap(pglob->gl_opendir, glob_copy.gl_opendir); 903 Swap(pglob->gl_lstat, glob_copy.gl_lstat); 904 Swap(pglob->gl_stat, glob_copy.gl_stat); 905 } 906 pglob_copy = 0; 907 glob_ctx = 0; 908 if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob); 909 return res; 910} 911#define INIT_GLOB \ 912 INTERCEPT_FUNCTION(glob); \ 913 INTERCEPT_FUNCTION(glob64); 914#else // SANITIZER_INTERCEPT_GLOB 915#define INIT_GLOB 916#endif // SANITIZER_INTERCEPT_GLOB 917 918#if SANITIZER_INTERCEPT_WAIT 919// According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version 920// suffixes on Darwin. See the declaration of INTERCEPTOR_WITH_SUFFIX for 921// details. 922INTERCEPTOR_WITH_SUFFIX(int, wait, int *status) { 923 void *ctx; 924 COMMON_INTERCEPTOR_ENTER(ctx, wait, status); 925 int res = REAL(wait)(status); 926 if (res != -1 && status) 927 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 928 return res; 929} 930INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, int id, void *infop, 931 int options) { 932 void *ctx; 933 COMMON_INTERCEPTOR_ENTER(ctx, waitid, idtype, id, infop, options); 934 int res = REAL(waitid)(idtype, id, infop, options); 935 if (res != -1 && infop) 936 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, infop, siginfo_t_sz); 937 return res; 938} 939INTERCEPTOR_WITH_SUFFIX(int, waitpid, int pid, int *status, int options) { 940 void *ctx; 941 COMMON_INTERCEPTOR_ENTER(ctx, waitpid, pid, status, options); 942 int res = REAL(waitpid)(pid, status, options); 943 if (res != -1 && status) 944 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 945 return res; 946} 947INTERCEPTOR(int, wait3, int *status, int options, void *rusage) { 948 void *ctx; 949 COMMON_INTERCEPTOR_ENTER(ctx, wait3, status, options, rusage); 950 int res = REAL(wait3)(status, options, rusage); 951 if (res != -1) { 952 if (status) 953 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 954 if (rusage) 955 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz); 956 } 957 return res; 958} 959INTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) { 960 void *ctx; 961 COMMON_INTERCEPTOR_ENTER(ctx, wait4, pid, status, options, rusage); 962 int res = REAL(wait4)(pid, status, options, rusage); 963 if (res != -1) { 964 if (status) 965 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 966 if (rusage) 967 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz); 968 } 969 return res; 970} 971#define INIT_WAIT \ 972 INTERCEPT_FUNCTION(wait); \ 973 INTERCEPT_FUNCTION(waitid); \ 974 INTERCEPT_FUNCTION(waitpid); \ 975 INTERCEPT_FUNCTION(wait3); \ 976 INTERCEPT_FUNCTION(wait4); 977#else 978#define INIT_WAIT 979#endif 980 981#if SANITIZER_INTERCEPT_INET 982INTERCEPTOR(char *, inet_ntop, int af, const void *src, char *dst, u32 size) { 983 void *ctx; 984 COMMON_INTERCEPTOR_ENTER(ctx, inet_ntop, af, src, dst, size); 985 uptr sz = __sanitizer_in_addr_sz(af); 986 if (sz) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sz); 987 // FIXME: figure out read size based on the address family. 988 char *res = REAL(inet_ntop)(af, src, dst, size); 989 if (res) 990 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 991 return res; 992} 993INTERCEPTOR(int, inet_pton, int af, const char *src, void *dst) { 994 void *ctx; 995 COMMON_INTERCEPTOR_ENTER(ctx, inet_pton, af, src, dst); 996 // FIXME: figure out read size based on the address family. 997 int res = REAL(inet_pton)(af, src, dst); 998 if (res == 1) { 999 uptr sz = __sanitizer_in_addr_sz(af); 1000 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz); 1001 } 1002 return res; 1003} 1004#define INIT_INET \ 1005 INTERCEPT_FUNCTION(inet_ntop); \ 1006 INTERCEPT_FUNCTION(inet_pton); 1007#else 1008#define INIT_INET 1009#endif 1010 1011#if SANITIZER_INTERCEPT_INET 1012INTERCEPTOR(int, inet_aton, const char *cp, void *dst) { 1013 void *ctx; 1014 COMMON_INTERCEPTOR_ENTER(ctx, inet_aton, cp, dst); 1015 if (cp) COMMON_INTERCEPTOR_READ_RANGE(ctx, cp, REAL(strlen)(cp) + 1); 1016 int res = REAL(inet_aton)(cp, dst); 1017 if (res != 0) { 1018 uptr sz = __sanitizer_in_addr_sz(af_inet); 1019 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz); 1020 } 1021 return res; 1022} 1023#define INIT_INET_ATON INTERCEPT_FUNCTION(inet_aton); 1024#else 1025#define INIT_INET_ATON 1026#endif 1027 1028#if SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM 1029INTERCEPTOR(int, pthread_getschedparam, uptr thread, int *policy, int *param) { 1030 void *ctx; 1031 COMMON_INTERCEPTOR_ENTER(ctx, pthread_getschedparam, thread, policy, param); 1032 int res = REAL(pthread_getschedparam)(thread, policy, param); 1033 if (res == 0) { 1034 if (policy) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, policy, sizeof(*policy)); 1035 if (param) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, sizeof(*param)); 1036 } 1037 return res; 1038} 1039#define INIT_PTHREAD_GETSCHEDPARAM INTERCEPT_FUNCTION(pthread_getschedparam); 1040#else 1041#define INIT_PTHREAD_GETSCHEDPARAM 1042#endif 1043 1044#if SANITIZER_INTERCEPT_GETADDRINFO 1045INTERCEPTOR(int, getaddrinfo, char *node, char *service, 1046 struct __sanitizer_addrinfo *hints, 1047 struct __sanitizer_addrinfo **out) { 1048 void *ctx; 1049 COMMON_INTERCEPTOR_ENTER(ctx, getaddrinfo, node, service, hints, out); 1050 if (node) COMMON_INTERCEPTOR_READ_RANGE(ctx, node, REAL(strlen)(node) + 1); 1051 if (service) 1052 COMMON_INTERCEPTOR_READ_RANGE(ctx, service, REAL(strlen)(service) + 1); 1053 if (hints) 1054 COMMON_INTERCEPTOR_READ_RANGE(ctx, hints, sizeof(__sanitizer_addrinfo)); 1055 int res = REAL(getaddrinfo)(node, service, hints, out); 1056 if (res == 0 && out) { 1057 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, out, sizeof(*out)); 1058 struct __sanitizer_addrinfo *p = *out; 1059 while (p) { 1060 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); 1061 if (p->ai_addr) 1062 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_addr, p->ai_addrlen); 1063 if (p->ai_canonname) 1064 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_canonname, 1065 REAL(strlen)(p->ai_canonname) + 1); 1066 p = p->ai_next; 1067 } 1068 } 1069 return res; 1070} 1071#define INIT_GETADDRINFO INTERCEPT_FUNCTION(getaddrinfo); 1072#else 1073#define INIT_GETADDRINFO 1074#endif 1075 1076#if SANITIZER_INTERCEPT_GETNAMEINFO 1077INTERCEPTOR(int, getnameinfo, void *sockaddr, unsigned salen, char *host, 1078 unsigned hostlen, char *serv, unsigned servlen, int flags) { 1079 void *ctx; 1080 COMMON_INTERCEPTOR_ENTER(ctx, getnameinfo, sockaddr, salen, host, hostlen, 1081 serv, servlen, flags); 1082 // FIXME: consider adding READ_RANGE(sockaddr, salen) 1083 // There is padding in in_addr that may make this too noisy 1084 int res = 1085 REAL(getnameinfo)(sockaddr, salen, host, hostlen, serv, servlen, flags); 1086 if (res == 0) { 1087 if (host && hostlen) 1088 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, host, REAL(strlen)(host) + 1); 1089 if (serv && servlen) 1090 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, serv, REAL(strlen)(serv) + 1); 1091 } 1092 return res; 1093} 1094#define INIT_GETNAMEINFO INTERCEPT_FUNCTION(getnameinfo); 1095#else 1096#define INIT_GETNAMEINFO 1097#endif 1098 1099#if SANITIZER_INTERCEPT_GETSOCKNAME 1100INTERCEPTOR(int, getsockname, int sock_fd, void *addr, int *addrlen) { 1101 void *ctx; 1102 COMMON_INTERCEPTOR_ENTER(ctx, getsockname, sock_fd, addr, addrlen); 1103 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 1104 int addrlen_in = *addrlen; 1105 int res = REAL(getsockname)(sock_fd, addr, addrlen); 1106 if (res == 0) { 1107 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addrlen_in, *addrlen)); 1108 } 1109 return res; 1110} 1111#define INIT_GETSOCKNAME INTERCEPT_FUNCTION(getsockname); 1112#else 1113#define INIT_GETSOCKNAME 1114#endif 1115 1116#if SANITIZER_INTERCEPT_GETHOSTBYNAME || SANITIZER_INTERCEPT_GETHOSTBYNAME_R 1117static void write_hostent(void *ctx, struct __sanitizer_hostent *h) { 1118 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h, sizeof(__sanitizer_hostent)); 1119 if (h->h_name) 1120 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h->h_name, REAL(strlen)(h->h_name) + 1); 1121 char **p = h->h_aliases; 1122 while (*p) { 1123 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1); 1124 ++p; 1125 } 1126 COMMON_INTERCEPTOR_WRITE_RANGE( 1127 ctx, h->h_aliases, (p - h->h_aliases + 1) * sizeof(*h->h_aliases)); 1128 p = h->h_addr_list; 1129 while (*p) { 1130 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, h->h_length); 1131 ++p; 1132 } 1133 COMMON_INTERCEPTOR_WRITE_RANGE( 1134 ctx, h->h_addr_list, (p - h->h_addr_list + 1) * sizeof(*h->h_addr_list)); 1135} 1136#endif 1137 1138#if SANITIZER_INTERCEPT_GETHOSTBYNAME 1139INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname, char *name) { 1140 void *ctx; 1141 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname, name); 1142 struct __sanitizer_hostent *res = REAL(gethostbyname)(name); 1143 if (res) write_hostent(ctx, res); 1144 return res; 1145} 1146 1147INTERCEPTOR(struct __sanitizer_hostent *, gethostbyaddr, void *addr, int len, 1148 int type) { 1149 void *ctx; 1150 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr, addr, len, type); 1151 COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len); 1152 struct __sanitizer_hostent *res = REAL(gethostbyaddr)(addr, len, type); 1153 if (res) write_hostent(ctx, res); 1154 return res; 1155} 1156 1157INTERCEPTOR(struct __sanitizer_hostent *, gethostent, int fake) { 1158 void *ctx; 1159 COMMON_INTERCEPTOR_ENTER(ctx, gethostent, fake); 1160 struct __sanitizer_hostent *res = REAL(gethostent)(fake); 1161 if (res) write_hostent(ctx, res); 1162 return res; 1163} 1164 1165INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname2, char *name, int af) { 1166 void *ctx; 1167 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2, name, af); 1168 struct __sanitizer_hostent *res = REAL(gethostbyname2)(name, af); 1169 if (res) write_hostent(ctx, res); 1170 return res; 1171} 1172#define INIT_GETHOSTBYNAME \ 1173 INTERCEPT_FUNCTION(gethostent); \ 1174 INTERCEPT_FUNCTION(gethostbyaddr); \ 1175 INTERCEPT_FUNCTION(gethostbyname); \ 1176 INTERCEPT_FUNCTION(gethostbyname2); 1177#else 1178#define INIT_GETHOSTBYNAME 1179#endif 1180 1181#if SANITIZER_INTERCEPT_GETHOSTBYNAME_R 1182INTERCEPTOR(int, gethostent_r, struct __sanitizer_hostent *ret, char *buf, 1183 SIZE_T buflen, __sanitizer_hostent **result, int *h_errnop) { 1184 void *ctx; 1185 COMMON_INTERCEPTOR_ENTER(ctx, gethostent_r, ret, buf, buflen, result, 1186 h_errnop); 1187 int res = REAL(gethostent_r)(ret, buf, buflen, result, h_errnop); 1188 if (res == 0) { 1189 if (result) { 1190 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1191 if (*result) write_hostent(ctx, *result); 1192 } 1193 if (h_errnop) 1194 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 1195 } 1196 return res; 1197} 1198 1199INTERCEPTOR(int, gethostbyaddr_r, void *addr, int len, int type, 1200 struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen, 1201 __sanitizer_hostent **result, int *h_errnop) { 1202 void *ctx; 1203 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr_r, addr, len, type, ret, buf, 1204 buflen, result, h_errnop); 1205 COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len); 1206 int res = REAL(gethostbyaddr_r)(addr, len, type, ret, buf, buflen, result, 1207 h_errnop); 1208 if (res == 0) { 1209 if (result) { 1210 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1211 if (*result) write_hostent(ctx, *result); 1212 } 1213 if (h_errnop) 1214 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 1215 } 1216 return res; 1217} 1218 1219INTERCEPTOR(int, gethostbyname_r, char *name, struct __sanitizer_hostent *ret, 1220 char *buf, SIZE_T buflen, __sanitizer_hostent **result, 1221 int *h_errnop) { 1222 void *ctx; 1223 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname_r, name, ret, buf, buflen, result, 1224 h_errnop); 1225 int res = REAL(gethostbyname_r)(name, ret, buf, buflen, result, h_errnop); 1226 if (res == 0) { 1227 if (result) { 1228 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1229 if (*result) write_hostent(ctx, *result); 1230 } 1231 if (h_errnop) 1232 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 1233 } 1234 return res; 1235} 1236 1237INTERCEPTOR(int, gethostbyname2_r, char *name, int af, 1238 struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen, 1239 __sanitizer_hostent **result, int *h_errnop) { 1240 void *ctx; 1241 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2_r, name, af, ret, buf, buflen, 1242 result, h_errnop); 1243 int res = 1244 REAL(gethostbyname2_r)(name, af, ret, buf, buflen, result, h_errnop); 1245 if (res == 0) { 1246 if (result) { 1247 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1248 if (*result) write_hostent(ctx, *result); 1249 } 1250 if (h_errnop) 1251 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 1252 } 1253 return res; 1254} 1255#define INIT_GETHOSTBYNAME_R \ 1256 INTERCEPT_FUNCTION(gethostent_r); \ 1257 INTERCEPT_FUNCTION(gethostbyaddr_r); \ 1258 INTERCEPT_FUNCTION(gethostbyname_r); \ 1259 INTERCEPT_FUNCTION(gethostbyname2_r); 1260#else 1261#define INIT_GETHOSTBYNAME_R 1262#endif 1263 1264#if SANITIZER_INTERCEPT_GETSOCKOPT 1265INTERCEPTOR(int, getsockopt, int sockfd, int level, int optname, void *optval, 1266 int *optlen) { 1267 void *ctx; 1268 COMMON_INTERCEPTOR_ENTER(ctx, getsockopt, sockfd, level, optname, optval, 1269 optlen); 1270 if (optlen) COMMON_INTERCEPTOR_READ_RANGE(ctx, optlen, sizeof(*optlen)); 1271 int res = REAL(getsockopt)(sockfd, level, optname, optval, optlen); 1272 if (res == 0) 1273 if (optval && optlen) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, optval, *optlen); 1274 return res; 1275} 1276#define INIT_GETSOCKOPT INTERCEPT_FUNCTION(getsockopt); 1277#else 1278#define INIT_GETSOCKOPT 1279#endif 1280 1281#if SANITIZER_INTERCEPT_ACCEPT 1282INTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) { 1283 void *ctx; 1284 COMMON_INTERCEPTOR_ENTER(ctx, accept, fd, addr, addrlen); 1285 unsigned addrlen0; 1286 if (addrlen) { 1287 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 1288 addrlen0 = *addrlen; 1289 } 1290 int fd2 = REAL(accept)(fd, addr, addrlen); 1291 if (fd2 >= 0) { 1292 if (fd >= 0) 1293 COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2); 1294 if (addr && addrlen) 1295 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0)); 1296 } 1297 return fd2; 1298} 1299#define INIT_ACCEPT INTERCEPT_FUNCTION(accept); 1300#else 1301#define INIT_ACCEPT 1302#endif 1303 1304#if SANITIZER_INTERCEPT_ACCEPT4 1305INTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) { 1306 void *ctx; 1307 COMMON_INTERCEPTOR_ENTER(ctx, accept4, fd, addr, addrlen, f); 1308 unsigned addrlen0; 1309 if (addrlen) { 1310 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 1311 addrlen0 = *addrlen; 1312 } 1313 int fd2 = REAL(accept4)(fd, addr, addrlen, f); 1314 if (fd2 >= 0) { 1315 if (fd >= 0) 1316 COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2); 1317 if (addr && addrlen) 1318 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0)); 1319 } 1320 return fd2; 1321} 1322#define INIT_ACCEPT4 INTERCEPT_FUNCTION(accept4); 1323#else 1324#define INIT_ACCEPT4 1325#endif 1326 1327#if SANITIZER_INTERCEPT_MODF 1328INTERCEPTOR(double, modf, double x, double *iptr) { 1329 void *ctx; 1330 COMMON_INTERCEPTOR_ENTER(ctx, modf, x, iptr); 1331 double res = REAL(modf)(x, iptr); 1332 if (iptr) { 1333 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr)); 1334 } 1335 return res; 1336} 1337INTERCEPTOR(float, modff, float x, float *iptr) { 1338 void *ctx; 1339 COMMON_INTERCEPTOR_ENTER(ctx, modff, x, iptr); 1340 float res = REAL(modff)(x, iptr); 1341 if (iptr) { 1342 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr)); 1343 } 1344 return res; 1345} 1346INTERCEPTOR(long double, modfl, long double x, long double *iptr) { 1347 void *ctx; 1348 COMMON_INTERCEPTOR_ENTER(ctx, modfl, x, iptr); 1349 long double res = REAL(modfl)(x, iptr); 1350 if (iptr) { 1351 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr)); 1352 } 1353 return res; 1354} 1355#define INIT_MODF \ 1356 INTERCEPT_FUNCTION(modf); \ 1357 INTERCEPT_FUNCTION(modff); \ 1358 INTERCEPT_FUNCTION(modfl); 1359#else 1360#define INIT_MODF 1361#endif 1362 1363#if SANITIZER_INTERCEPT_RECVMSG 1364static void write_msghdr(void *ctx, struct __sanitizer_msghdr *msg, 1365 SSIZE_T maxlen) { 1366 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg, sizeof(*msg)); 1367 if (msg->msg_name) 1368 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_name, 1369 REAL(strlen)((char *)msg->msg_name) + 1); 1370 if (msg->msg_iov) 1371 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_iov, 1372 sizeof(*msg->msg_iov) * msg->msg_iovlen); 1373 write_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen); 1374 if (msg->msg_control) 1375 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_control, msg->msg_controllen); 1376} 1377 1378INTERCEPTOR(SSIZE_T, recvmsg, int fd, struct __sanitizer_msghdr *msg, 1379 int flags) { 1380 void *ctx; 1381 COMMON_INTERCEPTOR_ENTER(ctx, recvmsg, fd, msg, flags); 1382 SSIZE_T res = REAL(recvmsg)(fd, msg, flags); 1383 if (res >= 0) { 1384 if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 1385 if (msg) write_msghdr(ctx, msg, res); 1386 } 1387 return res; 1388} 1389#define INIT_RECVMSG INTERCEPT_FUNCTION(recvmsg); 1390#else 1391#define INIT_RECVMSG 1392#endif 1393 1394#if SANITIZER_INTERCEPT_GETPEERNAME 1395INTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) { 1396 void *ctx; 1397 COMMON_INTERCEPTOR_ENTER(ctx, getpeername, sockfd, addr, addrlen); 1398 unsigned addr_sz; 1399 if (addrlen) addr_sz = *addrlen; 1400 int res = REAL(getpeername)(sockfd, addr, addrlen); 1401 if (!res && addr && addrlen) 1402 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen)); 1403 return res; 1404} 1405#define INIT_GETPEERNAME INTERCEPT_FUNCTION(getpeername); 1406#else 1407#define INIT_GETPEERNAME 1408#endif 1409 1410#if SANITIZER_INTERCEPT_SYSINFO 1411INTERCEPTOR(int, sysinfo, void *info) { 1412 void *ctx; 1413 COMMON_INTERCEPTOR_ENTER(ctx, sysinfo, info); 1414 int res = REAL(sysinfo)(info); 1415 if (!res && info) 1416 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, struct_sysinfo_sz); 1417 return res; 1418} 1419#define INIT_SYSINFO INTERCEPT_FUNCTION(sysinfo); 1420#else 1421#define INIT_SYSINFO 1422#endif 1423 1424#if SANITIZER_INTERCEPT_READDIR 1425INTERCEPTOR(__sanitizer_dirent *, readdir, void *dirp) { 1426 void *ctx; 1427 COMMON_INTERCEPTOR_ENTER(ctx, readdir, dirp); 1428 __sanitizer_dirent *res = REAL(readdir)(dirp); 1429 if (res) 1430 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen); 1431 return res; 1432} 1433 1434INTERCEPTOR(int, readdir_r, void *dirp, __sanitizer_dirent *entry, 1435 __sanitizer_dirent **result) { 1436 void *ctx; 1437 COMMON_INTERCEPTOR_ENTER(ctx, readdir_r, dirp, entry, result); 1438 int res = REAL(readdir_r)(dirp, entry, result); 1439 if (!res) { 1440 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1441 if (*result) 1442 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen); 1443 } 1444 return res; 1445} 1446 1447#define INIT_READDIR \ 1448 INTERCEPT_FUNCTION(readdir); \ 1449 INTERCEPT_FUNCTION(readdir_r); 1450#else 1451#define INIT_READDIR 1452#endif 1453 1454#if SANITIZER_INTERCEPT_READDIR64 1455INTERCEPTOR(__sanitizer_dirent64 *, readdir64, void *dirp) { 1456 void *ctx; 1457 COMMON_INTERCEPTOR_ENTER(ctx, readdir64, dirp); 1458 __sanitizer_dirent64 *res = REAL(readdir64)(dirp); 1459 if (res) 1460 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen); 1461 return res; 1462} 1463 1464INTERCEPTOR(int, readdir64_r, void *dirp, __sanitizer_dirent64 *entry, 1465 __sanitizer_dirent64 **result) { 1466 void *ctx; 1467 COMMON_INTERCEPTOR_ENTER(ctx, readdir64_r, dirp, entry, result); 1468 int res = REAL(readdir64_r)(dirp, entry, result); 1469 if (!res) { 1470 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1471 if (*result) 1472 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen); 1473 } 1474 return res; 1475} 1476#define INIT_READDIR64 \ 1477 INTERCEPT_FUNCTION(readdir64); \ 1478 INTERCEPT_FUNCTION(readdir64_r); 1479#else 1480#define INIT_READDIR64 1481#endif 1482 1483#if SANITIZER_INTERCEPT_PTRACE 1484INTERCEPTOR(uptr, ptrace, int request, int pid, void *addr, void *data) { 1485 void *ctx; 1486 COMMON_INTERCEPTOR_ENTER(ctx, ptrace, request, pid, addr, data); 1487 1488 if (data) { 1489 if (request == ptrace_setregs) 1490 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_regs_struct_sz); 1491 else if (request == ptrace_setfpregs) 1492 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpregs_struct_sz); 1493 else if (request == ptrace_setfpxregs) 1494 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpxregs_struct_sz); 1495 else if (request == ptrace_setsiginfo) 1496 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, siginfo_t_sz); 1497 else if (request == ptrace_setregset) { 1498 __sanitizer_iovec *iov = (__sanitizer_iovec *)data; 1499 COMMON_INTERCEPTOR_READ_RANGE(ctx, iov->iov_base, iov->iov_len); 1500 } 1501 } 1502 1503 uptr res = REAL(ptrace)(request, pid, addr, data); 1504 1505 if (!res && data) { 1506 // Note that PEEK* requests assing different meaning to the return value. 1507 // This function does not handle them (nor does it need to). 1508 if (request == ptrace_getregs) 1509 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_regs_struct_sz); 1510 else if (request == ptrace_getfpregs) 1511 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpregs_struct_sz); 1512 else if (request == ptrace_getfpxregs) 1513 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpxregs_struct_sz); 1514 else if (request == ptrace_getsiginfo) 1515 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, siginfo_t_sz); 1516 else if (request == ptrace_getregset) { 1517 __sanitizer_iovec *iov = (__sanitizer_iovec *)data; 1518 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iov->iov_base, iov->iov_len); 1519 } 1520 } 1521 return res; 1522} 1523 1524#define INIT_PTRACE \ 1525 INTERCEPT_FUNCTION(ptrace); 1526#else 1527#define INIT_PTRACE 1528#endif 1529 1530#if SANITIZER_INTERCEPT_SETLOCALE 1531INTERCEPTOR(char *, setlocale, int category, char *locale) { 1532 void *ctx; 1533 COMMON_INTERCEPTOR_ENTER(ctx, setlocale, category, locale); 1534 if (locale) 1535 COMMON_INTERCEPTOR_READ_RANGE(ctx, locale, REAL(strlen)(locale) + 1); 1536 char *res = REAL(setlocale)(category, locale); 1537 if (res) 1538 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1539 return res; 1540} 1541 1542#define INIT_SETLOCALE \ 1543 INTERCEPT_FUNCTION(setlocale); 1544#else 1545#define INIT_SETLOCALE 1546#endif 1547 1548#if SANITIZER_INTERCEPT_GETCWD 1549INTERCEPTOR(char *, getcwd, char *buf, SIZE_T size) { 1550 void *ctx; 1551 COMMON_INTERCEPTOR_ENTER(ctx, getcwd, buf, size); 1552 char *res = REAL(getcwd)(buf, size); 1553 if (res) 1554 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1555 return res; 1556} 1557#define INIT_GETCWD \ 1558 INTERCEPT_FUNCTION(getcwd); 1559#else 1560#define INIT_GETCWD 1561#endif 1562 1563#if SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME 1564INTERCEPTOR(char *, get_current_dir_name, int fake) { 1565 void *ctx; 1566 COMMON_INTERCEPTOR_ENTER(ctx, get_current_dir_name, fake); 1567 char *res = REAL(get_current_dir_name)(fake); 1568 if (res) 1569 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1570 return res; 1571} 1572 1573#define INIT_GET_CURRENT_DIR_NAME \ 1574 INTERCEPT_FUNCTION(get_current_dir_name); 1575#else 1576#define INIT_GET_CURRENT_DIR_NAME 1577#endif 1578 1579#if SANITIZER_INTERCEPT_STRTOIMAX 1580INTERCEPTOR(INTMAX_T, strtoimax, const char *nptr, char **endptr, int base) { 1581 void *ctx; 1582 COMMON_INTERCEPTOR_ENTER(ctx, strtoimax, nptr, endptr, base); 1583 INTMAX_T res = REAL(strtoimax)(nptr, endptr, base); 1584 if (endptr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr)); 1585 return res; 1586} 1587 1588INTERCEPTOR(INTMAX_T, strtoumax, const char *nptr, char **endptr, int base) { 1589 void *ctx; 1590 COMMON_INTERCEPTOR_ENTER(ctx, strtoumax, nptr, endptr, base); 1591 INTMAX_T res = REAL(strtoumax)(nptr, endptr, base); 1592 if (endptr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr)); 1593 return res; 1594} 1595 1596#define INIT_STRTOIMAX \ 1597 INTERCEPT_FUNCTION(strtoimax); \ 1598 INTERCEPT_FUNCTION(strtoumax); 1599#else 1600#define INIT_STRTOIMAX 1601#endif 1602 1603#if SANITIZER_INTERCEPT_MBSTOWCS 1604INTERCEPTOR(SIZE_T, mbstowcs, wchar_t *dest, const char *src, SIZE_T len) { 1605 void *ctx; 1606 COMMON_INTERCEPTOR_ENTER(ctx, mbstowcs, dest, src, len); 1607 SIZE_T res = REAL(mbstowcs)(dest, src, len); 1608 if (res != (SIZE_T) - 1 && dest) { 1609 SIZE_T write_cnt = res + (res < len); 1610 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t)); 1611 } 1612 return res; 1613} 1614 1615INTERCEPTOR(SIZE_T, mbsrtowcs, wchar_t *dest, const char **src, SIZE_T len, 1616 void *ps) { 1617 void *ctx; 1618 COMMON_INTERCEPTOR_ENTER(ctx, mbsrtowcs, dest, src, len, ps); 1619 if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 1620 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 1621 SIZE_T res = REAL(mbsrtowcs)(dest, src, len, ps); 1622 if (res != (SIZE_T)(-1) && dest && src) { 1623 // This function, and several others, may or may not write the terminating 1624 // \0 character. They write it iff they clear *src. 1625 SIZE_T write_cnt = res + !*src; 1626 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t)); 1627 } 1628 return res; 1629} 1630 1631#define INIT_MBSTOWCS \ 1632 INTERCEPT_FUNCTION(mbstowcs); \ 1633 INTERCEPT_FUNCTION(mbsrtowcs); 1634#else 1635#define INIT_MBSTOWCS 1636#endif 1637 1638#if SANITIZER_INTERCEPT_MBSNRTOWCS 1639INTERCEPTOR(SIZE_T, mbsnrtowcs, wchar_t *dest, const char **src, SIZE_T nms, 1640 SIZE_T len, void *ps) { 1641 void *ctx; 1642 COMMON_INTERCEPTOR_ENTER(ctx, mbsnrtowcs, dest, src, nms, len, ps); 1643 if (src) { 1644 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 1645 if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms); 1646 } 1647 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 1648 SIZE_T res = REAL(mbsnrtowcs)(dest, src, nms, len, ps); 1649 if (res != (SIZE_T)(-1) && dest && src) { 1650 SIZE_T write_cnt = res + !*src; 1651 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t)); 1652 } 1653 return res; 1654} 1655 1656#define INIT_MBSNRTOWCS INTERCEPT_FUNCTION(mbsnrtowcs); 1657#else 1658#define INIT_MBSNRTOWCS 1659#endif 1660 1661#if SANITIZER_INTERCEPT_WCSTOMBS 1662INTERCEPTOR(SIZE_T, wcstombs, char *dest, const wchar_t *src, SIZE_T len) { 1663 void *ctx; 1664 COMMON_INTERCEPTOR_ENTER(ctx, wcstombs, dest, src, len); 1665 SIZE_T res = REAL(wcstombs)(dest, src, len); 1666 if (res != (SIZE_T) - 1 && dest) { 1667 SIZE_T write_cnt = res + (res < len); 1668 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt); 1669 } 1670 return res; 1671} 1672 1673INTERCEPTOR(SIZE_T, wcsrtombs, char *dest, const wchar_t **src, SIZE_T len, 1674 void *ps) { 1675 void *ctx; 1676 COMMON_INTERCEPTOR_ENTER(ctx, wcsrtombs, dest, src, len, ps); 1677 if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 1678 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 1679 SIZE_T res = REAL(wcsrtombs)(dest, src, len, ps); 1680 if (res != (SIZE_T) - 1 && dest && src) { 1681 SIZE_T write_cnt = res + !*src; 1682 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt); 1683 } 1684 return res; 1685} 1686 1687#define INIT_WCSTOMBS \ 1688 INTERCEPT_FUNCTION(wcstombs); \ 1689 INTERCEPT_FUNCTION(wcsrtombs); 1690#else 1691#define INIT_WCSTOMBS 1692#endif 1693 1694#if SANITIZER_INTERCEPT_WCSNRTOMBS 1695INTERCEPTOR(SIZE_T, wcsnrtombs, char *dest, const wchar_t **src, SIZE_T nms, 1696 SIZE_T len, void *ps) { 1697 void *ctx; 1698 COMMON_INTERCEPTOR_ENTER(ctx, wcsnrtombs, dest, src, nms, len, ps); 1699 if (src) { 1700 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 1701 if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms); 1702 } 1703 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 1704 SIZE_T res = REAL(wcsnrtombs)(dest, src, nms, len, ps); 1705 if (res != (SIZE_T) - 1 && dest && src) { 1706 SIZE_T write_cnt = res + !*src; 1707 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt); 1708 } 1709 return res; 1710} 1711 1712#define INIT_WCSNRTOMBS INTERCEPT_FUNCTION(wcsnrtombs); 1713#else 1714#define INIT_WCSNRTOMBS 1715#endif 1716 1717 1718#if SANITIZER_INTERCEPT_TCGETATTR 1719INTERCEPTOR(int, tcgetattr, int fd, void *termios_p) { 1720 void *ctx; 1721 COMMON_INTERCEPTOR_ENTER(ctx, tcgetattr, fd, termios_p); 1722 int res = REAL(tcgetattr)(fd, termios_p); 1723 if (!res && termios_p) 1724 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, termios_p, struct_termios_sz); 1725 return res; 1726} 1727 1728#define INIT_TCGETATTR INTERCEPT_FUNCTION(tcgetattr); 1729#else 1730#define INIT_TCGETATTR 1731#endif 1732 1733 1734#if SANITIZER_INTERCEPT_REALPATH 1735INTERCEPTOR(char *, realpath, const char *path, char *resolved_path) { 1736 void *ctx; 1737 COMMON_INTERCEPTOR_ENTER(ctx, realpath, path, resolved_path); 1738 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 1739 1740 // Workaround a bug in glibc where dlsym(RTLD_NEXT, ...) returns the oldest 1741 // version of a versioned symbol. For realpath(), this gives us something 1742 // (called __old_realpath) that does not handle NULL in the second argument. 1743 // Handle it as part of the interceptor. 1744 char *allocated_path = 0; 1745 if (!resolved_path) 1746 allocated_path = resolved_path = (char *)WRAP(malloc)(path_max + 1); 1747 1748 char *res = REAL(realpath)(path, resolved_path); 1749 if (allocated_path && !res) 1750 WRAP(free)(allocated_path); 1751 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1752 return res; 1753} 1754#define INIT_REALPATH INTERCEPT_FUNCTION(realpath); 1755#else 1756#define INIT_REALPATH 1757#endif 1758 1759#if SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME 1760INTERCEPTOR(char *, canonicalize_file_name, const char *path) { 1761 void *ctx; 1762 COMMON_INTERCEPTOR_ENTER(ctx, canonicalize_file_name, path); 1763 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 1764 char *res = REAL(canonicalize_file_name)(path); 1765 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1766 return res; 1767} 1768#define INIT_CANONICALIZE_FILE_NAME INTERCEPT_FUNCTION(canonicalize_file_name); 1769#else 1770#define INIT_CANONICALIZE_FILE_NAME 1771#endif 1772 1773#if SANITIZER_INTERCEPT_CONFSTR 1774INTERCEPTOR(SIZE_T, confstr, int name, char *buf, SIZE_T len) { 1775 void *ctx; 1776 COMMON_INTERCEPTOR_ENTER(ctx, confstr, name, buf, len); 1777 SIZE_T res = REAL(confstr)(name, buf, len); 1778 if (buf && res) 1779 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res < len ? res : len); 1780 return res; 1781} 1782#define INIT_CONFSTR INTERCEPT_FUNCTION(confstr); 1783#else 1784#define INIT_CONFSTR 1785#endif 1786 1787#if SANITIZER_INTERCEPT_SCHED_GETAFFINITY 1788INTERCEPTOR(int, sched_getaffinity, int pid, SIZE_T cpusetsize, void *mask) { 1789 void *ctx; 1790 COMMON_INTERCEPTOR_ENTER(ctx, sched_getaffinity, pid, cpusetsize, mask); 1791 int res = REAL(sched_getaffinity)(pid, cpusetsize, mask); 1792 if (mask && !res) 1793 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mask, cpusetsize); 1794 return res; 1795} 1796#define INIT_SCHED_GETAFFINITY INTERCEPT_FUNCTION(sched_getaffinity); 1797#else 1798#define INIT_SCHED_GETAFFINITY 1799#endif 1800 1801#if SANITIZER_INTERCEPT_STRERROR 1802INTERCEPTOR(char *, strerror, int errnum) { 1803 void *ctx; 1804 COMMON_INTERCEPTOR_ENTER(ctx, strerror, errnum); 1805 char *res = REAL(strerror)(errnum); 1806 if (res) 1807 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1808 return res; 1809} 1810#define INIT_STRERROR INTERCEPT_FUNCTION(strerror); 1811#else 1812#define INIT_STRERROR 1813#endif 1814 1815#if SANITIZER_INTERCEPT_STRERROR_R 1816INTERCEPTOR(char *, strerror_r, int errnum, char *buf, SIZE_T buflen) { 1817 void *ctx; 1818 COMMON_INTERCEPTOR_ENTER(ctx, strerror_r, errnum, buf, buflen); 1819 char *res = REAL(strerror_r)(errnum, buf, buflen); 1820 // There are 2 versions of strerror_r: 1821 // * POSIX version returns 0 on success, negative error code on failure, 1822 // writes message to buf. 1823 // * GNU version returns message pointer, which points to either buf or some 1824 // static storage. 1825 SIZE_T posix_res = (SIZE_T)res; 1826 if (posix_res < 1024 || posix_res > (SIZE_T) - 1024) { 1827 // POSIX version. Spec is not clear on whether buf is NULL-terminated. 1828 // At least on OSX, buf contents are valid even when the call fails. 1829 SIZE_T sz = internal_strnlen(buf, buflen); 1830 if (sz < buflen) ++sz; 1831 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz); 1832 } else { 1833 // GNU version. 1834 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1835 } 1836 return res; 1837} 1838#define INIT_STRERROR_R INTERCEPT_FUNCTION(strerror_r); 1839#else 1840#define INIT_STRERROR_R 1841#endif 1842 1843#if SANITIZER_INTERCEPT_SCANDIR 1844typedef int (*scandir_filter_f)(const struct __sanitizer_dirent *); 1845typedef int (*scandir_compar_f)(const struct __sanitizer_dirent **, 1846 const struct __sanitizer_dirent **); 1847 1848static THREADLOCAL void *scandir_ctx; 1849static THREADLOCAL scandir_filter_f scandir_filter; 1850static THREADLOCAL scandir_compar_f scandir_compar; 1851 1852static int wrapped_scandir_filter(const struct __sanitizer_dirent *dir) { 1853 COMMON_INTERCEPTOR_UNPOISON_PARAM(scandir_ctx, 1); 1854 COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, dir, dir->d_reclen); 1855 return scandir_filter(dir); 1856} 1857 1858static int wrapped_scandir_compar(const struct __sanitizer_dirent **a, 1859 const struct __sanitizer_dirent **b) { 1860 COMMON_INTERCEPTOR_UNPOISON_PARAM(scandir_ctx, 2); 1861 COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, a, sizeof(*a)); 1862 COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, *a, (*a)->d_reclen); 1863 COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, b, sizeof(*b)); 1864 COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, *b, (*b)->d_reclen); 1865 return scandir_compar(a, b); 1866} 1867 1868INTERCEPTOR(int, scandir, char *dirp, __sanitizer_dirent ***namelist, 1869 scandir_filter_f filter, scandir_compar_f compar) { 1870 void *ctx; 1871 COMMON_INTERCEPTOR_ENTER(ctx, scandir, dirp, namelist, filter, compar); 1872 if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1); 1873 CHECK_EQ(0, scandir_ctx); 1874 scandir_ctx = ctx; 1875 scandir_filter = filter; 1876 scandir_compar = compar; 1877 int res = REAL(scandir)(dirp, namelist, filter ? wrapped_scandir_filter : 0, 1878 compar ? wrapped_scandir_compar : 0); 1879 scandir_ctx = 0; 1880 scandir_filter = 0; 1881 scandir_compar = 0; 1882 if (namelist && res > 0) { 1883 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist)); 1884 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res); 1885 for (int i = 0; i < res; ++i) 1886 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i], 1887 (*namelist)[i]->d_reclen); 1888 } 1889 return res; 1890} 1891#define INIT_SCANDIR INTERCEPT_FUNCTION(scandir); 1892#else 1893#define INIT_SCANDIR 1894#endif 1895 1896#if SANITIZER_INTERCEPT_SCANDIR64 1897typedef int (*scandir64_filter_f)(const struct __sanitizer_dirent64 *); 1898typedef int (*scandir64_compar_f)(const struct __sanitizer_dirent64 **, 1899 const struct __sanitizer_dirent64 **); 1900 1901static THREADLOCAL void *scandir64_ctx; 1902static THREADLOCAL scandir64_filter_f scandir64_filter; 1903static THREADLOCAL scandir64_compar_f scandir64_compar; 1904 1905static int wrapped_scandir64_filter(const struct __sanitizer_dirent64 *dir) { 1906 COMMON_INTERCEPTOR_UNPOISON_PARAM(scandir64_ctx, 1); 1907 COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, dir, dir->d_reclen); 1908 return scandir64_filter(dir); 1909} 1910 1911static int wrapped_scandir64_compar(const struct __sanitizer_dirent64 **a, 1912 const struct __sanitizer_dirent64 **b) { 1913 COMMON_INTERCEPTOR_UNPOISON_PARAM(scandir64_ctx, 2); 1914 COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, a, sizeof(*a)); 1915 COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, *a, (*a)->d_reclen); 1916 COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, b, sizeof(*b)); 1917 COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, *b, (*b)->d_reclen); 1918 return scandir64_compar(a, b); 1919} 1920 1921INTERCEPTOR(int, scandir64, char *dirp, __sanitizer_dirent64 ***namelist, 1922 scandir64_filter_f filter, scandir64_compar_f compar) { 1923 void *ctx; 1924 COMMON_INTERCEPTOR_ENTER(ctx, scandir64, dirp, namelist, filter, compar); 1925 if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1); 1926 CHECK_EQ(0, scandir64_ctx); 1927 scandir64_ctx = ctx; 1928 scandir64_filter = filter; 1929 scandir64_compar = compar; 1930 int res = 1931 REAL(scandir64)(dirp, namelist, filter ? wrapped_scandir64_filter : 0, 1932 compar ? wrapped_scandir64_compar : 0); 1933 scandir64_ctx = 0; 1934 scandir64_filter = 0; 1935 scandir64_compar = 0; 1936 if (namelist && res > 0) { 1937 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist)); 1938 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res); 1939 for (int i = 0; i < res; ++i) 1940 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i], 1941 (*namelist)[i]->d_reclen); 1942 } 1943 return res; 1944} 1945#define INIT_SCANDIR64 INTERCEPT_FUNCTION(scandir64); 1946#else 1947#define INIT_SCANDIR64 1948#endif 1949 1950#if SANITIZER_INTERCEPT_GETGROUPS 1951INTERCEPTOR(int, getgroups, int size, u32 *lst) { 1952 void *ctx; 1953 COMMON_INTERCEPTOR_ENTER(ctx, getgroups, size, lst); 1954 int res = REAL(getgroups)(size, lst); 1955 if (res && lst) 1956 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lst, res * sizeof(*lst)); 1957 return res; 1958} 1959#define INIT_GETGROUPS INTERCEPT_FUNCTION(getgroups); 1960#else 1961#define INIT_GETGROUPS 1962#endif 1963 1964#if SANITIZER_INTERCEPT_POLL 1965static void read_pollfd(void *ctx, __sanitizer_pollfd *fds, 1966 __sanitizer_nfds_t nfds) { 1967 for (unsigned i = 0; i < nfds; ++i) { 1968 COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].fd, sizeof(fds[i].fd)); 1969 COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].events, sizeof(fds[i].events)); 1970 } 1971} 1972 1973static void write_pollfd(void *ctx, __sanitizer_pollfd *fds, 1974 __sanitizer_nfds_t nfds) { 1975 for (unsigned i = 0; i < nfds; ++i) 1976 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &fds[i].revents, 1977 sizeof(fds[i].revents)); 1978} 1979 1980INTERCEPTOR(int, poll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds, 1981 int timeout) { 1982 void *ctx; 1983 COMMON_INTERCEPTOR_ENTER(ctx, poll, fds, nfds, timeout); 1984 if (fds && nfds) read_pollfd(ctx, fds, nfds); 1985 int res = COMMON_INTERCEPTOR_BLOCK_REAL(poll)(fds, nfds, timeout); 1986 if (fds && nfds) write_pollfd(ctx, fds, nfds); 1987 return res; 1988} 1989#define INIT_POLL INTERCEPT_FUNCTION(poll); 1990#else 1991#define INIT_POLL 1992#endif 1993 1994#if SANITIZER_INTERCEPT_PPOLL 1995INTERCEPTOR(int, ppoll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds, 1996 void *timeout_ts, __sanitizer_sigset_t *sigmask) { 1997 void *ctx; 1998 COMMON_INTERCEPTOR_ENTER(ctx, ppoll, fds, nfds, timeout_ts, sigmask); 1999 if (fds && nfds) read_pollfd(ctx, fds, nfds); 2000 if (timeout_ts) 2001 COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout_ts, struct_timespec_sz); 2002 // FIXME: read sigmask when all of sigemptyset, etc are intercepted. 2003 int res = 2004 COMMON_INTERCEPTOR_BLOCK_REAL(ppoll)(fds, nfds, timeout_ts, sigmask); 2005 if (fds && nfds) write_pollfd(ctx, fds, nfds); 2006 return res; 2007} 2008#define INIT_PPOLL INTERCEPT_FUNCTION(ppoll); 2009#else 2010#define INIT_PPOLL 2011#endif 2012 2013#if SANITIZER_INTERCEPT_WORDEXP 2014INTERCEPTOR(int, wordexp, char *s, __sanitizer_wordexp_t *p, int flags) { 2015 void *ctx; 2016 COMMON_INTERCEPTOR_ENTER(ctx, wordexp, s, p, flags); 2017 if (s) COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1); 2018 int res = REAL(wordexp)(s, p, flags); 2019 if (!res && p) { 2020 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); 2021 if (p->we_wordc) 2022 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->we_wordv, 2023 sizeof(*p->we_wordv) * p->we_wordc); 2024 for (uptr i = 0; i < p->we_wordc; ++i) { 2025 char *w = p->we_wordv[i]; 2026 if (w) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, w, REAL(strlen)(w) + 1); 2027 } 2028 } 2029 return res; 2030} 2031#define INIT_WORDEXP INTERCEPT_FUNCTION(wordexp); 2032#else 2033#define INIT_WORDEXP 2034#endif 2035 2036#if SANITIZER_INTERCEPT_SIGWAIT 2037INTERCEPTOR(int, sigwait, __sanitizer_sigset_t *set, int *sig) { 2038 void *ctx; 2039 COMMON_INTERCEPTOR_ENTER(ctx, sigwait, set, sig); 2040 // FIXME: read sigset_t when all of sigemptyset, etc are intercepted 2041 int res = REAL(sigwait)(set, sig); 2042 if (!res && sig) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sig, sizeof(*sig)); 2043 return res; 2044} 2045#define INIT_SIGWAIT INTERCEPT_FUNCTION(sigwait); 2046#else 2047#define INIT_SIGWAIT 2048#endif 2049 2050#if SANITIZER_INTERCEPT_SIGWAITINFO 2051INTERCEPTOR(int, sigwaitinfo, __sanitizer_sigset_t *set, void *info) { 2052 void *ctx; 2053 COMMON_INTERCEPTOR_ENTER(ctx, sigwaitinfo, set, info); 2054 // FIXME: read sigset_t when all of sigemptyset, etc are intercepted 2055 int res = REAL(sigwaitinfo)(set, info); 2056 if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz); 2057 return res; 2058} 2059#define INIT_SIGWAITINFO INTERCEPT_FUNCTION(sigwaitinfo); 2060#else 2061#define INIT_SIGWAITINFO 2062#endif 2063 2064#if SANITIZER_INTERCEPT_SIGTIMEDWAIT 2065INTERCEPTOR(int, sigtimedwait, __sanitizer_sigset_t *set, void *info, 2066 void *timeout) { 2067 void *ctx; 2068 COMMON_INTERCEPTOR_ENTER(ctx, sigtimedwait, set, info, timeout); 2069 if (timeout) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout, struct_timespec_sz); 2070 // FIXME: read sigset_t when all of sigemptyset, etc are intercepted 2071 int res = REAL(sigtimedwait)(set, info, timeout); 2072 if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz); 2073 return res; 2074} 2075#define INIT_SIGTIMEDWAIT INTERCEPT_FUNCTION(sigtimedwait); 2076#else 2077#define INIT_SIGTIMEDWAIT 2078#endif 2079 2080#if SANITIZER_INTERCEPT_SIGSETOPS 2081INTERCEPTOR(int, sigemptyset, __sanitizer_sigset_t *set) { 2082 void *ctx; 2083 COMMON_INTERCEPTOR_ENTER(ctx, sigemptyset, set); 2084 int res = REAL(sigemptyset)(set); 2085 if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set)); 2086 return res; 2087} 2088 2089INTERCEPTOR(int, sigfillset, __sanitizer_sigset_t *set) { 2090 void *ctx; 2091 COMMON_INTERCEPTOR_ENTER(ctx, sigfillset, set); 2092 int res = REAL(sigfillset)(set); 2093 if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set)); 2094 return res; 2095} 2096#define INIT_SIGSETOPS \ 2097 INTERCEPT_FUNCTION(sigemptyset); \ 2098 INTERCEPT_FUNCTION(sigfillset); 2099#else 2100#define INIT_SIGSETOPS 2101#endif 2102 2103#if SANITIZER_INTERCEPT_SIGPENDING 2104INTERCEPTOR(int, sigpending, __sanitizer_sigset_t *set) { 2105 void *ctx; 2106 COMMON_INTERCEPTOR_ENTER(ctx, sigpending, set); 2107 int res = REAL(sigpending)(set); 2108 if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set)); 2109 return res; 2110} 2111#define INIT_SIGPENDING INTERCEPT_FUNCTION(sigpending); 2112#else 2113#define INIT_SIGPENDING 2114#endif 2115 2116#if SANITIZER_INTERCEPT_SIGPROCMASK 2117INTERCEPTOR(int, sigprocmask, int how, __sanitizer_sigset_t *set, 2118 __sanitizer_sigset_t *oldset) { 2119 void *ctx; 2120 COMMON_INTERCEPTOR_ENTER(ctx, sigprocmask, how, set, oldset); 2121 // FIXME: read sigset_t when all of sigemptyset, etc are intercepted 2122 int res = REAL(sigprocmask)(how, set, oldset); 2123 if (!res && oldset) 2124 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset)); 2125 return res; 2126} 2127#define INIT_SIGPROCMASK INTERCEPT_FUNCTION(sigprocmask); 2128#else 2129#define INIT_SIGPROCMASK 2130#endif 2131 2132#if SANITIZER_INTERCEPT_BACKTRACE 2133INTERCEPTOR(int, backtrace, void **buffer, int size) { 2134 void *ctx; 2135 COMMON_INTERCEPTOR_ENTER(ctx, backtrace, buffer, size); 2136 int res = REAL(backtrace)(buffer, size); 2137 if (res && buffer) 2138 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buffer, res * sizeof(*buffer)); 2139 return res; 2140} 2141 2142INTERCEPTOR(char **, backtrace_symbols, void **buffer, int size) { 2143 void *ctx; 2144 COMMON_INTERCEPTOR_ENTER(ctx, backtrace_symbols, buffer, size); 2145 if (buffer && size) 2146 COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, size * sizeof(*buffer)); 2147 char ** res = REAL(backtrace_symbols)(buffer, size); 2148 if (res && size) { 2149 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, size * sizeof(*res)); 2150 for (int i = 0; i < size; ++i) 2151 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res[i], REAL(strlen(res[i])) + 1); 2152 } 2153 return res; 2154} 2155#define INIT_BACKTRACE \ 2156 INTERCEPT_FUNCTION(backtrace); \ 2157 INTERCEPT_FUNCTION(backtrace_symbols); 2158#else 2159#define INIT_BACKTRACE 2160#endif 2161 2162#define SANITIZER_COMMON_INTERCEPTORS_INIT \ 2163 INIT_STRCMP; \ 2164 INIT_STRNCMP; \ 2165 INIT_STRCASECMP; \ 2166 INIT_STRNCASECMP; \ 2167 INIT_READ; \ 2168 INIT_PREAD; \ 2169 INIT_PREAD64; \ 2170 INIT_READV; \ 2171 INIT_PREADV; \ 2172 INIT_PREADV64; \ 2173 INIT_WRITE; \ 2174 INIT_PWRITE; \ 2175 INIT_PWRITE64; \ 2176 INIT_WRITEV; \ 2177 INIT_PWRITEV; \ 2178 INIT_PWRITEV64; \ 2179 INIT_PRCTL; \ 2180 INIT_LOCALTIME_AND_FRIENDS; \ 2181 INIT_SCANF; \ 2182 INIT_ISOC99_SCANF; \ 2183 INIT_FREXP; \ 2184 INIT_FREXPF_FREXPL; \ 2185 INIT_GETPWNAM_AND_FRIENDS; \ 2186 INIT_GETPWNAM_R_AND_FRIENDS; \ 2187 INIT_CLOCK_GETTIME; \ 2188 INIT_GETITIMER; \ 2189 INIT_TIME; \ 2190 INIT_GLOB; \ 2191 INIT_WAIT; \ 2192 INIT_INET; \ 2193 INIT_PTHREAD_GETSCHEDPARAM; \ 2194 INIT_GETADDRINFO; \ 2195 INIT_GETNAMEINFO; \ 2196 INIT_GETSOCKNAME; \ 2197 INIT_GETHOSTBYNAME; \ 2198 INIT_GETHOSTBYNAME_R; \ 2199 INIT_GETSOCKOPT; \ 2200 INIT_ACCEPT; \ 2201 INIT_ACCEPT4; \ 2202 INIT_MODF; \ 2203 INIT_RECVMSG; \ 2204 INIT_GETPEERNAME; \ 2205 INIT_IOCTL; \ 2206 INIT_INET_ATON; \ 2207 INIT_SYSINFO; \ 2208 INIT_READDIR; \ 2209 INIT_READDIR64; \ 2210 INIT_PTRACE; \ 2211 INIT_SETLOCALE; \ 2212 INIT_GETCWD; \ 2213 INIT_GET_CURRENT_DIR_NAME; \ 2214 INIT_STRTOIMAX; \ 2215 INIT_MBSTOWCS; \ 2216 INIT_MBSNRTOWCS; \ 2217 INIT_WCSTOMBS; \ 2218 INIT_WCSNRTOMBS; \ 2219 INIT_TCGETATTR; \ 2220 INIT_REALPATH; \ 2221 INIT_CANONICALIZE_FILE_NAME; \ 2222 INIT_CONFSTR; \ 2223 INIT_SCHED_GETAFFINITY; \ 2224 INIT_STRERROR; \ 2225 INIT_STRERROR_R; \ 2226 INIT_SCANDIR; \ 2227 INIT_SCANDIR64; \ 2228 INIT_GETGROUPS; \ 2229 INIT_POLL; \ 2230 INIT_PPOLL; \ 2231 INIT_WORDEXP; \ 2232 INIT_SIGWAIT; \ 2233 INIT_SIGWAITINFO; \ 2234 INIT_SIGTIMEDWAIT; \ 2235 INIT_SIGSETOPS; \ 2236 INIT_SIGPENDING; \ 2237 INIT_SIGPROCMASK; \ 2238 INIT_BACKTRACE; 2239