1*ee754c2dSkamil//===-- sanitizer_common_interceptors.inc -----------------------*- C++ -*-===// 2*ee754c2dSkamil// 3*ee754c2dSkamil// The LLVM Compiler Infrastructure 4*ee754c2dSkamil// 5*ee754c2dSkamil// This file is distributed under the University of Illinois Open Source 6*ee754c2dSkamil// License. See LICENSE.TXT for details. 7*ee754c2dSkamil// 8*ee754c2dSkamil//===----------------------------------------------------------------------===// 9*ee754c2dSkamil// 10*ee754c2dSkamil// Common function interceptors for tools like AddressSanitizer, 11*ee754c2dSkamil// ThreadSanitizer, MemorySanitizer, etc. 12*ee754c2dSkamil// 13*ee754c2dSkamil// This file should be included into the tool's interceptor file, 14*ee754c2dSkamil// which has to define its own macros: 15*ee754c2dSkamil// COMMON_INTERCEPTOR_ENTER 16*ee754c2dSkamil// COMMON_INTERCEPTOR_ENTER_NOIGNORE 17*ee754c2dSkamil// COMMON_INTERCEPTOR_READ_RANGE 18*ee754c2dSkamil// COMMON_INTERCEPTOR_WRITE_RANGE 19*ee754c2dSkamil// COMMON_INTERCEPTOR_INITIALIZE_RANGE 20*ee754c2dSkamil// COMMON_INTERCEPTOR_DIR_ACQUIRE 21*ee754c2dSkamil// COMMON_INTERCEPTOR_FD_ACQUIRE 22*ee754c2dSkamil// COMMON_INTERCEPTOR_FD_RELEASE 23*ee754c2dSkamil// COMMON_INTERCEPTOR_FD_ACCESS 24*ee754c2dSkamil// COMMON_INTERCEPTOR_SET_THREAD_NAME 25*ee754c2dSkamil// COMMON_INTERCEPTOR_ON_DLOPEN 26*ee754c2dSkamil// COMMON_INTERCEPTOR_ON_EXIT 27*ee754c2dSkamil// COMMON_INTERCEPTOR_MUTEX_PRE_LOCK 28*ee754c2dSkamil// COMMON_INTERCEPTOR_MUTEX_POST_LOCK 29*ee754c2dSkamil// COMMON_INTERCEPTOR_MUTEX_UNLOCK 30*ee754c2dSkamil// COMMON_INTERCEPTOR_MUTEX_REPAIR 31*ee754c2dSkamil// COMMON_INTERCEPTOR_SET_PTHREAD_NAME 32*ee754c2dSkamil// COMMON_INTERCEPTOR_HANDLE_RECVMSG 33*ee754c2dSkamil// COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED 34*ee754c2dSkamil// COMMON_INTERCEPTOR_MEMSET_IMPL 35*ee754c2dSkamil// COMMON_INTERCEPTOR_MEMMOVE_IMPL 36*ee754c2dSkamil// COMMON_INTERCEPTOR_MEMCPY_IMPL 37*ee754c2dSkamil// COMMON_INTERCEPTOR_MMAP_IMPL 38*ee754c2dSkamil// COMMON_INTERCEPTOR_COPY_STRING 39*ee754c2dSkamil// COMMON_INTERCEPTOR_STRNDUP_IMPL 40*ee754c2dSkamil//===----------------------------------------------------------------------===// 41*ee754c2dSkamil 42*ee754c2dSkamil#include "interception/interception.h" 43*ee754c2dSkamil#include "sanitizer_addrhashmap.h" 44*ee754c2dSkamil#include "sanitizer_errno.h" 45*ee754c2dSkamil#include "sanitizer_placement_new.h" 46*ee754c2dSkamil#include "sanitizer_platform_interceptors.h" 47*ee754c2dSkamil#include "sanitizer_symbolizer.h" 48*ee754c2dSkamil#include "sanitizer_tls_get_addr.h" 49*ee754c2dSkamil 50*ee754c2dSkamil#include <stdarg.h> 51*ee754c2dSkamil 52*ee754c2dSkamil#if SANITIZER_INTERCEPTOR_HOOKS 53*ee754c2dSkamil#define CALL_WEAK_INTERCEPTOR_HOOK(f, ...) f(__VA_ARGS__); 54*ee754c2dSkamil#define DECLARE_WEAK_INTERCEPTOR_HOOK(f, ...) \ 55*ee754c2dSkamil SANITIZER_INTERFACE_WEAK_DEF(void, f, __VA_ARGS__) {} 56*ee754c2dSkamil#else 57*ee754c2dSkamil#define DECLARE_WEAK_INTERCEPTOR_HOOK(f, ...) 58*ee754c2dSkamil#define CALL_WEAK_INTERCEPTOR_HOOK(f, ...) 59*ee754c2dSkamil 60*ee754c2dSkamil#endif // SANITIZER_INTERCEPTOR_HOOKS 61*ee754c2dSkamil 62*ee754c2dSkamil#if SANITIZER_WINDOWS && !defined(va_copy) 63*ee754c2dSkamil#define va_copy(dst, src) ((dst) = (src)) 64*ee754c2dSkamil#endif // _WIN32 65*ee754c2dSkamil 66*ee754c2dSkamil#if SANITIZER_FREEBSD 67*ee754c2dSkamil#define pthread_setname_np pthread_set_name_np 68*ee754c2dSkamil#define inet_aton __inet_aton 69*ee754c2dSkamil#define inet_pton __inet_pton 70*ee754c2dSkamil#define iconv __bsd_iconv 71*ee754c2dSkamil#endif 72*ee754c2dSkamil 73*ee754c2dSkamil#if SANITIZER_NETBSD 74*ee754c2dSkamil#define clock_getres __clock_getres50 75*ee754c2dSkamil#define clock_gettime __clock_gettime50 76*ee754c2dSkamil#define clock_settime __clock_settime50 77*ee754c2dSkamil#define ctime __ctime50 78*ee754c2dSkamil#define ctime_r __ctime_r50 79*ee754c2dSkamil#define devname __devname50 80*ee754c2dSkamil#define fgetpos __fgetpos50 81*ee754c2dSkamil#define fsetpos __fsetpos50 82*ee754c2dSkamil#define fts_children __fts_children60 83*ee754c2dSkamil#define fts_close __fts_close60 84*ee754c2dSkamil#define fts_open __fts_open60 85*ee754c2dSkamil#define fts_read __fts_read60 86*ee754c2dSkamil#define fts_set __fts_set60 87*ee754c2dSkamil#define getitimer __getitimer50 88*ee754c2dSkamil#define getmntinfo __getmntinfo13 89*ee754c2dSkamil#define getpwent __getpwent50 90*ee754c2dSkamil#define getpwnam __getpwnam50 91*ee754c2dSkamil#define getpwnam_r __getpwnam_r50 92*ee754c2dSkamil#define getpwuid __getpwuid50 93*ee754c2dSkamil#define getpwuid_r __getpwuid_r50 94*ee754c2dSkamil#define getutent __getutent50 95*ee754c2dSkamil#define getutxent __getutxent50 96*ee754c2dSkamil#define getutxid __getutxid50 97*ee754c2dSkamil#define getutxline __getutxline50 98*ee754c2dSkamil#define glob __glob30 99*ee754c2dSkamil#define gmtime __gmtime50 100*ee754c2dSkamil#define gmtime_r __gmtime_r50 101*ee754c2dSkamil#define localtime __locatime50 102*ee754c2dSkamil#define localtime_r __localtime_r50 103*ee754c2dSkamil#define mktime __mktime50 104*ee754c2dSkamil#define lstat __lstat50 105*ee754c2dSkamil#define opendir __opendir30 106*ee754c2dSkamil#define readdir __readdir30 107*ee754c2dSkamil#define readdir_r __readdir_r30 108*ee754c2dSkamil#define scandir __scandir30 109*ee754c2dSkamil#define setitimer __setitimer50 110*ee754c2dSkamil#define setlocale __setlocale50 111*ee754c2dSkamil#define shmctl __shmctl50 112*ee754c2dSkamil#define sigemptyset __sigemptyset14 113*ee754c2dSkamil#define sigfillset __sigfillset14 114*ee754c2dSkamil#define sigpending __sigpending14 115*ee754c2dSkamil#define sigprocmask __sigprocmask14 116*ee754c2dSkamil#define sigtimedwait __sigtimedwait50 117*ee754c2dSkamil#define stat __stat50 118*ee754c2dSkamil#define time __time50 119*ee754c2dSkamil#define times __times13 120*ee754c2dSkamil#define unvis __unvis50 121*ee754c2dSkamil#define wait3 __wait350 122*ee754c2dSkamil#define wait4 __wait450 123*ee754c2dSkamilextern const unsigned short *_ctype_tab_; 124*ee754c2dSkamilextern const short *_toupper_tab_; 125*ee754c2dSkamilextern const short *_tolower_tab_; 126*ee754c2dSkamil#endif 127*ee754c2dSkamil 128*ee754c2dSkamil// Platform-specific options. 129*ee754c2dSkamil#if SANITIZER_MAC 130*ee754c2dSkamilnamespace __sanitizer { 131*ee754c2dSkamilbool PlatformHasDifferentMemcpyAndMemmove(); 132*ee754c2dSkamil} 133*ee754c2dSkamil#define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE \ 134*ee754c2dSkamil (__sanitizer::PlatformHasDifferentMemcpyAndMemmove()) 135*ee754c2dSkamil#elif SANITIZER_WINDOWS64 136*ee754c2dSkamil#define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE false 137*ee754c2dSkamil#else 138*ee754c2dSkamil#define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE true 139*ee754c2dSkamil#endif // SANITIZER_MAC 140*ee754c2dSkamil 141*ee754c2dSkamil#ifndef COMMON_INTERCEPTOR_INITIALIZE_RANGE 142*ee754c2dSkamil#define COMMON_INTERCEPTOR_INITIALIZE_RANGE(p, size) {} 143*ee754c2dSkamil#endif 144*ee754c2dSkamil 145*ee754c2dSkamil#ifndef COMMON_INTERCEPTOR_UNPOISON_PARAM 146*ee754c2dSkamil#define COMMON_INTERCEPTOR_UNPOISON_PARAM(count) {} 147*ee754c2dSkamil#endif 148*ee754c2dSkamil 149*ee754c2dSkamil#ifndef COMMON_INTERCEPTOR_FD_ACCESS 150*ee754c2dSkamil#define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd) {} 151*ee754c2dSkamil#endif 152*ee754c2dSkamil 153*ee754c2dSkamil#ifndef COMMON_INTERCEPTOR_MUTEX_PRE_LOCK 154*ee754c2dSkamil#define COMMON_INTERCEPTOR_MUTEX_PRE_LOCK(ctx, m) {} 155*ee754c2dSkamil#endif 156*ee754c2dSkamil 157*ee754c2dSkamil#ifndef COMMON_INTERCEPTOR_MUTEX_POST_LOCK 158*ee754c2dSkamil#define COMMON_INTERCEPTOR_MUTEX_POST_LOCK(ctx, m) {} 159*ee754c2dSkamil#endif 160*ee754c2dSkamil 161*ee754c2dSkamil#ifndef COMMON_INTERCEPTOR_MUTEX_UNLOCK 162*ee754c2dSkamil#define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m) {} 163*ee754c2dSkamil#endif 164*ee754c2dSkamil 165*ee754c2dSkamil#ifndef COMMON_INTERCEPTOR_MUTEX_REPAIR 166*ee754c2dSkamil#define COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m) {} 167*ee754c2dSkamil#endif 168*ee754c2dSkamil 169*ee754c2dSkamil#ifndef COMMON_INTERCEPTOR_MUTEX_INVALID 170*ee754c2dSkamil#define COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m) {} 171*ee754c2dSkamil#endif 172*ee754c2dSkamil 173*ee754c2dSkamil#ifndef COMMON_INTERCEPTOR_HANDLE_RECVMSG 174*ee754c2dSkamil#define COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg) ((void)(msg)) 175*ee754c2dSkamil#endif 176*ee754c2dSkamil 177*ee754c2dSkamil#ifndef COMMON_INTERCEPTOR_FILE_OPEN 178*ee754c2dSkamil#define COMMON_INTERCEPTOR_FILE_OPEN(ctx, file, path) {} 179*ee754c2dSkamil#endif 180*ee754c2dSkamil 181*ee754c2dSkamil#ifndef COMMON_INTERCEPTOR_FILE_CLOSE 182*ee754c2dSkamil#define COMMON_INTERCEPTOR_FILE_CLOSE(ctx, file) {} 183*ee754c2dSkamil#endif 184*ee754c2dSkamil 185*ee754c2dSkamil#ifndef COMMON_INTERCEPTOR_LIBRARY_LOADED 186*ee754c2dSkamil#define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle) {} 187*ee754c2dSkamil#endif 188*ee754c2dSkamil 189*ee754c2dSkamil#ifndef COMMON_INTERCEPTOR_LIBRARY_UNLOADED 190*ee754c2dSkamil#define COMMON_INTERCEPTOR_LIBRARY_UNLOADED() {} 191*ee754c2dSkamil#endif 192*ee754c2dSkamil 193*ee754c2dSkamil#ifndef COMMON_INTERCEPTOR_ENTER_NOIGNORE 194*ee754c2dSkamil#define COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, ...) \ 195*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, __VA_ARGS__) 196*ee754c2dSkamil#endif 197*ee754c2dSkamil 198*ee754c2dSkamil#ifndef COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED 199*ee754c2dSkamil#define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (0) 200*ee754c2dSkamil#endif 201*ee754c2dSkamil 202*ee754c2dSkamil#define COMMON_INTERCEPTOR_READ_STRING(ctx, s, n) \ 203*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE((ctx), (s), \ 204*ee754c2dSkamil common_flags()->strict_string_checks ? (REAL(strlen)(s)) + 1 : (n) ) 205*ee754c2dSkamil 206*ee754c2dSkamil#ifndef COMMON_INTERCEPTOR_ON_DLOPEN 207*ee754c2dSkamil#define COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag) \ 208*ee754c2dSkamil CheckNoDeepBind(filename, flag); 209*ee754c2dSkamil#endif 210*ee754c2dSkamil 211*ee754c2dSkamil#ifndef COMMON_INTERCEPTOR_GET_TLS_RANGE 212*ee754c2dSkamil#define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end) *begin = *end = 0; 213*ee754c2dSkamil#endif 214*ee754c2dSkamil 215*ee754c2dSkamil#ifndef COMMON_INTERCEPTOR_ACQUIRE 216*ee754c2dSkamil#define COMMON_INTERCEPTOR_ACQUIRE(ctx, u) {} 217*ee754c2dSkamil#endif 218*ee754c2dSkamil 219*ee754c2dSkamil#ifndef COMMON_INTERCEPTOR_RELEASE 220*ee754c2dSkamil#define COMMON_INTERCEPTOR_RELEASE(ctx, u) {} 221*ee754c2dSkamil#endif 222*ee754c2dSkamil 223*ee754c2dSkamil#ifndef COMMON_INTERCEPTOR_USER_CALLBACK_START 224*ee754c2dSkamil#define COMMON_INTERCEPTOR_USER_CALLBACK_START() {} 225*ee754c2dSkamil#endif 226*ee754c2dSkamil 227*ee754c2dSkamil#ifndef COMMON_INTERCEPTOR_USER_CALLBACK_END 228*ee754c2dSkamil#define COMMON_INTERCEPTOR_USER_CALLBACK_END() {} 229*ee754c2dSkamil#endif 230*ee754c2dSkamil 231*ee754c2dSkamil#ifdef SANITIZER_NLDBL_VERSION 232*ee754c2dSkamil#define COMMON_INTERCEPT_FUNCTION_LDBL(fn) \ 233*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION_VER(fn, SANITIZER_NLDBL_VERSION) 234*ee754c2dSkamil#else 235*ee754c2dSkamil#define COMMON_INTERCEPT_FUNCTION_LDBL(fn) \ 236*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(fn) 237*ee754c2dSkamil#endif 238*ee754c2dSkamil 239*ee754c2dSkamil#ifndef COMMON_INTERCEPTOR_MEMSET_IMPL 240*ee754c2dSkamil#define COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, dst, v, size) \ 241*ee754c2dSkamil { \ 242*ee754c2dSkamil if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) \ 243*ee754c2dSkamil return internal_memset(dst, v, size); \ 244*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, memset, dst, v, size); \ 245*ee754c2dSkamil if (common_flags()->intercept_intrin) \ 246*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size); \ 247*ee754c2dSkamil return REAL(memset)(dst, v, size); \ 248*ee754c2dSkamil } 249*ee754c2dSkamil#endif 250*ee754c2dSkamil 251*ee754c2dSkamil#ifndef COMMON_INTERCEPTOR_MEMMOVE_IMPL 252*ee754c2dSkamil#define COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, dst, src, size) \ 253*ee754c2dSkamil { \ 254*ee754c2dSkamil if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) \ 255*ee754c2dSkamil return internal_memmove(dst, src, size); \ 256*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, memmove, dst, src, size); \ 257*ee754c2dSkamil if (common_flags()->intercept_intrin) { \ 258*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size); \ 259*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, src, size); \ 260*ee754c2dSkamil } \ 261*ee754c2dSkamil return REAL(memmove)(dst, src, size); \ 262*ee754c2dSkamil } 263*ee754c2dSkamil#endif 264*ee754c2dSkamil 265*ee754c2dSkamil#ifndef COMMON_INTERCEPTOR_MEMCPY_IMPL 266*ee754c2dSkamil#define COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, dst, src, size) \ 267*ee754c2dSkamil { \ 268*ee754c2dSkamil if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) { \ 269*ee754c2dSkamil return internal_memmove(dst, src, size); \ 270*ee754c2dSkamil } \ 271*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, memcpy, dst, src, size); \ 272*ee754c2dSkamil if (common_flags()->intercept_intrin) { \ 273*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size); \ 274*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, src, size); \ 275*ee754c2dSkamil } \ 276*ee754c2dSkamil return REAL(memcpy)(dst, src, size); \ 277*ee754c2dSkamil } 278*ee754c2dSkamil#endif 279*ee754c2dSkamil 280*ee754c2dSkamil#ifndef COMMON_INTERCEPTOR_MMAP_IMPL 281*ee754c2dSkamil#define COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, sz, prot, flags, fd, \ 282*ee754c2dSkamil off) \ 283*ee754c2dSkamil { return REAL(mmap)(addr, sz, prot, flags, fd, off); } 284*ee754c2dSkamil#endif 285*ee754c2dSkamil 286*ee754c2dSkamil#ifndef COMMON_INTERCEPTOR_COPY_STRING 287*ee754c2dSkamil#define COMMON_INTERCEPTOR_COPY_STRING(ctx, to, from, size) {} 288*ee754c2dSkamil#endif 289*ee754c2dSkamil 290*ee754c2dSkamil#ifndef COMMON_INTERCEPTOR_STRNDUP_IMPL 291*ee754c2dSkamil#define COMMON_INTERCEPTOR_STRNDUP_IMPL(ctx, s, size) \ 292*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strndup, s, size); \ 293*ee754c2dSkamil uptr copy_length = internal_strnlen(s, size); \ 294*ee754c2dSkamil char *new_mem = (char *)WRAP(malloc)(copy_length + 1); \ 295*ee754c2dSkamil if (common_flags()->intercept_strndup) { \ 296*ee754c2dSkamil COMMON_INTERCEPTOR_READ_STRING(ctx, s, Min(size, copy_length + 1)); \ 297*ee754c2dSkamil } \ 298*ee754c2dSkamil COMMON_INTERCEPTOR_COPY_STRING(ctx, new_mem, s, copy_length); \ 299*ee754c2dSkamil internal_memcpy(new_mem, s, copy_length); \ 300*ee754c2dSkamil new_mem[copy_length] = '\0'; \ 301*ee754c2dSkamil return new_mem; 302*ee754c2dSkamil#endif 303*ee754c2dSkamil 304*ee754c2dSkamilstruct FileMetadata { 305*ee754c2dSkamil // For open_memstream(). 306*ee754c2dSkamil char **addr; 307*ee754c2dSkamil SIZE_T *size; 308*ee754c2dSkamil}; 309*ee754c2dSkamil 310*ee754c2dSkamilstruct CommonInterceptorMetadata { 311*ee754c2dSkamil enum { 312*ee754c2dSkamil CIMT_INVALID = 0, 313*ee754c2dSkamil CIMT_FILE 314*ee754c2dSkamil } type; 315*ee754c2dSkamil union { 316*ee754c2dSkamil FileMetadata file; 317*ee754c2dSkamil }; 318*ee754c2dSkamil}; 319*ee754c2dSkamil 320*ee754c2dSkamiltypedef AddrHashMap<CommonInterceptorMetadata, 31051> MetadataHashMap; 321*ee754c2dSkamil 322*ee754c2dSkamilstatic MetadataHashMap *interceptor_metadata_map; 323*ee754c2dSkamil 324*ee754c2dSkamil#if SI_POSIX 325*ee754c2dSkamilUNUSED static void SetInterceptorMetadata(__sanitizer_FILE *addr, 326*ee754c2dSkamil const FileMetadata &file) { 327*ee754c2dSkamil MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr); 328*ee754c2dSkamil CHECK(h.created()); 329*ee754c2dSkamil h->type = CommonInterceptorMetadata::CIMT_FILE; 330*ee754c2dSkamil h->file = file; 331*ee754c2dSkamil} 332*ee754c2dSkamil 333*ee754c2dSkamilUNUSED static const FileMetadata *GetInterceptorMetadata( 334*ee754c2dSkamil __sanitizer_FILE *addr) { 335*ee754c2dSkamil MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr, 336*ee754c2dSkamil /* remove */ false, 337*ee754c2dSkamil /* create */ false); 338*ee754c2dSkamil if (addr && h.exists()) { 339*ee754c2dSkamil CHECK(!h.created()); 340*ee754c2dSkamil CHECK(h->type == CommonInterceptorMetadata::CIMT_FILE); 341*ee754c2dSkamil return &h->file; 342*ee754c2dSkamil } else { 343*ee754c2dSkamil return 0; 344*ee754c2dSkamil } 345*ee754c2dSkamil} 346*ee754c2dSkamil 347*ee754c2dSkamilUNUSED static void DeleteInterceptorMetadata(void *addr) { 348*ee754c2dSkamil MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr, true); 349*ee754c2dSkamil CHECK(h.exists()); 350*ee754c2dSkamil} 351*ee754c2dSkamil#endif // SI_POSIX 352*ee754c2dSkamil 353*ee754c2dSkamil#if SANITIZER_INTERCEPT_STRLEN 354*ee754c2dSkamilINTERCEPTOR(SIZE_T, strlen, const char *s) { 355*ee754c2dSkamil // Sometimes strlen is called prior to InitializeCommonInterceptors, 356*ee754c2dSkamil // in which case the REAL(strlen) typically used in 357*ee754c2dSkamil // COMMON_INTERCEPTOR_ENTER will fail. We use internal_strlen here 358*ee754c2dSkamil // to handle that. 359*ee754c2dSkamil if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) 360*ee754c2dSkamil return internal_strlen(s); 361*ee754c2dSkamil void *ctx; 362*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strlen, s); 363*ee754c2dSkamil SIZE_T result = REAL(strlen)(s); 364*ee754c2dSkamil if (common_flags()->intercept_strlen) 365*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, s, result + 1); 366*ee754c2dSkamil return result; 367*ee754c2dSkamil} 368*ee754c2dSkamil#define INIT_STRLEN COMMON_INTERCEPT_FUNCTION(strlen) 369*ee754c2dSkamil#else 370*ee754c2dSkamil#define INIT_STRLEN 371*ee754c2dSkamil#endif 372*ee754c2dSkamil 373*ee754c2dSkamil#if SANITIZER_INTERCEPT_STRNLEN 374*ee754c2dSkamilINTERCEPTOR(SIZE_T, strnlen, const char *s, SIZE_T maxlen) { 375*ee754c2dSkamil void *ctx; 376*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strnlen, s, maxlen); 377*ee754c2dSkamil SIZE_T length = REAL(strnlen)(s, maxlen); 378*ee754c2dSkamil if (common_flags()->intercept_strlen) 379*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, s, Min(length + 1, maxlen)); 380*ee754c2dSkamil return length; 381*ee754c2dSkamil} 382*ee754c2dSkamil#define INIT_STRNLEN COMMON_INTERCEPT_FUNCTION(strnlen) 383*ee754c2dSkamil#else 384*ee754c2dSkamil#define INIT_STRNLEN 385*ee754c2dSkamil#endif 386*ee754c2dSkamil 387*ee754c2dSkamil#if SANITIZER_INTERCEPT_STRNDUP 388*ee754c2dSkamilINTERCEPTOR(char*, strndup, const char *s, uptr size) { 389*ee754c2dSkamil void *ctx; 390*ee754c2dSkamil COMMON_INTERCEPTOR_STRNDUP_IMPL(ctx, s, size); 391*ee754c2dSkamil} 392*ee754c2dSkamil#define INIT_STRNDUP COMMON_INTERCEPT_FUNCTION(strndup) 393*ee754c2dSkamil#else 394*ee754c2dSkamil#define INIT_STRNDUP 395*ee754c2dSkamil#endif // SANITIZER_INTERCEPT_STRNDUP 396*ee754c2dSkamil 397*ee754c2dSkamil#if SANITIZER_INTERCEPT___STRNDUP 398*ee754c2dSkamilINTERCEPTOR(char*, __strndup, const char *s, uptr size) { 399*ee754c2dSkamil void *ctx; 400*ee754c2dSkamil COMMON_INTERCEPTOR_STRNDUP_IMPL(ctx, s, size); 401*ee754c2dSkamil} 402*ee754c2dSkamil#define INIT___STRNDUP COMMON_INTERCEPT_FUNCTION(__strndup) 403*ee754c2dSkamil#else 404*ee754c2dSkamil#define INIT___STRNDUP 405*ee754c2dSkamil#endif // SANITIZER_INTERCEPT___STRNDUP 406*ee754c2dSkamil 407*ee754c2dSkamil#if SANITIZER_INTERCEPT_TEXTDOMAIN 408*ee754c2dSkamilINTERCEPTOR(char*, textdomain, const char *domainname) { 409*ee754c2dSkamil void *ctx; 410*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, textdomain, domainname); 411*ee754c2dSkamil if (domainname) COMMON_INTERCEPTOR_READ_STRING(ctx, domainname, 0); 412*ee754c2dSkamil char *domain = REAL(textdomain)(domainname); 413*ee754c2dSkamil if (domain) { 414*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(domain, REAL(strlen)(domain) + 1); 415*ee754c2dSkamil } 416*ee754c2dSkamil return domain; 417*ee754c2dSkamil} 418*ee754c2dSkamil#define INIT_TEXTDOMAIN COMMON_INTERCEPT_FUNCTION(textdomain) 419*ee754c2dSkamil#else 420*ee754c2dSkamil#define INIT_TEXTDOMAIN 421*ee754c2dSkamil#endif 422*ee754c2dSkamil 423*ee754c2dSkamil#if SANITIZER_INTERCEPT_STRCMP 424*ee754c2dSkamilstatic inline int CharCmpX(unsigned char c1, unsigned char c2) { 425*ee754c2dSkamil return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1; 426*ee754c2dSkamil} 427*ee754c2dSkamil 428*ee754c2dSkamilDECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcmp, uptr called_pc, 429*ee754c2dSkamil const char *s1, const char *s2, int result) 430*ee754c2dSkamil 431*ee754c2dSkamilINTERCEPTOR(int, strcmp, const char *s1, const char *s2) { 432*ee754c2dSkamil void *ctx; 433*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strcmp, s1, s2); 434*ee754c2dSkamil unsigned char c1, c2; 435*ee754c2dSkamil uptr i; 436*ee754c2dSkamil for (i = 0;; i++) { 437*ee754c2dSkamil c1 = (unsigned char)s1[i]; 438*ee754c2dSkamil c2 = (unsigned char)s2[i]; 439*ee754c2dSkamil if (c1 != c2 || c1 == '\0') break; 440*ee754c2dSkamil } 441*ee754c2dSkamil COMMON_INTERCEPTOR_READ_STRING(ctx, s1, i + 1); 442*ee754c2dSkamil COMMON_INTERCEPTOR_READ_STRING(ctx, s2, i + 1); 443*ee754c2dSkamil int result = CharCmpX(c1, c2); 444*ee754c2dSkamil CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcmp, GET_CALLER_PC(), s1, 445*ee754c2dSkamil s2, result); 446*ee754c2dSkamil return result; 447*ee754c2dSkamil} 448*ee754c2dSkamil 449*ee754c2dSkamilDECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncmp, uptr called_pc, 450*ee754c2dSkamil const char *s1, const char *s2, uptr n, 451*ee754c2dSkamil int result) 452*ee754c2dSkamil 453*ee754c2dSkamilINTERCEPTOR(int, strncmp, const char *s1, const char *s2, uptr size) { 454*ee754c2dSkamil if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) 455*ee754c2dSkamil return internal_strncmp(s1, s2, size); 456*ee754c2dSkamil void *ctx; 457*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strncmp, s1, s2, size); 458*ee754c2dSkamil unsigned char c1 = 0, c2 = 0; 459*ee754c2dSkamil uptr i; 460*ee754c2dSkamil for (i = 0; i < size; i++) { 461*ee754c2dSkamil c1 = (unsigned char)s1[i]; 462*ee754c2dSkamil c2 = (unsigned char)s2[i]; 463*ee754c2dSkamil if (c1 != c2 || c1 == '\0') break; 464*ee754c2dSkamil } 465*ee754c2dSkamil uptr i1 = i; 466*ee754c2dSkamil uptr i2 = i; 467*ee754c2dSkamil if (common_flags()->strict_string_checks) { 468*ee754c2dSkamil for (; i1 < size && s1[i1]; i1++) {} 469*ee754c2dSkamil for (; i2 < size && s2[i2]; i2++) {} 470*ee754c2dSkamil } 471*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE((ctx), (s1), Min(i1 + 1, size)); 472*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE((ctx), (s2), Min(i2 + 1, size)); 473*ee754c2dSkamil int result = CharCmpX(c1, c2); 474*ee754c2dSkamil CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncmp, GET_CALLER_PC(), s1, 475*ee754c2dSkamil s2, size, result); 476*ee754c2dSkamil return result; 477*ee754c2dSkamil} 478*ee754c2dSkamil 479*ee754c2dSkamil#define INIT_STRCMP COMMON_INTERCEPT_FUNCTION(strcmp) 480*ee754c2dSkamil#define INIT_STRNCMP COMMON_INTERCEPT_FUNCTION(strncmp) 481*ee754c2dSkamil#else 482*ee754c2dSkamil#define INIT_STRCMP 483*ee754c2dSkamil#define INIT_STRNCMP 484*ee754c2dSkamil#endif 485*ee754c2dSkamil 486*ee754c2dSkamil#if SANITIZER_INTERCEPT_STRCASECMP 487*ee754c2dSkamilstatic inline int CharCaseCmp(unsigned char c1, unsigned char c2) { 488*ee754c2dSkamil int c1_low = ToLower(c1); 489*ee754c2dSkamil int c2_low = ToLower(c2); 490*ee754c2dSkamil return c1_low - c2_low; 491*ee754c2dSkamil} 492*ee754c2dSkamil 493*ee754c2dSkamilDECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasecmp, uptr called_pc, 494*ee754c2dSkamil const char *s1, const char *s2, int result) 495*ee754c2dSkamil 496*ee754c2dSkamilINTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) { 497*ee754c2dSkamil void *ctx; 498*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strcasecmp, s1, s2); 499*ee754c2dSkamil unsigned char c1 = 0, c2 = 0; 500*ee754c2dSkamil uptr i; 501*ee754c2dSkamil for (i = 0;; i++) { 502*ee754c2dSkamil c1 = (unsigned char)s1[i]; 503*ee754c2dSkamil c2 = (unsigned char)s2[i]; 504*ee754c2dSkamil if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break; 505*ee754c2dSkamil } 506*ee754c2dSkamil COMMON_INTERCEPTOR_READ_STRING(ctx, s1, i + 1); 507*ee754c2dSkamil COMMON_INTERCEPTOR_READ_STRING(ctx, s2, i + 1); 508*ee754c2dSkamil int result = CharCaseCmp(c1, c2); 509*ee754c2dSkamil CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasecmp, GET_CALLER_PC(), 510*ee754c2dSkamil s1, s2, result); 511*ee754c2dSkamil return result; 512*ee754c2dSkamil} 513*ee754c2dSkamil 514*ee754c2dSkamilDECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncasecmp, uptr called_pc, 515*ee754c2dSkamil const char *s1, const char *s2, uptr size, 516*ee754c2dSkamil int result) 517*ee754c2dSkamil 518*ee754c2dSkamilINTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, SIZE_T size) { 519*ee754c2dSkamil void *ctx; 520*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strncasecmp, s1, s2, size); 521*ee754c2dSkamil unsigned char c1 = 0, c2 = 0; 522*ee754c2dSkamil uptr i; 523*ee754c2dSkamil for (i = 0; i < size; i++) { 524*ee754c2dSkamil c1 = (unsigned char)s1[i]; 525*ee754c2dSkamil c2 = (unsigned char)s2[i]; 526*ee754c2dSkamil if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break; 527*ee754c2dSkamil } 528*ee754c2dSkamil uptr i1 = i; 529*ee754c2dSkamil uptr i2 = i; 530*ee754c2dSkamil if (common_flags()->strict_string_checks) { 531*ee754c2dSkamil for (; i1 < size && s1[i1]; i1++) {} 532*ee754c2dSkamil for (; i2 < size && s2[i2]; i2++) {} 533*ee754c2dSkamil } 534*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE((ctx), (s1), Min(i1 + 1, size)); 535*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE((ctx), (s2), Min(i2 + 1, size)); 536*ee754c2dSkamil int result = CharCaseCmp(c1, c2); 537*ee754c2dSkamil CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncasecmp, GET_CALLER_PC(), 538*ee754c2dSkamil s1, s2, size, result); 539*ee754c2dSkamil return result; 540*ee754c2dSkamil} 541*ee754c2dSkamil 542*ee754c2dSkamil#define INIT_STRCASECMP COMMON_INTERCEPT_FUNCTION(strcasecmp) 543*ee754c2dSkamil#define INIT_STRNCASECMP COMMON_INTERCEPT_FUNCTION(strncasecmp) 544*ee754c2dSkamil#else 545*ee754c2dSkamil#define INIT_STRCASECMP 546*ee754c2dSkamil#define INIT_STRNCASECMP 547*ee754c2dSkamil#endif 548*ee754c2dSkamil 549*ee754c2dSkamil#if SANITIZER_INTERCEPT_STRSTR || SANITIZER_INTERCEPT_STRCASESTR 550*ee754c2dSkamilstatic inline void StrstrCheck(void *ctx, char *r, const char *s1, 551*ee754c2dSkamil const char *s2) { 552*ee754c2dSkamil uptr len1 = REAL(strlen)(s1); 553*ee754c2dSkamil uptr len2 = REAL(strlen)(s2); 554*ee754c2dSkamil COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r ? r - s1 + len2 : len1 + 1); 555*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, len2 + 1); 556*ee754c2dSkamil} 557*ee754c2dSkamil#endif 558*ee754c2dSkamil 559*ee754c2dSkamil#if SANITIZER_INTERCEPT_STRSTR 560*ee754c2dSkamil 561*ee754c2dSkamilDECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strstr, uptr called_pc, 562*ee754c2dSkamil const char *s1, const char *s2, char *result) 563*ee754c2dSkamil 564*ee754c2dSkamilINTERCEPTOR(char*, strstr, const char *s1, const char *s2) { 565*ee754c2dSkamil if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) 566*ee754c2dSkamil return internal_strstr(s1, s2); 567*ee754c2dSkamil void *ctx; 568*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strstr, s1, s2); 569*ee754c2dSkamil char *r = REAL(strstr)(s1, s2); 570*ee754c2dSkamil if (common_flags()->intercept_strstr) 571*ee754c2dSkamil StrstrCheck(ctx, r, s1, s2); 572*ee754c2dSkamil CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strstr, GET_CALLER_PC(), s1, 573*ee754c2dSkamil s2, r); 574*ee754c2dSkamil return r; 575*ee754c2dSkamil} 576*ee754c2dSkamil 577*ee754c2dSkamil#define INIT_STRSTR COMMON_INTERCEPT_FUNCTION(strstr); 578*ee754c2dSkamil#else 579*ee754c2dSkamil#define INIT_STRSTR 580*ee754c2dSkamil#endif 581*ee754c2dSkamil 582*ee754c2dSkamil#if SANITIZER_INTERCEPT_STRCASESTR 583*ee754c2dSkamil 584*ee754c2dSkamilDECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasestr, uptr called_pc, 585*ee754c2dSkamil const char *s1, const char *s2, char *result) 586*ee754c2dSkamil 587*ee754c2dSkamilINTERCEPTOR(char*, strcasestr, const char *s1, const char *s2) { 588*ee754c2dSkamil void *ctx; 589*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strcasestr, s1, s2); 590*ee754c2dSkamil char *r = REAL(strcasestr)(s1, s2); 591*ee754c2dSkamil if (common_flags()->intercept_strstr) 592*ee754c2dSkamil StrstrCheck(ctx, r, s1, s2); 593*ee754c2dSkamil CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasestr, GET_CALLER_PC(), 594*ee754c2dSkamil s1, s2, r); 595*ee754c2dSkamil return r; 596*ee754c2dSkamil} 597*ee754c2dSkamil 598*ee754c2dSkamil#define INIT_STRCASESTR COMMON_INTERCEPT_FUNCTION(strcasestr); 599*ee754c2dSkamil#else 600*ee754c2dSkamil#define INIT_STRCASESTR 601*ee754c2dSkamil#endif 602*ee754c2dSkamil 603*ee754c2dSkamil#if SANITIZER_INTERCEPT_STRTOK 604*ee754c2dSkamil 605*ee754c2dSkamilINTERCEPTOR(char*, strtok, char *str, const char *delimiters) { 606*ee754c2dSkamil void *ctx; 607*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strtok, str, delimiters); 608*ee754c2dSkamil if (!common_flags()->intercept_strtok) { 609*ee754c2dSkamil return REAL(strtok)(str, delimiters); 610*ee754c2dSkamil } 611*ee754c2dSkamil if (common_flags()->strict_string_checks) { 612*ee754c2dSkamil // If strict_string_checks is enabled, we check the whole first argument 613*ee754c2dSkamil // string on the first call (strtok saves this string in a static buffer 614*ee754c2dSkamil // for subsequent calls). We do not need to check strtok's result. 615*ee754c2dSkamil // As the delimiters can change, we check them every call. 616*ee754c2dSkamil if (str != nullptr) { 617*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, str, REAL(strlen)(str) + 1); 618*ee754c2dSkamil } 619*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, delimiters, 620*ee754c2dSkamil REAL(strlen)(delimiters) + 1); 621*ee754c2dSkamil return REAL(strtok)(str, delimiters); 622*ee754c2dSkamil } else { 623*ee754c2dSkamil // However, when strict_string_checks is disabled we cannot check the 624*ee754c2dSkamil // whole string on the first call. Instead, we check the result string 625*ee754c2dSkamil // which is guaranteed to be a NULL-terminated substring of the first 626*ee754c2dSkamil // argument. We also conservatively check one character of str and the 627*ee754c2dSkamil // delimiters. 628*ee754c2dSkamil if (str != nullptr) { 629*ee754c2dSkamil COMMON_INTERCEPTOR_READ_STRING(ctx, str, 1); 630*ee754c2dSkamil } 631*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, delimiters, 1); 632*ee754c2dSkamil char *result = REAL(strtok)(str, delimiters); 633*ee754c2dSkamil if (result != nullptr) { 634*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, result, REAL(strlen)(result) + 1); 635*ee754c2dSkamil } else if (str != nullptr) { 636*ee754c2dSkamil // No delimiter were found, it's safe to assume that the entire str was 637*ee754c2dSkamil // scanned. 638*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, str, REAL(strlen)(str) + 1); 639*ee754c2dSkamil } 640*ee754c2dSkamil return result; 641*ee754c2dSkamil } 642*ee754c2dSkamil} 643*ee754c2dSkamil 644*ee754c2dSkamil#define INIT_STRTOK COMMON_INTERCEPT_FUNCTION(strtok) 645*ee754c2dSkamil#else 646*ee754c2dSkamil#define INIT_STRTOK 647*ee754c2dSkamil#endif 648*ee754c2dSkamil 649*ee754c2dSkamil#if SANITIZER_INTERCEPT_MEMMEM 650*ee754c2dSkamilDECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memmem, uptr called_pc, 651*ee754c2dSkamil const void *s1, SIZE_T len1, const void *s2, 652*ee754c2dSkamil SIZE_T len2, void *result) 653*ee754c2dSkamil 654*ee754c2dSkamilINTERCEPTOR(void*, memmem, const void *s1, SIZE_T len1, const void *s2, 655*ee754c2dSkamil SIZE_T len2) { 656*ee754c2dSkamil void *ctx; 657*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, memmem, s1, len1, s2, len2); 658*ee754c2dSkamil void *r = REAL(memmem)(s1, len1, s2, len2); 659*ee754c2dSkamil if (common_flags()->intercept_memmem) { 660*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, len1); 661*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, len2); 662*ee754c2dSkamil } 663*ee754c2dSkamil CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memmem, GET_CALLER_PC(), 664*ee754c2dSkamil s1, len1, s2, len2, r); 665*ee754c2dSkamil return r; 666*ee754c2dSkamil} 667*ee754c2dSkamil 668*ee754c2dSkamil#define INIT_MEMMEM COMMON_INTERCEPT_FUNCTION(memmem); 669*ee754c2dSkamil#else 670*ee754c2dSkamil#define INIT_MEMMEM 671*ee754c2dSkamil#endif // SANITIZER_INTERCEPT_MEMMEM 672*ee754c2dSkamil 673*ee754c2dSkamil#if SANITIZER_INTERCEPT_STRCHR 674*ee754c2dSkamilINTERCEPTOR(char*, strchr, const char *s, int c) { 675*ee754c2dSkamil void *ctx; 676*ee754c2dSkamil if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) 677*ee754c2dSkamil return internal_strchr(s, c); 678*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strchr, s, c); 679*ee754c2dSkamil char *result = REAL(strchr)(s, c); 680*ee754c2dSkamil if (common_flags()->intercept_strchr) { 681*ee754c2dSkamil // Keep strlen as macro argument, as macro may ignore it. 682*ee754c2dSkamil COMMON_INTERCEPTOR_READ_STRING(ctx, s, 683*ee754c2dSkamil (result ? result - s : REAL(strlen)(s)) + 1); 684*ee754c2dSkamil } 685*ee754c2dSkamil return result; 686*ee754c2dSkamil} 687*ee754c2dSkamil#define INIT_STRCHR COMMON_INTERCEPT_FUNCTION(strchr) 688*ee754c2dSkamil#else 689*ee754c2dSkamil#define INIT_STRCHR 690*ee754c2dSkamil#endif 691*ee754c2dSkamil 692*ee754c2dSkamil#if SANITIZER_INTERCEPT_STRCHRNUL 693*ee754c2dSkamilINTERCEPTOR(char*, strchrnul, const char *s, int c) { 694*ee754c2dSkamil void *ctx; 695*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strchrnul, s, c); 696*ee754c2dSkamil char *result = REAL(strchrnul)(s, c); 697*ee754c2dSkamil uptr len = result - s + 1; 698*ee754c2dSkamil if (common_flags()->intercept_strchr) 699*ee754c2dSkamil COMMON_INTERCEPTOR_READ_STRING(ctx, s, len); 700*ee754c2dSkamil return result; 701*ee754c2dSkamil} 702*ee754c2dSkamil#define INIT_STRCHRNUL COMMON_INTERCEPT_FUNCTION(strchrnul) 703*ee754c2dSkamil#else 704*ee754c2dSkamil#define INIT_STRCHRNUL 705*ee754c2dSkamil#endif 706*ee754c2dSkamil 707*ee754c2dSkamil#if SANITIZER_INTERCEPT_STRRCHR 708*ee754c2dSkamilINTERCEPTOR(char*, strrchr, const char *s, int c) { 709*ee754c2dSkamil void *ctx; 710*ee754c2dSkamil if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) 711*ee754c2dSkamil return internal_strrchr(s, c); 712*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strrchr, s, c); 713*ee754c2dSkamil if (common_flags()->intercept_strchr) 714*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1); 715*ee754c2dSkamil return REAL(strrchr)(s, c); 716*ee754c2dSkamil} 717*ee754c2dSkamil#define INIT_STRRCHR COMMON_INTERCEPT_FUNCTION(strrchr) 718*ee754c2dSkamil#else 719*ee754c2dSkamil#define INIT_STRRCHR 720*ee754c2dSkamil#endif 721*ee754c2dSkamil 722*ee754c2dSkamil#if SANITIZER_INTERCEPT_STRSPN 723*ee754c2dSkamilINTERCEPTOR(SIZE_T, strspn, const char *s1, const char *s2) { 724*ee754c2dSkamil void *ctx; 725*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strspn, s1, s2); 726*ee754c2dSkamil SIZE_T r = REAL(strspn)(s1, s2); 727*ee754c2dSkamil if (common_flags()->intercept_strspn) { 728*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, REAL(strlen)(s2) + 1); 729*ee754c2dSkamil COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r + 1); 730*ee754c2dSkamil } 731*ee754c2dSkamil return r; 732*ee754c2dSkamil} 733*ee754c2dSkamil 734*ee754c2dSkamilINTERCEPTOR(SIZE_T, strcspn, const char *s1, const char *s2) { 735*ee754c2dSkamil void *ctx; 736*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strcspn, s1, s2); 737*ee754c2dSkamil SIZE_T r = REAL(strcspn)(s1, s2); 738*ee754c2dSkamil if (common_flags()->intercept_strspn) { 739*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, REAL(strlen)(s2) + 1); 740*ee754c2dSkamil COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r + 1); 741*ee754c2dSkamil } 742*ee754c2dSkamil return r; 743*ee754c2dSkamil} 744*ee754c2dSkamil 745*ee754c2dSkamil#define INIT_STRSPN \ 746*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(strspn); \ 747*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(strcspn); 748*ee754c2dSkamil#else 749*ee754c2dSkamil#define INIT_STRSPN 750*ee754c2dSkamil#endif 751*ee754c2dSkamil 752*ee754c2dSkamil#if SANITIZER_INTERCEPT_STRPBRK 753*ee754c2dSkamilINTERCEPTOR(char *, strpbrk, const char *s1, const char *s2) { 754*ee754c2dSkamil void *ctx; 755*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strpbrk, s1, s2); 756*ee754c2dSkamil char *r = REAL(strpbrk)(s1, s2); 757*ee754c2dSkamil if (common_flags()->intercept_strpbrk) { 758*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, REAL(strlen)(s2) + 1); 759*ee754c2dSkamil COMMON_INTERCEPTOR_READ_STRING(ctx, s1, 760*ee754c2dSkamil r ? r - s1 + 1 : REAL(strlen)(s1) + 1); 761*ee754c2dSkamil } 762*ee754c2dSkamil return r; 763*ee754c2dSkamil} 764*ee754c2dSkamil 765*ee754c2dSkamil#define INIT_STRPBRK COMMON_INTERCEPT_FUNCTION(strpbrk); 766*ee754c2dSkamil#else 767*ee754c2dSkamil#define INIT_STRPBRK 768*ee754c2dSkamil#endif 769*ee754c2dSkamil 770*ee754c2dSkamil#if SANITIZER_INTERCEPT_MEMSET 771*ee754c2dSkamilINTERCEPTOR(void *, memset, void *dst, int v, uptr size) { 772*ee754c2dSkamil void *ctx; 773*ee754c2dSkamil COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, dst, v, size); 774*ee754c2dSkamil} 775*ee754c2dSkamil 776*ee754c2dSkamil#define INIT_MEMSET COMMON_INTERCEPT_FUNCTION(memset) 777*ee754c2dSkamil#else 778*ee754c2dSkamil#define INIT_MEMSET 779*ee754c2dSkamil#endif 780*ee754c2dSkamil 781*ee754c2dSkamil#if SANITIZER_INTERCEPT_MEMMOVE 782*ee754c2dSkamilINTERCEPTOR(void *, memmove, void *dst, const void *src, uptr size) { 783*ee754c2dSkamil void *ctx; 784*ee754c2dSkamil COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, dst, src, size); 785*ee754c2dSkamil} 786*ee754c2dSkamil 787*ee754c2dSkamil#define INIT_MEMMOVE COMMON_INTERCEPT_FUNCTION(memmove) 788*ee754c2dSkamil#else 789*ee754c2dSkamil#define INIT_MEMMOVE 790*ee754c2dSkamil#endif 791*ee754c2dSkamil 792*ee754c2dSkamil#if SANITIZER_INTERCEPT_MEMCPY 793*ee754c2dSkamilINTERCEPTOR(void *, memcpy, void *dst, const void *src, uptr size) { 794*ee754c2dSkamil // On OS X, calling internal_memcpy here will cause memory corruptions, 795*ee754c2dSkamil // because memcpy and memmove are actually aliases of the same 796*ee754c2dSkamil // implementation. We need to use internal_memmove here. 797*ee754c2dSkamil // N.B.: If we switch this to internal_ we'll have to use internal_memmove 798*ee754c2dSkamil // due to memcpy being an alias of memmove on OS X. 799*ee754c2dSkamil void *ctx; 800*ee754c2dSkamil if (PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE) { 801*ee754c2dSkamil COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, dst, src, size); 802*ee754c2dSkamil } else { 803*ee754c2dSkamil COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, dst, src, size); 804*ee754c2dSkamil } 805*ee754c2dSkamil} 806*ee754c2dSkamil 807*ee754c2dSkamil#define INIT_MEMCPY \ 808*ee754c2dSkamil do { \ 809*ee754c2dSkamil if (PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE) { \ 810*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(memcpy); \ 811*ee754c2dSkamil } else { \ 812*ee754c2dSkamil ASSIGN_REAL(memcpy, memmove); \ 813*ee754c2dSkamil } \ 814*ee754c2dSkamil CHECK(REAL(memcpy)); \ 815*ee754c2dSkamil } while (false) 816*ee754c2dSkamil 817*ee754c2dSkamil#else 818*ee754c2dSkamil#define INIT_MEMCPY 819*ee754c2dSkamil#endif 820*ee754c2dSkamil 821*ee754c2dSkamil#if SANITIZER_INTERCEPT_MEMCMP 822*ee754c2dSkamil 823*ee754c2dSkamilDECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, uptr called_pc, 824*ee754c2dSkamil const void *s1, const void *s2, uptr n, 825*ee754c2dSkamil int result) 826*ee754c2dSkamil 827*ee754c2dSkamilINTERCEPTOR(int, memcmp, const void *a1, const void *a2, uptr size) { 828*ee754c2dSkamil if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) 829*ee754c2dSkamil return internal_memcmp(a1, a2, size); 830*ee754c2dSkamil void *ctx; 831*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, memcmp, a1, a2, size); 832*ee754c2dSkamil if (common_flags()->intercept_memcmp) { 833*ee754c2dSkamil if (common_flags()->strict_memcmp) { 834*ee754c2dSkamil // Check the entire regions even if the first bytes of the buffers are 835*ee754c2dSkamil // different. 836*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, a1, size); 837*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, a2, size); 838*ee754c2dSkamil // Fallthrough to REAL(memcmp) below. 839*ee754c2dSkamil } else { 840*ee754c2dSkamil unsigned char c1 = 0, c2 = 0; 841*ee754c2dSkamil const unsigned char *s1 = (const unsigned char*)a1; 842*ee754c2dSkamil const unsigned char *s2 = (const unsigned char*)a2; 843*ee754c2dSkamil uptr i; 844*ee754c2dSkamil for (i = 0; i < size; i++) { 845*ee754c2dSkamil c1 = s1[i]; 846*ee754c2dSkamil c2 = s2[i]; 847*ee754c2dSkamil if (c1 != c2) break; 848*ee754c2dSkamil } 849*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, size)); 850*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, size)); 851*ee754c2dSkamil int r = CharCmpX(c1, c2); 852*ee754c2dSkamil CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, GET_CALLER_PC(), 853*ee754c2dSkamil a1, a2, size, r); 854*ee754c2dSkamil return r; 855*ee754c2dSkamil } 856*ee754c2dSkamil } 857*ee754c2dSkamil int result = REAL(memcmp(a1, a2, size)); 858*ee754c2dSkamil CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, GET_CALLER_PC(), a1, 859*ee754c2dSkamil a2, size, result); 860*ee754c2dSkamil return result; 861*ee754c2dSkamil} 862*ee754c2dSkamil 863*ee754c2dSkamil#define INIT_MEMCMP COMMON_INTERCEPT_FUNCTION(memcmp) 864*ee754c2dSkamil#else 865*ee754c2dSkamil#define INIT_MEMCMP 866*ee754c2dSkamil#endif 867*ee754c2dSkamil 868*ee754c2dSkamil#if SANITIZER_INTERCEPT_MEMCHR 869*ee754c2dSkamilINTERCEPTOR(void*, memchr, const void *s, int c, SIZE_T n) { 870*ee754c2dSkamil if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) 871*ee754c2dSkamil return internal_memchr(s, c, n); 872*ee754c2dSkamil void *ctx; 873*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, memchr, s, c, n); 874*ee754c2dSkamil#if SANITIZER_WINDOWS 875*ee754c2dSkamil void *res; 876*ee754c2dSkamil if (REAL(memchr)) { 877*ee754c2dSkamil res = REAL(memchr)(s, c, n); 878*ee754c2dSkamil } else { 879*ee754c2dSkamil res = internal_memchr(s, c, n); 880*ee754c2dSkamil } 881*ee754c2dSkamil#else 882*ee754c2dSkamil void *res = REAL(memchr)(s, c, n); 883*ee754c2dSkamil#endif 884*ee754c2dSkamil uptr len = res ? (char *)res - (const char *)s + 1 : n; 885*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, s, len); 886*ee754c2dSkamil return res; 887*ee754c2dSkamil} 888*ee754c2dSkamil 889*ee754c2dSkamil#define INIT_MEMCHR COMMON_INTERCEPT_FUNCTION(memchr) 890*ee754c2dSkamil#else 891*ee754c2dSkamil#define INIT_MEMCHR 892*ee754c2dSkamil#endif 893*ee754c2dSkamil 894*ee754c2dSkamil#if SANITIZER_INTERCEPT_MEMRCHR 895*ee754c2dSkamilINTERCEPTOR(void*, memrchr, const void *s, int c, SIZE_T n) { 896*ee754c2dSkamil void *ctx; 897*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, memrchr, s, c, n); 898*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, s, n); 899*ee754c2dSkamil return REAL(memrchr)(s, c, n); 900*ee754c2dSkamil} 901*ee754c2dSkamil 902*ee754c2dSkamil#define INIT_MEMRCHR COMMON_INTERCEPT_FUNCTION(memrchr) 903*ee754c2dSkamil#else 904*ee754c2dSkamil#define INIT_MEMRCHR 905*ee754c2dSkamil#endif 906*ee754c2dSkamil 907*ee754c2dSkamil#if SANITIZER_INTERCEPT_FREXP 908*ee754c2dSkamilINTERCEPTOR(double, frexp, double x, int *exp) { 909*ee754c2dSkamil void *ctx; 910*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, frexp, x, exp); 911*ee754c2dSkamil // Assuming frexp() always writes to |exp|. 912*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp)); 913*ee754c2dSkamil double res = REAL(frexp)(x, exp); 914*ee754c2dSkamil return res; 915*ee754c2dSkamil} 916*ee754c2dSkamil 917*ee754c2dSkamil#define INIT_FREXP COMMON_INTERCEPT_FUNCTION(frexp); 918*ee754c2dSkamil#else 919*ee754c2dSkamil#define INIT_FREXP 920*ee754c2dSkamil#endif // SANITIZER_INTERCEPT_FREXP 921*ee754c2dSkamil 922*ee754c2dSkamil#if SANITIZER_INTERCEPT_FREXPF_FREXPL 923*ee754c2dSkamilINTERCEPTOR(float, frexpf, float x, int *exp) { 924*ee754c2dSkamil void *ctx; 925*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, frexpf, x, exp); 926*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 927*ee754c2dSkamil // its metadata. See 928*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 929*ee754c2dSkamil float res = REAL(frexpf)(x, exp); 930*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp)); 931*ee754c2dSkamil return res; 932*ee754c2dSkamil} 933*ee754c2dSkamil 934*ee754c2dSkamilINTERCEPTOR(long double, frexpl, long double x, int *exp) { 935*ee754c2dSkamil void *ctx; 936*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, frexpl, x, exp); 937*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 938*ee754c2dSkamil // its metadata. See 939*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 940*ee754c2dSkamil long double res = REAL(frexpl)(x, exp); 941*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp)); 942*ee754c2dSkamil return res; 943*ee754c2dSkamil} 944*ee754c2dSkamil 945*ee754c2dSkamil#define INIT_FREXPF_FREXPL \ 946*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(frexpf); \ 947*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION_LDBL(frexpl) 948*ee754c2dSkamil#else 949*ee754c2dSkamil#define INIT_FREXPF_FREXPL 950*ee754c2dSkamil#endif // SANITIZER_INTERCEPT_FREXPF_FREXPL 951*ee754c2dSkamil 952*ee754c2dSkamil#if SI_POSIX 953*ee754c2dSkamilstatic void write_iovec(void *ctx, struct __sanitizer_iovec *iovec, 954*ee754c2dSkamil SIZE_T iovlen, SIZE_T maxlen) { 955*ee754c2dSkamil for (SIZE_T i = 0; i < iovlen && maxlen; ++i) { 956*ee754c2dSkamil SSIZE_T sz = Min(iovec[i].iov_len, maxlen); 957*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec[i].iov_base, sz); 958*ee754c2dSkamil maxlen -= sz; 959*ee754c2dSkamil } 960*ee754c2dSkamil} 961*ee754c2dSkamil 962*ee754c2dSkamilstatic void read_iovec(void *ctx, struct __sanitizer_iovec *iovec, 963*ee754c2dSkamil SIZE_T iovlen, SIZE_T maxlen) { 964*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec) * iovlen); 965*ee754c2dSkamil for (SIZE_T i = 0; i < iovlen && maxlen; ++i) { 966*ee754c2dSkamil SSIZE_T sz = Min(iovec[i].iov_len, maxlen); 967*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec[i].iov_base, sz); 968*ee754c2dSkamil maxlen -= sz; 969*ee754c2dSkamil } 970*ee754c2dSkamil} 971*ee754c2dSkamil#endif 972*ee754c2dSkamil 973*ee754c2dSkamil#if SANITIZER_INTERCEPT_READ 974*ee754c2dSkamilINTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) { 975*ee754c2dSkamil void *ctx; 976*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, read, fd, ptr, count); 977*ee754c2dSkamil COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 978*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 979*ee754c2dSkamil // its metadata. See 980*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 981*ee754c2dSkamil SSIZE_T res = REAL(read)(fd, ptr, count); 982*ee754c2dSkamil if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); 983*ee754c2dSkamil if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 984*ee754c2dSkamil return res; 985*ee754c2dSkamil} 986*ee754c2dSkamil#define INIT_READ COMMON_INTERCEPT_FUNCTION(read) 987*ee754c2dSkamil#else 988*ee754c2dSkamil#define INIT_READ 989*ee754c2dSkamil#endif 990*ee754c2dSkamil 991*ee754c2dSkamil#if SANITIZER_INTERCEPT_FREAD 992*ee754c2dSkamilINTERCEPTOR(SIZE_T, fread, void *ptr, SIZE_T size, SIZE_T nmemb, void *file) { 993*ee754c2dSkamil // libc file streams can call user-supplied functions, see fopencookie. 994*ee754c2dSkamil void *ctx; 995*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, fread, ptr, size, nmemb, file); 996*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 997*ee754c2dSkamil // its metadata. See 998*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 999*ee754c2dSkamil SIZE_T res = REAL(fread)(ptr, size, nmemb, file); 1000*ee754c2dSkamil if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res * size); 1001*ee754c2dSkamil return res; 1002*ee754c2dSkamil} 1003*ee754c2dSkamil#define INIT_FREAD COMMON_INTERCEPT_FUNCTION(fread) 1004*ee754c2dSkamil#else 1005*ee754c2dSkamil#define INIT_FREAD 1006*ee754c2dSkamil#endif 1007*ee754c2dSkamil 1008*ee754c2dSkamil#if SANITIZER_INTERCEPT_PREAD 1009*ee754c2dSkamilINTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) { 1010*ee754c2dSkamil void *ctx; 1011*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, pread, fd, ptr, count, offset); 1012*ee754c2dSkamil COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 1013*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 1014*ee754c2dSkamil // its metadata. See 1015*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 1016*ee754c2dSkamil SSIZE_T res = REAL(pread)(fd, ptr, count, offset); 1017*ee754c2dSkamil if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); 1018*ee754c2dSkamil if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 1019*ee754c2dSkamil return res; 1020*ee754c2dSkamil} 1021*ee754c2dSkamil#define INIT_PREAD COMMON_INTERCEPT_FUNCTION(pread) 1022*ee754c2dSkamil#else 1023*ee754c2dSkamil#define INIT_PREAD 1024*ee754c2dSkamil#endif 1025*ee754c2dSkamil 1026*ee754c2dSkamil#if SANITIZER_INTERCEPT_PREAD64 1027*ee754c2dSkamilINTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) { 1028*ee754c2dSkamil void *ctx; 1029*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, pread64, fd, ptr, count, offset); 1030*ee754c2dSkamil COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 1031*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 1032*ee754c2dSkamil // its metadata. See 1033*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 1034*ee754c2dSkamil SSIZE_T res = REAL(pread64)(fd, ptr, count, offset); 1035*ee754c2dSkamil if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); 1036*ee754c2dSkamil if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 1037*ee754c2dSkamil return res; 1038*ee754c2dSkamil} 1039*ee754c2dSkamil#define INIT_PREAD64 COMMON_INTERCEPT_FUNCTION(pread64) 1040*ee754c2dSkamil#else 1041*ee754c2dSkamil#define INIT_PREAD64 1042*ee754c2dSkamil#endif 1043*ee754c2dSkamil 1044*ee754c2dSkamil#if SANITIZER_INTERCEPT_READV 1045*ee754c2dSkamilINTERCEPTOR_WITH_SUFFIX(SSIZE_T, readv, int fd, __sanitizer_iovec *iov, 1046*ee754c2dSkamil int iovcnt) { 1047*ee754c2dSkamil void *ctx; 1048*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, readv, fd, iov, iovcnt); 1049*ee754c2dSkamil COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 1050*ee754c2dSkamil SSIZE_T res = REAL(readv)(fd, iov, iovcnt); 1051*ee754c2dSkamil if (res > 0) write_iovec(ctx, iov, iovcnt, res); 1052*ee754c2dSkamil if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 1053*ee754c2dSkamil return res; 1054*ee754c2dSkamil} 1055*ee754c2dSkamil#define INIT_READV COMMON_INTERCEPT_FUNCTION(readv) 1056*ee754c2dSkamil#else 1057*ee754c2dSkamil#define INIT_READV 1058*ee754c2dSkamil#endif 1059*ee754c2dSkamil 1060*ee754c2dSkamil#if SANITIZER_INTERCEPT_PREADV 1061*ee754c2dSkamilINTERCEPTOR(SSIZE_T, preadv, int fd, __sanitizer_iovec *iov, int iovcnt, 1062*ee754c2dSkamil OFF_T offset) { 1063*ee754c2dSkamil void *ctx; 1064*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, preadv, fd, iov, iovcnt, offset); 1065*ee754c2dSkamil COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 1066*ee754c2dSkamil SSIZE_T res = REAL(preadv)(fd, iov, iovcnt, offset); 1067*ee754c2dSkamil if (res > 0) write_iovec(ctx, iov, iovcnt, res); 1068*ee754c2dSkamil if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 1069*ee754c2dSkamil return res; 1070*ee754c2dSkamil} 1071*ee754c2dSkamil#define INIT_PREADV COMMON_INTERCEPT_FUNCTION(preadv) 1072*ee754c2dSkamil#else 1073*ee754c2dSkamil#define INIT_PREADV 1074*ee754c2dSkamil#endif 1075*ee754c2dSkamil 1076*ee754c2dSkamil#if SANITIZER_INTERCEPT_PREADV64 1077*ee754c2dSkamilINTERCEPTOR(SSIZE_T, preadv64, int fd, __sanitizer_iovec *iov, int iovcnt, 1078*ee754c2dSkamil OFF64_T offset) { 1079*ee754c2dSkamil void *ctx; 1080*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, preadv64, fd, iov, iovcnt, offset); 1081*ee754c2dSkamil COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 1082*ee754c2dSkamil SSIZE_T res = REAL(preadv64)(fd, iov, iovcnt, offset); 1083*ee754c2dSkamil if (res > 0) write_iovec(ctx, iov, iovcnt, res); 1084*ee754c2dSkamil if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 1085*ee754c2dSkamil return res; 1086*ee754c2dSkamil} 1087*ee754c2dSkamil#define INIT_PREADV64 COMMON_INTERCEPT_FUNCTION(preadv64) 1088*ee754c2dSkamil#else 1089*ee754c2dSkamil#define INIT_PREADV64 1090*ee754c2dSkamil#endif 1091*ee754c2dSkamil 1092*ee754c2dSkamil#if SANITIZER_INTERCEPT_WRITE 1093*ee754c2dSkamilINTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) { 1094*ee754c2dSkamil void *ctx; 1095*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, write, fd, ptr, count); 1096*ee754c2dSkamil COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 1097*ee754c2dSkamil if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 1098*ee754c2dSkamil SSIZE_T res = REAL(write)(fd, ptr, count); 1099*ee754c2dSkamil // FIXME: this check should be _before_ the call to REAL(write), not after 1100*ee754c2dSkamil if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); 1101*ee754c2dSkamil return res; 1102*ee754c2dSkamil} 1103*ee754c2dSkamil#define INIT_WRITE COMMON_INTERCEPT_FUNCTION(write) 1104*ee754c2dSkamil#else 1105*ee754c2dSkamil#define INIT_WRITE 1106*ee754c2dSkamil#endif 1107*ee754c2dSkamil 1108*ee754c2dSkamil#if SANITIZER_INTERCEPT_FWRITE 1109*ee754c2dSkamilINTERCEPTOR(SIZE_T, fwrite, const void *p, uptr size, uptr nmemb, void *file) { 1110*ee754c2dSkamil // libc file streams can call user-supplied functions, see fopencookie. 1111*ee754c2dSkamil void *ctx; 1112*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, fwrite, p, size, nmemb, file); 1113*ee754c2dSkamil SIZE_T res = REAL(fwrite)(p, size, nmemb, file); 1114*ee754c2dSkamil if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, p, res * size); 1115*ee754c2dSkamil return res; 1116*ee754c2dSkamil} 1117*ee754c2dSkamil#define INIT_FWRITE COMMON_INTERCEPT_FUNCTION(fwrite) 1118*ee754c2dSkamil#else 1119*ee754c2dSkamil#define INIT_FWRITE 1120*ee754c2dSkamil#endif 1121*ee754c2dSkamil 1122*ee754c2dSkamil#if SANITIZER_INTERCEPT_PWRITE 1123*ee754c2dSkamilINTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) { 1124*ee754c2dSkamil void *ctx; 1125*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, pwrite, fd, ptr, count, offset); 1126*ee754c2dSkamil COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 1127*ee754c2dSkamil if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 1128*ee754c2dSkamil SSIZE_T res = REAL(pwrite)(fd, ptr, count, offset); 1129*ee754c2dSkamil if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); 1130*ee754c2dSkamil return res; 1131*ee754c2dSkamil} 1132*ee754c2dSkamil#define INIT_PWRITE COMMON_INTERCEPT_FUNCTION(pwrite) 1133*ee754c2dSkamil#else 1134*ee754c2dSkamil#define INIT_PWRITE 1135*ee754c2dSkamil#endif 1136*ee754c2dSkamil 1137*ee754c2dSkamil#if SANITIZER_INTERCEPT_PWRITE64 1138*ee754c2dSkamilINTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count, 1139*ee754c2dSkamil OFF64_T offset) { 1140*ee754c2dSkamil void *ctx; 1141*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, pwrite64, fd, ptr, count, offset); 1142*ee754c2dSkamil COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 1143*ee754c2dSkamil if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 1144*ee754c2dSkamil SSIZE_T res = REAL(pwrite64)(fd, ptr, count, offset); 1145*ee754c2dSkamil if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); 1146*ee754c2dSkamil return res; 1147*ee754c2dSkamil} 1148*ee754c2dSkamil#define INIT_PWRITE64 COMMON_INTERCEPT_FUNCTION(pwrite64) 1149*ee754c2dSkamil#else 1150*ee754c2dSkamil#define INIT_PWRITE64 1151*ee754c2dSkamil#endif 1152*ee754c2dSkamil 1153*ee754c2dSkamil#if SANITIZER_INTERCEPT_WRITEV 1154*ee754c2dSkamilINTERCEPTOR_WITH_SUFFIX(SSIZE_T, writev, int fd, __sanitizer_iovec *iov, 1155*ee754c2dSkamil int iovcnt) { 1156*ee754c2dSkamil void *ctx; 1157*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, writev, fd, iov, iovcnt); 1158*ee754c2dSkamil COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 1159*ee754c2dSkamil if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 1160*ee754c2dSkamil SSIZE_T res = REAL(writev)(fd, iov, iovcnt); 1161*ee754c2dSkamil if (res > 0) read_iovec(ctx, iov, iovcnt, res); 1162*ee754c2dSkamil return res; 1163*ee754c2dSkamil} 1164*ee754c2dSkamil#define INIT_WRITEV COMMON_INTERCEPT_FUNCTION(writev) 1165*ee754c2dSkamil#else 1166*ee754c2dSkamil#define INIT_WRITEV 1167*ee754c2dSkamil#endif 1168*ee754c2dSkamil 1169*ee754c2dSkamil#if SANITIZER_INTERCEPT_PWRITEV 1170*ee754c2dSkamilINTERCEPTOR(SSIZE_T, pwritev, int fd, __sanitizer_iovec *iov, int iovcnt, 1171*ee754c2dSkamil OFF_T offset) { 1172*ee754c2dSkamil void *ctx; 1173*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, pwritev, fd, iov, iovcnt, offset); 1174*ee754c2dSkamil COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 1175*ee754c2dSkamil if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 1176*ee754c2dSkamil SSIZE_T res = REAL(pwritev)(fd, iov, iovcnt, offset); 1177*ee754c2dSkamil if (res > 0) read_iovec(ctx, iov, iovcnt, res); 1178*ee754c2dSkamil return res; 1179*ee754c2dSkamil} 1180*ee754c2dSkamil#define INIT_PWRITEV COMMON_INTERCEPT_FUNCTION(pwritev) 1181*ee754c2dSkamil#else 1182*ee754c2dSkamil#define INIT_PWRITEV 1183*ee754c2dSkamil#endif 1184*ee754c2dSkamil 1185*ee754c2dSkamil#if SANITIZER_INTERCEPT_PWRITEV64 1186*ee754c2dSkamilINTERCEPTOR(SSIZE_T, pwritev64, int fd, __sanitizer_iovec *iov, int iovcnt, 1187*ee754c2dSkamil OFF64_T offset) { 1188*ee754c2dSkamil void *ctx; 1189*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, pwritev64, fd, iov, iovcnt, offset); 1190*ee754c2dSkamil COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 1191*ee754c2dSkamil if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 1192*ee754c2dSkamil SSIZE_T res = REAL(pwritev64)(fd, iov, iovcnt, offset); 1193*ee754c2dSkamil if (res > 0) read_iovec(ctx, iov, iovcnt, res); 1194*ee754c2dSkamil return res; 1195*ee754c2dSkamil} 1196*ee754c2dSkamil#define INIT_PWRITEV64 COMMON_INTERCEPT_FUNCTION(pwritev64) 1197*ee754c2dSkamil#else 1198*ee754c2dSkamil#define INIT_PWRITEV64 1199*ee754c2dSkamil#endif 1200*ee754c2dSkamil 1201*ee754c2dSkamil#if SANITIZER_INTERCEPT_FGETS 1202*ee754c2dSkamilINTERCEPTOR(char *, fgets, char *s, SIZE_T size, void *file) { 1203*ee754c2dSkamil // libc file streams can call user-supplied functions, see fopencookie. 1204*ee754c2dSkamil void *ctx; 1205*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, fgets, s, size, file); 1206*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 1207*ee754c2dSkamil // its metadata. See 1208*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 1209*ee754c2dSkamil char *res = REAL(fgets)(s, size, file); 1210*ee754c2dSkamil if (res) 1211*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1); 1212*ee754c2dSkamil return res; 1213*ee754c2dSkamil} 1214*ee754c2dSkamil#define INIT_FGETS COMMON_INTERCEPT_FUNCTION(fgets) 1215*ee754c2dSkamil#else 1216*ee754c2dSkamil#define INIT_FGETS 1217*ee754c2dSkamil#endif 1218*ee754c2dSkamil 1219*ee754c2dSkamil#if SANITIZER_INTERCEPT_FPUTS 1220*ee754c2dSkamilINTERCEPTOR_WITH_SUFFIX(int, fputs, char *s, void *file) { 1221*ee754c2dSkamil // libc file streams can call user-supplied functions, see fopencookie. 1222*ee754c2dSkamil void *ctx; 1223*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, fputs, s, file); 1224*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1); 1225*ee754c2dSkamil return REAL(fputs)(s, file); 1226*ee754c2dSkamil} 1227*ee754c2dSkamil#define INIT_FPUTS COMMON_INTERCEPT_FUNCTION(fputs) 1228*ee754c2dSkamil#else 1229*ee754c2dSkamil#define INIT_FPUTS 1230*ee754c2dSkamil#endif 1231*ee754c2dSkamil 1232*ee754c2dSkamil#if SANITIZER_INTERCEPT_PUTS 1233*ee754c2dSkamilINTERCEPTOR(int, puts, char *s) { 1234*ee754c2dSkamil // libc file streams can call user-supplied functions, see fopencookie. 1235*ee754c2dSkamil void *ctx; 1236*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, puts, s); 1237*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1); 1238*ee754c2dSkamil return REAL(puts)(s); 1239*ee754c2dSkamil} 1240*ee754c2dSkamil#define INIT_PUTS COMMON_INTERCEPT_FUNCTION(puts) 1241*ee754c2dSkamil#else 1242*ee754c2dSkamil#define INIT_PUTS 1243*ee754c2dSkamil#endif 1244*ee754c2dSkamil 1245*ee754c2dSkamil#if SANITIZER_INTERCEPT_PRCTL 1246*ee754c2dSkamilINTERCEPTOR(int, prctl, int option, unsigned long arg2, 1247*ee754c2dSkamil unsigned long arg3, // NOLINT 1248*ee754c2dSkamil unsigned long arg4, unsigned long arg5) { // NOLINT 1249*ee754c2dSkamil void *ctx; 1250*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5); 1251*ee754c2dSkamil static const int PR_SET_NAME = 15; 1252*ee754c2dSkamil int res = REAL(prctl(option, arg2, arg3, arg4, arg5)); 1253*ee754c2dSkamil if (option == PR_SET_NAME) { 1254*ee754c2dSkamil char buff[16]; 1255*ee754c2dSkamil internal_strncpy(buff, (char *)arg2, 15); 1256*ee754c2dSkamil buff[15] = 0; 1257*ee754c2dSkamil COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff); 1258*ee754c2dSkamil } 1259*ee754c2dSkamil return res; 1260*ee754c2dSkamil} 1261*ee754c2dSkamil#define INIT_PRCTL COMMON_INTERCEPT_FUNCTION(prctl) 1262*ee754c2dSkamil#else 1263*ee754c2dSkamil#define INIT_PRCTL 1264*ee754c2dSkamil#endif // SANITIZER_INTERCEPT_PRCTL 1265*ee754c2dSkamil 1266*ee754c2dSkamil#if SANITIZER_INTERCEPT_TIME 1267*ee754c2dSkamilINTERCEPTOR(unsigned long, time, unsigned long *t) { 1268*ee754c2dSkamil void *ctx; 1269*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, time, t); 1270*ee754c2dSkamil unsigned long local_t; 1271*ee754c2dSkamil unsigned long res = REAL(time)(&local_t); 1272*ee754c2dSkamil if (t && res != (unsigned long)-1) { 1273*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, t, sizeof(*t)); 1274*ee754c2dSkamil *t = local_t; 1275*ee754c2dSkamil } 1276*ee754c2dSkamil return res; 1277*ee754c2dSkamil} 1278*ee754c2dSkamil#define INIT_TIME COMMON_INTERCEPT_FUNCTION(time); 1279*ee754c2dSkamil#else 1280*ee754c2dSkamil#define INIT_TIME 1281*ee754c2dSkamil#endif // SANITIZER_INTERCEPT_TIME 1282*ee754c2dSkamil 1283*ee754c2dSkamil#if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS 1284*ee754c2dSkamilstatic void unpoison_tm(void *ctx, __sanitizer_tm *tm) { 1285*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm)); 1286*ee754c2dSkamil#if !SANITIZER_SOLARIS 1287*ee754c2dSkamil if (tm->tm_zone) { 1288*ee754c2dSkamil // Can not use COMMON_INTERCEPTOR_WRITE_RANGE here, because tm->tm_zone 1289*ee754c2dSkamil // can point to shared memory and tsan would report a data race. 1290*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(tm->tm_zone, 1291*ee754c2dSkamil REAL(strlen(tm->tm_zone)) + 1); 1292*ee754c2dSkamil } 1293*ee754c2dSkamil#endif 1294*ee754c2dSkamil} 1295*ee754c2dSkamilINTERCEPTOR(__sanitizer_tm *, localtime, unsigned long *timep) { 1296*ee754c2dSkamil void *ctx; 1297*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep); 1298*ee754c2dSkamil __sanitizer_tm *res = REAL(localtime)(timep); 1299*ee754c2dSkamil if (res) { 1300*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 1301*ee754c2dSkamil unpoison_tm(ctx, res); 1302*ee754c2dSkamil } 1303*ee754c2dSkamil return res; 1304*ee754c2dSkamil} 1305*ee754c2dSkamilINTERCEPTOR(__sanitizer_tm *, localtime_r, unsigned long *timep, void *result) { 1306*ee754c2dSkamil void *ctx; 1307*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result); 1308*ee754c2dSkamil __sanitizer_tm *res = REAL(localtime_r)(timep, result); 1309*ee754c2dSkamil if (res) { 1310*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 1311*ee754c2dSkamil unpoison_tm(ctx, res); 1312*ee754c2dSkamil } 1313*ee754c2dSkamil return res; 1314*ee754c2dSkamil} 1315*ee754c2dSkamilINTERCEPTOR(__sanitizer_tm *, gmtime, unsigned long *timep) { 1316*ee754c2dSkamil void *ctx; 1317*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep); 1318*ee754c2dSkamil __sanitizer_tm *res = REAL(gmtime)(timep); 1319*ee754c2dSkamil if (res) { 1320*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 1321*ee754c2dSkamil unpoison_tm(ctx, res); 1322*ee754c2dSkamil } 1323*ee754c2dSkamil return res; 1324*ee754c2dSkamil} 1325*ee754c2dSkamilINTERCEPTOR(__sanitizer_tm *, gmtime_r, unsigned long *timep, void *result) { 1326*ee754c2dSkamil void *ctx; 1327*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result); 1328*ee754c2dSkamil __sanitizer_tm *res = REAL(gmtime_r)(timep, result); 1329*ee754c2dSkamil if (res) { 1330*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 1331*ee754c2dSkamil unpoison_tm(ctx, res); 1332*ee754c2dSkamil } 1333*ee754c2dSkamil return res; 1334*ee754c2dSkamil} 1335*ee754c2dSkamilINTERCEPTOR(char *, ctime, unsigned long *timep) { 1336*ee754c2dSkamil void *ctx; 1337*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep); 1338*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 1339*ee754c2dSkamil // its metadata. See 1340*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 1341*ee754c2dSkamil char *res = REAL(ctime)(timep); 1342*ee754c2dSkamil if (res) { 1343*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 1344*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1345*ee754c2dSkamil } 1346*ee754c2dSkamil return res; 1347*ee754c2dSkamil} 1348*ee754c2dSkamilINTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) { 1349*ee754c2dSkamil void *ctx; 1350*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result); 1351*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 1352*ee754c2dSkamil // its metadata. See 1353*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 1354*ee754c2dSkamil char *res = REAL(ctime_r)(timep, result); 1355*ee754c2dSkamil if (res) { 1356*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 1357*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1358*ee754c2dSkamil } 1359*ee754c2dSkamil return res; 1360*ee754c2dSkamil} 1361*ee754c2dSkamilINTERCEPTOR(char *, asctime, __sanitizer_tm *tm) { 1362*ee754c2dSkamil void *ctx; 1363*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm); 1364*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 1365*ee754c2dSkamil // its metadata. See 1366*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 1367*ee754c2dSkamil char *res = REAL(asctime)(tm); 1368*ee754c2dSkamil if (res) { 1369*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm)); 1370*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1371*ee754c2dSkamil } 1372*ee754c2dSkamil return res; 1373*ee754c2dSkamil} 1374*ee754c2dSkamilINTERCEPTOR(char *, asctime_r, __sanitizer_tm *tm, char *result) { 1375*ee754c2dSkamil void *ctx; 1376*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result); 1377*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 1378*ee754c2dSkamil // its metadata. See 1379*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 1380*ee754c2dSkamil char *res = REAL(asctime_r)(tm, result); 1381*ee754c2dSkamil if (res) { 1382*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm)); 1383*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1384*ee754c2dSkamil } 1385*ee754c2dSkamil return res; 1386*ee754c2dSkamil} 1387*ee754c2dSkamilINTERCEPTOR(long, mktime, __sanitizer_tm *tm) { 1388*ee754c2dSkamil void *ctx; 1389*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, mktime, tm); 1390*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_sec, sizeof(tm->tm_sec)); 1391*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_min, sizeof(tm->tm_min)); 1392*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_hour, sizeof(tm->tm_hour)); 1393*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_mday, sizeof(tm->tm_mday)); 1394*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_mon, sizeof(tm->tm_mon)); 1395*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_year, sizeof(tm->tm_year)); 1396*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_isdst, sizeof(tm->tm_isdst)); 1397*ee754c2dSkamil long res = REAL(mktime)(tm); 1398*ee754c2dSkamil if (res != -1) unpoison_tm(ctx, tm); 1399*ee754c2dSkamil return res; 1400*ee754c2dSkamil} 1401*ee754c2dSkamil#define INIT_LOCALTIME_AND_FRIENDS \ 1402*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(localtime); \ 1403*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(localtime_r); \ 1404*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(gmtime); \ 1405*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(gmtime_r); \ 1406*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(ctime); \ 1407*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(ctime_r); \ 1408*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(asctime); \ 1409*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(asctime_r); \ 1410*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(mktime); 1411*ee754c2dSkamil#else 1412*ee754c2dSkamil#define INIT_LOCALTIME_AND_FRIENDS 1413*ee754c2dSkamil#endif // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS 1414*ee754c2dSkamil 1415*ee754c2dSkamil#if SANITIZER_INTERCEPT_STRPTIME 1416*ee754c2dSkamilINTERCEPTOR(char *, strptime, char *s, char *format, __sanitizer_tm *tm) { 1417*ee754c2dSkamil void *ctx; 1418*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strptime, s, format, tm); 1419*ee754c2dSkamil if (format) 1420*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, format, REAL(strlen)(format) + 1); 1421*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 1422*ee754c2dSkamil // its metadata. See 1423*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 1424*ee754c2dSkamil char *res = REAL(strptime)(s, format, tm); 1425*ee754c2dSkamil COMMON_INTERCEPTOR_READ_STRING(ctx, s, res ? res - s : 0); 1426*ee754c2dSkamil if (res && tm) { 1427*ee754c2dSkamil // Do not call unpoison_tm here, because strptime does not, in fact, 1428*ee754c2dSkamil // initialize the entire struct tm. For example, tm_zone pointer is left 1429*ee754c2dSkamil // uninitialized. 1430*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm)); 1431*ee754c2dSkamil } 1432*ee754c2dSkamil return res; 1433*ee754c2dSkamil} 1434*ee754c2dSkamil#define INIT_STRPTIME COMMON_INTERCEPT_FUNCTION(strptime); 1435*ee754c2dSkamil#else 1436*ee754c2dSkamil#define INIT_STRPTIME 1437*ee754c2dSkamil#endif 1438*ee754c2dSkamil 1439*ee754c2dSkamil#if SANITIZER_INTERCEPT_SCANF || SANITIZER_INTERCEPT_PRINTF 1440*ee754c2dSkamil#include "sanitizer_common_interceptors_format.inc" 1441*ee754c2dSkamil 1442*ee754c2dSkamil#define FORMAT_INTERCEPTOR_IMPL(name, vname, ...) \ 1443*ee754c2dSkamil { \ 1444*ee754c2dSkamil void *ctx; \ 1445*ee754c2dSkamil va_list ap; \ 1446*ee754c2dSkamil va_start(ap, format); \ 1447*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__, ap); \ 1448*ee754c2dSkamil int res = WRAP(vname)(__VA_ARGS__, ap); \ 1449*ee754c2dSkamil va_end(ap); \ 1450*ee754c2dSkamil return res; \ 1451*ee754c2dSkamil } 1452*ee754c2dSkamil 1453*ee754c2dSkamil#endif 1454*ee754c2dSkamil 1455*ee754c2dSkamil#if SANITIZER_INTERCEPT_SCANF 1456*ee754c2dSkamil 1457*ee754c2dSkamil#define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...) \ 1458*ee754c2dSkamil { \ 1459*ee754c2dSkamil void *ctx; \ 1460*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__); \ 1461*ee754c2dSkamil va_list aq; \ 1462*ee754c2dSkamil va_copy(aq, ap); \ 1463*ee754c2dSkamil int res = REAL(vname)(__VA_ARGS__); \ 1464*ee754c2dSkamil if (res > 0) \ 1465*ee754c2dSkamil scanf_common(ctx, res, allowGnuMalloc, format, aq); \ 1466*ee754c2dSkamil va_end(aq); \ 1467*ee754c2dSkamil return res; \ 1468*ee754c2dSkamil } 1469*ee754c2dSkamil 1470*ee754c2dSkamilINTERCEPTOR(int, vscanf, const char *format, va_list ap) 1471*ee754c2dSkamilVSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap) 1472*ee754c2dSkamil 1473*ee754c2dSkamilINTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap) 1474*ee754c2dSkamilVSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap) 1475*ee754c2dSkamil 1476*ee754c2dSkamilINTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap) 1477*ee754c2dSkamilVSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap) 1478*ee754c2dSkamil 1479*ee754c2dSkamil#if SANITIZER_INTERCEPT_ISOC99_SCANF 1480*ee754c2dSkamilINTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap) 1481*ee754c2dSkamilVSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap) 1482*ee754c2dSkamil 1483*ee754c2dSkamilINTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format, 1484*ee754c2dSkamil va_list ap) 1485*ee754c2dSkamilVSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap) 1486*ee754c2dSkamil 1487*ee754c2dSkamilINTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap) 1488*ee754c2dSkamilVSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap) 1489*ee754c2dSkamil#endif // SANITIZER_INTERCEPT_ISOC99_SCANF 1490*ee754c2dSkamil 1491*ee754c2dSkamilINTERCEPTOR(int, scanf, const char *format, ...) 1492*ee754c2dSkamilFORMAT_INTERCEPTOR_IMPL(scanf, vscanf, format) 1493*ee754c2dSkamil 1494*ee754c2dSkamilINTERCEPTOR(int, fscanf, void *stream, const char *format, ...) 1495*ee754c2dSkamilFORMAT_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format) 1496*ee754c2dSkamil 1497*ee754c2dSkamilINTERCEPTOR(int, sscanf, const char *str, const char *format, ...) 1498*ee754c2dSkamilFORMAT_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format) 1499*ee754c2dSkamil 1500*ee754c2dSkamil#if SANITIZER_INTERCEPT_ISOC99_SCANF 1501*ee754c2dSkamilINTERCEPTOR(int, __isoc99_scanf, const char *format, ...) 1502*ee754c2dSkamilFORMAT_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format) 1503*ee754c2dSkamil 1504*ee754c2dSkamilINTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...) 1505*ee754c2dSkamilFORMAT_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format) 1506*ee754c2dSkamil 1507*ee754c2dSkamilINTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...) 1508*ee754c2dSkamilFORMAT_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format) 1509*ee754c2dSkamil#endif 1510*ee754c2dSkamil 1511*ee754c2dSkamil#endif 1512*ee754c2dSkamil 1513*ee754c2dSkamil#if SANITIZER_INTERCEPT_SCANF 1514*ee754c2dSkamil#define INIT_SCANF \ 1515*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION_LDBL(scanf); \ 1516*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION_LDBL(sscanf); \ 1517*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION_LDBL(fscanf); \ 1518*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION_LDBL(vscanf); \ 1519*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION_LDBL(vsscanf); \ 1520*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION_LDBL(vfscanf); 1521*ee754c2dSkamil#else 1522*ee754c2dSkamil#define INIT_SCANF 1523*ee754c2dSkamil#endif 1524*ee754c2dSkamil 1525*ee754c2dSkamil#if SANITIZER_INTERCEPT_ISOC99_SCANF 1526*ee754c2dSkamil#define INIT_ISOC99_SCANF \ 1527*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(__isoc99_scanf); \ 1528*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(__isoc99_sscanf); \ 1529*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(__isoc99_fscanf); \ 1530*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(__isoc99_vscanf); \ 1531*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(__isoc99_vsscanf); \ 1532*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(__isoc99_vfscanf); 1533*ee754c2dSkamil#else 1534*ee754c2dSkamil#define INIT_ISOC99_SCANF 1535*ee754c2dSkamil#endif 1536*ee754c2dSkamil 1537*ee754c2dSkamil#if SANITIZER_INTERCEPT_PRINTF 1538*ee754c2dSkamil 1539*ee754c2dSkamil#define VPRINTF_INTERCEPTOR_ENTER(vname, ...) \ 1540*ee754c2dSkamil void *ctx; \ 1541*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__); \ 1542*ee754c2dSkamil va_list aq; \ 1543*ee754c2dSkamil va_copy(aq, ap); 1544*ee754c2dSkamil 1545*ee754c2dSkamil#define VPRINTF_INTERCEPTOR_RETURN() \ 1546*ee754c2dSkamil va_end(aq); 1547*ee754c2dSkamil 1548*ee754c2dSkamil#define VPRINTF_INTERCEPTOR_IMPL(vname, ...) \ 1549*ee754c2dSkamil { \ 1550*ee754c2dSkamil VPRINTF_INTERCEPTOR_ENTER(vname, __VA_ARGS__); \ 1551*ee754c2dSkamil if (common_flags()->check_printf) \ 1552*ee754c2dSkamil printf_common(ctx, format, aq); \ 1553*ee754c2dSkamil int res = REAL(vname)(__VA_ARGS__); \ 1554*ee754c2dSkamil VPRINTF_INTERCEPTOR_RETURN(); \ 1555*ee754c2dSkamil return res; \ 1556*ee754c2dSkamil } 1557*ee754c2dSkamil 1558*ee754c2dSkamil// FIXME: under ASan the REAL() call below may write to freed memory and 1559*ee754c2dSkamil// corrupt its metadata. See 1560*ee754c2dSkamil// https://github.com/google/sanitizers/issues/321. 1561*ee754c2dSkamil#define VSPRINTF_INTERCEPTOR_IMPL(vname, str, ...) \ 1562*ee754c2dSkamil { \ 1563*ee754c2dSkamil VPRINTF_INTERCEPTOR_ENTER(vname, str, __VA_ARGS__) \ 1564*ee754c2dSkamil if (common_flags()->check_printf) { \ 1565*ee754c2dSkamil printf_common(ctx, format, aq); \ 1566*ee754c2dSkamil } \ 1567*ee754c2dSkamil int res = REAL(vname)(str, __VA_ARGS__); \ 1568*ee754c2dSkamil if (res >= 0) { \ 1569*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, res + 1); \ 1570*ee754c2dSkamil } \ 1571*ee754c2dSkamil VPRINTF_INTERCEPTOR_RETURN(); \ 1572*ee754c2dSkamil return res; \ 1573*ee754c2dSkamil } 1574*ee754c2dSkamil 1575*ee754c2dSkamil// FIXME: under ASan the REAL() call below may write to freed memory and 1576*ee754c2dSkamil// corrupt its metadata. See 1577*ee754c2dSkamil// https://github.com/google/sanitizers/issues/321. 1578*ee754c2dSkamil#define VSNPRINTF_INTERCEPTOR_IMPL(vname, str, size, ...) \ 1579*ee754c2dSkamil { \ 1580*ee754c2dSkamil VPRINTF_INTERCEPTOR_ENTER(vname, str, size, __VA_ARGS__) \ 1581*ee754c2dSkamil if (common_flags()->check_printf) { \ 1582*ee754c2dSkamil printf_common(ctx, format, aq); \ 1583*ee754c2dSkamil } \ 1584*ee754c2dSkamil int res = REAL(vname)(str, size, __VA_ARGS__); \ 1585*ee754c2dSkamil if (res >= 0) { \ 1586*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, Min(size, (SIZE_T)(res + 1))); \ 1587*ee754c2dSkamil } \ 1588*ee754c2dSkamil VPRINTF_INTERCEPTOR_RETURN(); \ 1589*ee754c2dSkamil return res; \ 1590*ee754c2dSkamil } 1591*ee754c2dSkamil 1592*ee754c2dSkamil// FIXME: under ASan the REAL() call below may write to freed memory and 1593*ee754c2dSkamil// corrupt its metadata. See 1594*ee754c2dSkamil// https://github.com/google/sanitizers/issues/321. 1595*ee754c2dSkamil#define VASPRINTF_INTERCEPTOR_IMPL(vname, strp, ...) \ 1596*ee754c2dSkamil { \ 1597*ee754c2dSkamil VPRINTF_INTERCEPTOR_ENTER(vname, strp, __VA_ARGS__) \ 1598*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, strp, sizeof(char *)); \ 1599*ee754c2dSkamil if (common_flags()->check_printf) { \ 1600*ee754c2dSkamil printf_common(ctx, format, aq); \ 1601*ee754c2dSkamil } \ 1602*ee754c2dSkamil int res = REAL(vname)(strp, __VA_ARGS__); \ 1603*ee754c2dSkamil if (res >= 0) { \ 1604*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *strp, res + 1); \ 1605*ee754c2dSkamil } \ 1606*ee754c2dSkamil VPRINTF_INTERCEPTOR_RETURN(); \ 1607*ee754c2dSkamil return res; \ 1608*ee754c2dSkamil } 1609*ee754c2dSkamil 1610*ee754c2dSkamilINTERCEPTOR(int, vprintf, const char *format, va_list ap) 1611*ee754c2dSkamilVPRINTF_INTERCEPTOR_IMPL(vprintf, format, ap) 1612*ee754c2dSkamil 1613*ee754c2dSkamilINTERCEPTOR(int, vfprintf, __sanitizer_FILE *stream, const char *format, 1614*ee754c2dSkamil va_list ap) 1615*ee754c2dSkamilVPRINTF_INTERCEPTOR_IMPL(vfprintf, stream, format, ap) 1616*ee754c2dSkamil 1617*ee754c2dSkamilINTERCEPTOR(int, vsnprintf, char *str, SIZE_T size, const char *format, 1618*ee754c2dSkamil va_list ap) 1619*ee754c2dSkamilVSNPRINTF_INTERCEPTOR_IMPL(vsnprintf, str, size, format, ap) 1620*ee754c2dSkamil 1621*ee754c2dSkamil#if SANITIZER_INTERCEPT___PRINTF_CHK 1622*ee754c2dSkamilINTERCEPTOR(int, __vsnprintf_chk, char *str, SIZE_T size, int flag, 1623*ee754c2dSkamil SIZE_T size_to, const char *format, va_list ap) 1624*ee754c2dSkamilVSNPRINTF_INTERCEPTOR_IMPL(vsnprintf, str, size, format, ap) 1625*ee754c2dSkamil#endif 1626*ee754c2dSkamil 1627*ee754c2dSkamil#if SANITIZER_INTERCEPT_PRINTF_L 1628*ee754c2dSkamilINTERCEPTOR(int, vsnprintf_l, char *str, SIZE_T size, void *loc, 1629*ee754c2dSkamil const char *format, va_list ap) 1630*ee754c2dSkamilVSNPRINTF_INTERCEPTOR_IMPL(vsnprintf_l, str, size, loc, format, ap) 1631*ee754c2dSkamil 1632*ee754c2dSkamilINTERCEPTOR(int, snprintf_l, char *str, SIZE_T size, void *loc, 1633*ee754c2dSkamil const char *format, ...) 1634*ee754c2dSkamilFORMAT_INTERCEPTOR_IMPL(snprintf_l, vsnprintf_l, str, size, loc, format) 1635*ee754c2dSkamil#endif // SANITIZER_INTERCEPT_PRINTF_L 1636*ee754c2dSkamil 1637*ee754c2dSkamilINTERCEPTOR(int, vsprintf, char *str, const char *format, va_list ap) 1638*ee754c2dSkamilVSPRINTF_INTERCEPTOR_IMPL(vsprintf, str, format, ap) 1639*ee754c2dSkamil 1640*ee754c2dSkamil#if SANITIZER_INTERCEPT___PRINTF_CHK 1641*ee754c2dSkamilINTERCEPTOR(int, __vsprintf_chk, char *str, int flag, SIZE_T size_to, 1642*ee754c2dSkamil const char *format, va_list ap) 1643*ee754c2dSkamilVSPRINTF_INTERCEPTOR_IMPL(vsprintf, str, format, ap) 1644*ee754c2dSkamil#endif 1645*ee754c2dSkamil 1646*ee754c2dSkamilINTERCEPTOR(int, vasprintf, char **strp, const char *format, va_list ap) 1647*ee754c2dSkamilVASPRINTF_INTERCEPTOR_IMPL(vasprintf, strp, format, ap) 1648*ee754c2dSkamil 1649*ee754c2dSkamil#if SANITIZER_INTERCEPT_ISOC99_PRINTF 1650*ee754c2dSkamilINTERCEPTOR(int, __isoc99_vprintf, const char *format, va_list ap) 1651*ee754c2dSkamilVPRINTF_INTERCEPTOR_IMPL(__isoc99_vprintf, format, ap) 1652*ee754c2dSkamil 1653*ee754c2dSkamilINTERCEPTOR(int, __isoc99_vfprintf, __sanitizer_FILE *stream, 1654*ee754c2dSkamil const char *format, va_list ap) 1655*ee754c2dSkamilVPRINTF_INTERCEPTOR_IMPL(__isoc99_vfprintf, stream, format, ap) 1656*ee754c2dSkamil 1657*ee754c2dSkamilINTERCEPTOR(int, __isoc99_vsnprintf, char *str, SIZE_T size, const char *format, 1658*ee754c2dSkamil va_list ap) 1659*ee754c2dSkamilVSNPRINTF_INTERCEPTOR_IMPL(__isoc99_vsnprintf, str, size, format, ap) 1660*ee754c2dSkamil 1661*ee754c2dSkamilINTERCEPTOR(int, __isoc99_vsprintf, char *str, const char *format, 1662*ee754c2dSkamil va_list ap) 1663*ee754c2dSkamilVSPRINTF_INTERCEPTOR_IMPL(__isoc99_vsprintf, str, format, 1664*ee754c2dSkamil ap) 1665*ee754c2dSkamil 1666*ee754c2dSkamil#endif // SANITIZER_INTERCEPT_ISOC99_PRINTF 1667*ee754c2dSkamil 1668*ee754c2dSkamilINTERCEPTOR(int, printf, const char *format, ...) 1669*ee754c2dSkamilFORMAT_INTERCEPTOR_IMPL(printf, vprintf, format) 1670*ee754c2dSkamil 1671*ee754c2dSkamilINTERCEPTOR(int, fprintf, __sanitizer_FILE *stream, const char *format, ...) 1672*ee754c2dSkamilFORMAT_INTERCEPTOR_IMPL(fprintf, vfprintf, stream, format) 1673*ee754c2dSkamil 1674*ee754c2dSkamil#if SANITIZER_INTERCEPT___PRINTF_CHK 1675*ee754c2dSkamilINTERCEPTOR(int, __fprintf_chk, __sanitizer_FILE *stream, SIZE_T size, 1676*ee754c2dSkamil const char *format, ...) 1677*ee754c2dSkamilFORMAT_INTERCEPTOR_IMPL(__fprintf_chk, vfprintf, stream, format) 1678*ee754c2dSkamil#endif 1679*ee754c2dSkamil 1680*ee754c2dSkamilINTERCEPTOR(int, sprintf, char *str, const char *format, ...) // NOLINT 1681*ee754c2dSkamilFORMAT_INTERCEPTOR_IMPL(sprintf, vsprintf, str, format) // NOLINT 1682*ee754c2dSkamil 1683*ee754c2dSkamil#if SANITIZER_INTERCEPT___PRINTF_CHK 1684*ee754c2dSkamilINTERCEPTOR(int, __sprintf_chk, char *str, int flag, SIZE_T size_to, 1685*ee754c2dSkamil const char *format, ...) // NOLINT 1686*ee754c2dSkamilFORMAT_INTERCEPTOR_IMPL(__sprintf_chk, vsprintf, str, format) // NOLINT 1687*ee754c2dSkamil#endif 1688*ee754c2dSkamil 1689*ee754c2dSkamilINTERCEPTOR(int, snprintf, char *str, SIZE_T size, const char *format, ...) 1690*ee754c2dSkamilFORMAT_INTERCEPTOR_IMPL(snprintf, vsnprintf, str, size, format) 1691*ee754c2dSkamil 1692*ee754c2dSkamil#if SANITIZER_INTERCEPT___PRINTF_CHK 1693*ee754c2dSkamilINTERCEPTOR(int, __snprintf_chk, char *str, SIZE_T size, int flag, 1694*ee754c2dSkamil SIZE_T size_to, const char *format, ...) // NOLINT 1695*ee754c2dSkamilFORMAT_INTERCEPTOR_IMPL(__snprintf_chk, vsnprintf, str, size, format) // NOLINT 1696*ee754c2dSkamil#endif 1697*ee754c2dSkamil 1698*ee754c2dSkamilINTERCEPTOR(int, asprintf, char **strp, const char *format, ...) 1699*ee754c2dSkamilFORMAT_INTERCEPTOR_IMPL(asprintf, vasprintf, strp, format) 1700*ee754c2dSkamil 1701*ee754c2dSkamil#if SANITIZER_INTERCEPT_ISOC99_PRINTF 1702*ee754c2dSkamilINTERCEPTOR(int, __isoc99_printf, const char *format, ...) 1703*ee754c2dSkamilFORMAT_INTERCEPTOR_IMPL(__isoc99_printf, __isoc99_vprintf, format) 1704*ee754c2dSkamil 1705*ee754c2dSkamilINTERCEPTOR(int, __isoc99_fprintf, __sanitizer_FILE *stream, const char *format, 1706*ee754c2dSkamil ...) 1707*ee754c2dSkamilFORMAT_INTERCEPTOR_IMPL(__isoc99_fprintf, __isoc99_vfprintf, stream, format) 1708*ee754c2dSkamil 1709*ee754c2dSkamilINTERCEPTOR(int, __isoc99_sprintf, char *str, const char *format, ...) 1710*ee754c2dSkamilFORMAT_INTERCEPTOR_IMPL(__isoc99_sprintf, __isoc99_vsprintf, str, format) 1711*ee754c2dSkamil 1712*ee754c2dSkamilINTERCEPTOR(int, __isoc99_snprintf, char *str, SIZE_T size, 1713*ee754c2dSkamil const char *format, ...) 1714*ee754c2dSkamilFORMAT_INTERCEPTOR_IMPL(__isoc99_snprintf, __isoc99_vsnprintf, str, size, 1715*ee754c2dSkamil format) 1716*ee754c2dSkamil 1717*ee754c2dSkamil#endif // SANITIZER_INTERCEPT_ISOC99_PRINTF 1718*ee754c2dSkamil 1719*ee754c2dSkamil#endif // SANITIZER_INTERCEPT_PRINTF 1720*ee754c2dSkamil 1721*ee754c2dSkamil#if SANITIZER_INTERCEPT_PRINTF 1722*ee754c2dSkamil#define INIT_PRINTF \ 1723*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION_LDBL(printf); \ 1724*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION_LDBL(sprintf); \ 1725*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION_LDBL(snprintf); \ 1726*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION_LDBL(asprintf); \ 1727*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION_LDBL(fprintf); \ 1728*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION_LDBL(vprintf); \ 1729*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION_LDBL(vsprintf); \ 1730*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION_LDBL(vsnprintf); \ 1731*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION_LDBL(vasprintf); \ 1732*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION_LDBL(vfprintf); 1733*ee754c2dSkamil#else 1734*ee754c2dSkamil#define INIT_PRINTF 1735*ee754c2dSkamil#endif 1736*ee754c2dSkamil 1737*ee754c2dSkamil#if SANITIZER_INTERCEPT___PRINTF_CHK 1738*ee754c2dSkamil#define INIT___PRINTF_CHK \ 1739*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(__sprintf_chk); \ 1740*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(__snprintf_chk); \ 1741*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(__vsprintf_chk); \ 1742*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(__vsnprintf_chk); \ 1743*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(__fprintf_chk); 1744*ee754c2dSkamil#else 1745*ee754c2dSkamil#define INIT___PRINTF_CHK 1746*ee754c2dSkamil#endif 1747*ee754c2dSkamil 1748*ee754c2dSkamil#if SANITIZER_INTERCEPT_PRINTF_L 1749*ee754c2dSkamil#define INIT_PRINTF_L \ 1750*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(snprintf_l); \ 1751*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(vsnprintf_l); 1752*ee754c2dSkamil#else 1753*ee754c2dSkamil#define INIT_PRINTF_L 1754*ee754c2dSkamil#endif 1755*ee754c2dSkamil 1756*ee754c2dSkamil#if SANITIZER_INTERCEPT_ISOC99_PRINTF 1757*ee754c2dSkamil#define INIT_ISOC99_PRINTF \ 1758*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(__isoc99_printf); \ 1759*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(__isoc99_sprintf); \ 1760*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(__isoc99_snprintf); \ 1761*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(__isoc99_fprintf); \ 1762*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(__isoc99_vprintf); \ 1763*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(__isoc99_vsprintf); \ 1764*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(__isoc99_vsnprintf); \ 1765*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(__isoc99_vfprintf); 1766*ee754c2dSkamil#else 1767*ee754c2dSkamil#define INIT_ISOC99_PRINTF 1768*ee754c2dSkamil#endif 1769*ee754c2dSkamil 1770*ee754c2dSkamil#if SANITIZER_INTERCEPT_IOCTL 1771*ee754c2dSkamil#include "sanitizer_common_interceptors_ioctl.inc" 1772*ee754c2dSkamil#include "sanitizer_interceptors_ioctl_netbsd.inc" 1773*ee754c2dSkamilINTERCEPTOR(int, ioctl, int d, unsigned long request, ...) { 1774*ee754c2dSkamil // We need a frame pointer, because we call into ioctl_common_[pre|post] which 1775*ee754c2dSkamil // can trigger a report and we need to be able to unwind through this 1776*ee754c2dSkamil // function. On Mac in debug mode we might not have a frame pointer, because 1777*ee754c2dSkamil // ioctl_common_[pre|post] doesn't get inlined here. 1778*ee754c2dSkamil ENABLE_FRAME_POINTER; 1779*ee754c2dSkamil 1780*ee754c2dSkamil void *ctx; 1781*ee754c2dSkamil va_list ap; 1782*ee754c2dSkamil va_start(ap, request); 1783*ee754c2dSkamil void *arg = va_arg(ap, void *); 1784*ee754c2dSkamil va_end(ap); 1785*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, ioctl, d, request, arg); 1786*ee754c2dSkamil 1787*ee754c2dSkamil CHECK(ioctl_initialized); 1788*ee754c2dSkamil 1789*ee754c2dSkamil // Note: TSan does not use common flags, and they are zero-initialized. 1790*ee754c2dSkamil // This effectively disables ioctl handling in TSan. 1791*ee754c2dSkamil if (!common_flags()->handle_ioctl) return REAL(ioctl)(d, request, arg); 1792*ee754c2dSkamil 1793*ee754c2dSkamil // Although request is unsigned long, the rest of the interceptor uses it 1794*ee754c2dSkamil // as just "unsigned" to save space, because we know that all values fit in 1795*ee754c2dSkamil // "unsigned" - they are compile-time constants. 1796*ee754c2dSkamil 1797*ee754c2dSkamil const ioctl_desc *desc = ioctl_lookup(request); 1798*ee754c2dSkamil ioctl_desc decoded_desc; 1799*ee754c2dSkamil if (!desc) { 1800*ee754c2dSkamil VPrintf(2, "Decoding unknown ioctl 0x%x\n", request); 1801*ee754c2dSkamil if (!ioctl_decode(request, &decoded_desc)) 1802*ee754c2dSkamil Printf("WARNING: failed decoding unknown ioctl 0x%x\n", request); 1803*ee754c2dSkamil else 1804*ee754c2dSkamil desc = &decoded_desc; 1805*ee754c2dSkamil } 1806*ee754c2dSkamil 1807*ee754c2dSkamil if (desc) ioctl_common_pre(ctx, desc, d, request, arg); 1808*ee754c2dSkamil int res = REAL(ioctl)(d, request, arg); 1809*ee754c2dSkamil // FIXME: some ioctls have different return values for success and failure. 1810*ee754c2dSkamil if (desc && res != -1) ioctl_common_post(ctx, desc, res, d, request, arg); 1811*ee754c2dSkamil return res; 1812*ee754c2dSkamil} 1813*ee754c2dSkamil#define INIT_IOCTL \ 1814*ee754c2dSkamil ioctl_init(); \ 1815*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(ioctl); 1816*ee754c2dSkamil#else 1817*ee754c2dSkamil#define INIT_IOCTL 1818*ee754c2dSkamil#endif 1819*ee754c2dSkamil 1820*ee754c2dSkamil#if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS || \ 1821*ee754c2dSkamil SANITIZER_INTERCEPT_GETPWENT || SANITIZER_INTERCEPT_FGETPWENT || \ 1822*ee754c2dSkamil SANITIZER_INTERCEPT_GETPWENT_R || \ 1823*ee754c2dSkamil SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS || \ 1824*ee754c2dSkamil SANITIZER_INTERCEPT_FGETPWENT_R || \ 1825*ee754c2dSkamil SANITIZER_INTERCEPT_FGETGRENT_R 1826*ee754c2dSkamilstatic void unpoison_passwd(void *ctx, __sanitizer_passwd *pwd) { 1827*ee754c2dSkamil if (pwd) { 1828*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, sizeof(*pwd)); 1829*ee754c2dSkamil if (pwd->pw_name) 1830*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_name, 1831*ee754c2dSkamil REAL(strlen)(pwd->pw_name) + 1); 1832*ee754c2dSkamil if (pwd->pw_passwd) 1833*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_passwd, 1834*ee754c2dSkamil REAL(strlen)(pwd->pw_passwd) + 1); 1835*ee754c2dSkamil#if !SANITIZER_ANDROID 1836*ee754c2dSkamil if (pwd->pw_gecos) 1837*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_gecos, 1838*ee754c2dSkamil REAL(strlen)(pwd->pw_gecos) + 1); 1839*ee754c2dSkamil#endif 1840*ee754c2dSkamil#if SANITIZER_MAC 1841*ee754c2dSkamil if (pwd->pw_class) 1842*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_class, 1843*ee754c2dSkamil REAL(strlen)(pwd->pw_class) + 1); 1844*ee754c2dSkamil#endif 1845*ee754c2dSkamil if (pwd->pw_dir) 1846*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_dir, 1847*ee754c2dSkamil REAL(strlen)(pwd->pw_dir) + 1); 1848*ee754c2dSkamil if (pwd->pw_shell) 1849*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_shell, 1850*ee754c2dSkamil REAL(strlen)(pwd->pw_shell) + 1); 1851*ee754c2dSkamil } 1852*ee754c2dSkamil} 1853*ee754c2dSkamil 1854*ee754c2dSkamilstatic void unpoison_group(void *ctx, __sanitizer_group *grp) { 1855*ee754c2dSkamil if (grp) { 1856*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, sizeof(*grp)); 1857*ee754c2dSkamil if (grp->gr_name) 1858*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(grp->gr_name, 1859*ee754c2dSkamil REAL(strlen)(grp->gr_name) + 1); 1860*ee754c2dSkamil if (grp->gr_passwd) 1861*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(grp->gr_passwd, 1862*ee754c2dSkamil REAL(strlen)(grp->gr_passwd) + 1); 1863*ee754c2dSkamil char **p = grp->gr_mem; 1864*ee754c2dSkamil for (; *p; ++p) { 1865*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(*p, REAL(strlen)(*p) + 1); 1866*ee754c2dSkamil } 1867*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(grp->gr_mem, 1868*ee754c2dSkamil (p - grp->gr_mem + 1) * sizeof(*p)); 1869*ee754c2dSkamil } 1870*ee754c2dSkamil} 1871*ee754c2dSkamil#endif // SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS || 1872*ee754c2dSkamil // SANITIZER_INTERCEPT_GETPWENT || SANITIZER_INTERCEPT_FGETPWENT || 1873*ee754c2dSkamil // SANITIZER_INTERCEPT_GETPWENT_R || 1874*ee754c2dSkamil // SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS 1875*ee754c2dSkamil 1876*ee754c2dSkamil#if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS 1877*ee754c2dSkamilINTERCEPTOR(__sanitizer_passwd *, getpwnam, const char *name) { 1878*ee754c2dSkamil void *ctx; 1879*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getpwnam, name); 1880*ee754c2dSkamil if (name) 1881*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 1882*ee754c2dSkamil __sanitizer_passwd *res = REAL(getpwnam)(name); 1883*ee754c2dSkamil if (res) unpoison_passwd(ctx, res); 1884*ee754c2dSkamil return res; 1885*ee754c2dSkamil} 1886*ee754c2dSkamilINTERCEPTOR(__sanitizer_passwd *, getpwuid, u32 uid) { 1887*ee754c2dSkamil void *ctx; 1888*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getpwuid, uid); 1889*ee754c2dSkamil __sanitizer_passwd *res = REAL(getpwuid)(uid); 1890*ee754c2dSkamil if (res) unpoison_passwd(ctx, res); 1891*ee754c2dSkamil return res; 1892*ee754c2dSkamil} 1893*ee754c2dSkamilINTERCEPTOR(__sanitizer_group *, getgrnam, const char *name) { 1894*ee754c2dSkamil void *ctx; 1895*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getgrnam, name); 1896*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 1897*ee754c2dSkamil __sanitizer_group *res = REAL(getgrnam)(name); 1898*ee754c2dSkamil if (res) unpoison_group(ctx, res); 1899*ee754c2dSkamil return res; 1900*ee754c2dSkamil} 1901*ee754c2dSkamilINTERCEPTOR(__sanitizer_group *, getgrgid, u32 gid) { 1902*ee754c2dSkamil void *ctx; 1903*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getgrgid, gid); 1904*ee754c2dSkamil __sanitizer_group *res = REAL(getgrgid)(gid); 1905*ee754c2dSkamil if (res) unpoison_group(ctx, res); 1906*ee754c2dSkamil return res; 1907*ee754c2dSkamil} 1908*ee754c2dSkamil#define INIT_GETPWNAM_AND_FRIENDS \ 1909*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(getpwnam); \ 1910*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(getpwuid); \ 1911*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(getgrnam); \ 1912*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(getgrgid); 1913*ee754c2dSkamil#else 1914*ee754c2dSkamil#define INIT_GETPWNAM_AND_FRIENDS 1915*ee754c2dSkamil#endif 1916*ee754c2dSkamil 1917*ee754c2dSkamil#if SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS 1918*ee754c2dSkamilINTERCEPTOR(int, getpwnam_r, const char *name, __sanitizer_passwd *pwd, 1919*ee754c2dSkamil char *buf, SIZE_T buflen, __sanitizer_passwd **result) { 1920*ee754c2dSkamil void *ctx; 1921*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getpwnam_r, name, pwd, buf, buflen, result); 1922*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 1923*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 1924*ee754c2dSkamil // its metadata. See 1925*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 1926*ee754c2dSkamil int res = REAL(getpwnam_r)(name, pwd, buf, buflen, result); 1927*ee754c2dSkamil if (!res) { 1928*ee754c2dSkamil if (result && *result) unpoison_passwd(ctx, *result); 1929*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 1930*ee754c2dSkamil } 1931*ee754c2dSkamil if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1932*ee754c2dSkamil return res; 1933*ee754c2dSkamil} 1934*ee754c2dSkamilINTERCEPTOR(int, getpwuid_r, u32 uid, __sanitizer_passwd *pwd, char *buf, 1935*ee754c2dSkamil SIZE_T buflen, __sanitizer_passwd **result) { 1936*ee754c2dSkamil void *ctx; 1937*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getpwuid_r, uid, pwd, buf, buflen, result); 1938*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 1939*ee754c2dSkamil // its metadata. See 1940*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 1941*ee754c2dSkamil int res = REAL(getpwuid_r)(uid, pwd, buf, buflen, result); 1942*ee754c2dSkamil if (!res) { 1943*ee754c2dSkamil if (result && *result) unpoison_passwd(ctx, *result); 1944*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 1945*ee754c2dSkamil } 1946*ee754c2dSkamil if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1947*ee754c2dSkamil return res; 1948*ee754c2dSkamil} 1949*ee754c2dSkamilINTERCEPTOR(int, getgrnam_r, const char *name, __sanitizer_group *grp, 1950*ee754c2dSkamil char *buf, SIZE_T buflen, __sanitizer_group **result) { 1951*ee754c2dSkamil void *ctx; 1952*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getgrnam_r, name, grp, buf, buflen, result); 1953*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 1954*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 1955*ee754c2dSkamil // its metadata. See 1956*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 1957*ee754c2dSkamil int res = REAL(getgrnam_r)(name, grp, buf, buflen, result); 1958*ee754c2dSkamil if (!res) { 1959*ee754c2dSkamil if (result && *result) unpoison_group(ctx, *result); 1960*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 1961*ee754c2dSkamil } 1962*ee754c2dSkamil if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1963*ee754c2dSkamil return res; 1964*ee754c2dSkamil} 1965*ee754c2dSkamilINTERCEPTOR(int, getgrgid_r, u32 gid, __sanitizer_group *grp, char *buf, 1966*ee754c2dSkamil SIZE_T buflen, __sanitizer_group **result) { 1967*ee754c2dSkamil void *ctx; 1968*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getgrgid_r, gid, grp, buf, buflen, result); 1969*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 1970*ee754c2dSkamil // its metadata. See 1971*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 1972*ee754c2dSkamil int res = REAL(getgrgid_r)(gid, grp, buf, buflen, result); 1973*ee754c2dSkamil if (!res) { 1974*ee754c2dSkamil if (result && *result) unpoison_group(ctx, *result); 1975*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 1976*ee754c2dSkamil } 1977*ee754c2dSkamil if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1978*ee754c2dSkamil return res; 1979*ee754c2dSkamil} 1980*ee754c2dSkamil#define INIT_GETPWNAM_R_AND_FRIENDS \ 1981*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(getpwnam_r); \ 1982*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(getpwuid_r); \ 1983*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(getgrnam_r); \ 1984*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(getgrgid_r); 1985*ee754c2dSkamil#else 1986*ee754c2dSkamil#define INIT_GETPWNAM_R_AND_FRIENDS 1987*ee754c2dSkamil#endif 1988*ee754c2dSkamil 1989*ee754c2dSkamil#if SANITIZER_INTERCEPT_GETPWENT 1990*ee754c2dSkamilINTERCEPTOR(__sanitizer_passwd *, getpwent, int dummy) { 1991*ee754c2dSkamil void *ctx; 1992*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getpwent, dummy); 1993*ee754c2dSkamil __sanitizer_passwd *res = REAL(getpwent)(dummy); 1994*ee754c2dSkamil if (res) unpoison_passwd(ctx, res); 1995*ee754c2dSkamil return res; 1996*ee754c2dSkamil} 1997*ee754c2dSkamilINTERCEPTOR(__sanitizer_group *, getgrent, int dummy) { 1998*ee754c2dSkamil void *ctx; 1999*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getgrent, dummy); 2000*ee754c2dSkamil __sanitizer_group *res = REAL(getgrent)(dummy); 2001*ee754c2dSkamil if (res) unpoison_group(ctx, res);; 2002*ee754c2dSkamil return res; 2003*ee754c2dSkamil} 2004*ee754c2dSkamil#define INIT_GETPWENT \ 2005*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(getpwent); \ 2006*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(getgrent); 2007*ee754c2dSkamil#else 2008*ee754c2dSkamil#define INIT_GETPWENT 2009*ee754c2dSkamil#endif 2010*ee754c2dSkamil 2011*ee754c2dSkamil#if SANITIZER_INTERCEPT_FGETPWENT 2012*ee754c2dSkamilINTERCEPTOR(__sanitizer_passwd *, fgetpwent, void *fp) { 2013*ee754c2dSkamil void *ctx; 2014*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent, fp); 2015*ee754c2dSkamil __sanitizer_passwd *res = REAL(fgetpwent)(fp); 2016*ee754c2dSkamil if (res) unpoison_passwd(ctx, res); 2017*ee754c2dSkamil return res; 2018*ee754c2dSkamil} 2019*ee754c2dSkamilINTERCEPTOR(__sanitizer_group *, fgetgrent, void *fp) { 2020*ee754c2dSkamil void *ctx; 2021*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, fgetgrent, fp); 2022*ee754c2dSkamil __sanitizer_group *res = REAL(fgetgrent)(fp); 2023*ee754c2dSkamil if (res) unpoison_group(ctx, res); 2024*ee754c2dSkamil return res; 2025*ee754c2dSkamil} 2026*ee754c2dSkamil#define INIT_FGETPWENT \ 2027*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(fgetpwent); \ 2028*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(fgetgrent); 2029*ee754c2dSkamil#else 2030*ee754c2dSkamil#define INIT_FGETPWENT 2031*ee754c2dSkamil#endif 2032*ee754c2dSkamil 2033*ee754c2dSkamil#if SANITIZER_INTERCEPT_GETPWENT_R 2034*ee754c2dSkamilINTERCEPTOR(int, getpwent_r, __sanitizer_passwd *pwbuf, char *buf, 2035*ee754c2dSkamil SIZE_T buflen, __sanitizer_passwd **pwbufp) { 2036*ee754c2dSkamil void *ctx; 2037*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getpwent_r, pwbuf, buf, buflen, pwbufp); 2038*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 2039*ee754c2dSkamil // its metadata. See 2040*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 2041*ee754c2dSkamil int res = REAL(getpwent_r)(pwbuf, buf, buflen, pwbufp); 2042*ee754c2dSkamil if (!res) { 2043*ee754c2dSkamil if (pwbufp && *pwbufp) unpoison_passwd(ctx, *pwbufp); 2044*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 2045*ee754c2dSkamil } 2046*ee754c2dSkamil if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp)); 2047*ee754c2dSkamil return res; 2048*ee754c2dSkamil} 2049*ee754c2dSkamilINTERCEPTOR(int, getgrent_r, __sanitizer_group *pwbuf, char *buf, SIZE_T buflen, 2050*ee754c2dSkamil __sanitizer_group **pwbufp) { 2051*ee754c2dSkamil void *ctx; 2052*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getgrent_r, pwbuf, buf, buflen, pwbufp); 2053*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 2054*ee754c2dSkamil // its metadata. See 2055*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 2056*ee754c2dSkamil int res = REAL(getgrent_r)(pwbuf, buf, buflen, pwbufp); 2057*ee754c2dSkamil if (!res) { 2058*ee754c2dSkamil if (pwbufp && *pwbufp) unpoison_group(ctx, *pwbufp); 2059*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 2060*ee754c2dSkamil } 2061*ee754c2dSkamil if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp)); 2062*ee754c2dSkamil return res; 2063*ee754c2dSkamil} 2064*ee754c2dSkamil#define INIT_GETPWENT_R \ 2065*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(getpwent_r); \ 2066*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(getgrent_r); 2067*ee754c2dSkamil#else 2068*ee754c2dSkamil#define INIT_GETPWENT_R 2069*ee754c2dSkamil#endif 2070*ee754c2dSkamil 2071*ee754c2dSkamil#if SANITIZER_INTERCEPT_FGETPWENT_R 2072*ee754c2dSkamilINTERCEPTOR(int, fgetpwent_r, void *fp, __sanitizer_passwd *pwbuf, char *buf, 2073*ee754c2dSkamil SIZE_T buflen, __sanitizer_passwd **pwbufp) { 2074*ee754c2dSkamil void *ctx; 2075*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent_r, fp, pwbuf, buf, buflen, pwbufp); 2076*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 2077*ee754c2dSkamil // its metadata. See 2078*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 2079*ee754c2dSkamil int res = REAL(fgetpwent_r)(fp, pwbuf, buf, buflen, pwbufp); 2080*ee754c2dSkamil if (!res) { 2081*ee754c2dSkamil if (pwbufp && *pwbufp) unpoison_passwd(ctx, *pwbufp); 2082*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 2083*ee754c2dSkamil } 2084*ee754c2dSkamil if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp)); 2085*ee754c2dSkamil return res; 2086*ee754c2dSkamil} 2087*ee754c2dSkamil#define INIT_FGETPWENT_R \ 2088*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(fgetpwent_r); 2089*ee754c2dSkamil#else 2090*ee754c2dSkamil#define INIT_FGETPWENT_R 2091*ee754c2dSkamil#endif 2092*ee754c2dSkamil 2093*ee754c2dSkamil#if SANITIZER_INTERCEPT_FGETGRENT_R 2094*ee754c2dSkamilINTERCEPTOR(int, fgetgrent_r, void *fp, __sanitizer_group *pwbuf, char *buf, 2095*ee754c2dSkamil SIZE_T buflen, __sanitizer_group **pwbufp) { 2096*ee754c2dSkamil void *ctx; 2097*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, fgetgrent_r, fp, pwbuf, buf, buflen, pwbufp); 2098*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 2099*ee754c2dSkamil // its metadata. See 2100*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 2101*ee754c2dSkamil int res = REAL(fgetgrent_r)(fp, pwbuf, buf, buflen, pwbufp); 2102*ee754c2dSkamil if (!res) { 2103*ee754c2dSkamil if (pwbufp && *pwbufp) unpoison_group(ctx, *pwbufp); 2104*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 2105*ee754c2dSkamil } 2106*ee754c2dSkamil if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp)); 2107*ee754c2dSkamil return res; 2108*ee754c2dSkamil} 2109*ee754c2dSkamil#define INIT_FGETGRENT_R \ 2110*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(fgetgrent_r); 2111*ee754c2dSkamil#else 2112*ee754c2dSkamil#define INIT_FGETGRENT_R 2113*ee754c2dSkamil#endif 2114*ee754c2dSkamil 2115*ee754c2dSkamil#if SANITIZER_INTERCEPT_SETPWENT 2116*ee754c2dSkamil// The only thing these interceptors do is disable any nested interceptors. 2117*ee754c2dSkamil// These functions may open nss modules and call uninstrumented functions from 2118*ee754c2dSkamil// them, and we don't want things like strlen() to trigger. 2119*ee754c2dSkamilINTERCEPTOR(void, setpwent, int dummy) { 2120*ee754c2dSkamil void *ctx; 2121*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, setpwent, dummy); 2122*ee754c2dSkamil REAL(setpwent)(dummy); 2123*ee754c2dSkamil} 2124*ee754c2dSkamilINTERCEPTOR(void, endpwent, int dummy) { 2125*ee754c2dSkamil void *ctx; 2126*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, endpwent, dummy); 2127*ee754c2dSkamil REAL(endpwent)(dummy); 2128*ee754c2dSkamil} 2129*ee754c2dSkamilINTERCEPTOR(void, setgrent, int dummy) { 2130*ee754c2dSkamil void *ctx; 2131*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, setgrent, dummy); 2132*ee754c2dSkamil REAL(setgrent)(dummy); 2133*ee754c2dSkamil} 2134*ee754c2dSkamilINTERCEPTOR(void, endgrent, int dummy) { 2135*ee754c2dSkamil void *ctx; 2136*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, endgrent, dummy); 2137*ee754c2dSkamil REAL(endgrent)(dummy); 2138*ee754c2dSkamil} 2139*ee754c2dSkamil#define INIT_SETPWENT \ 2140*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(setpwent); \ 2141*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(endpwent); \ 2142*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(setgrent); \ 2143*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(endgrent); 2144*ee754c2dSkamil#else 2145*ee754c2dSkamil#define INIT_SETPWENT 2146*ee754c2dSkamil#endif 2147*ee754c2dSkamil 2148*ee754c2dSkamil#if SANITIZER_INTERCEPT_CLOCK_GETTIME 2149*ee754c2dSkamilINTERCEPTOR(int, clock_getres, u32 clk_id, void *tp) { 2150*ee754c2dSkamil void *ctx; 2151*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, clock_getres, clk_id, tp); 2152*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 2153*ee754c2dSkamil // its metadata. See 2154*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 2155*ee754c2dSkamil int res = REAL(clock_getres)(clk_id, tp); 2156*ee754c2dSkamil if (!res && tp) { 2157*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz); 2158*ee754c2dSkamil } 2159*ee754c2dSkamil return res; 2160*ee754c2dSkamil} 2161*ee754c2dSkamilINTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) { 2162*ee754c2dSkamil void *ctx; 2163*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, clock_gettime, clk_id, tp); 2164*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 2165*ee754c2dSkamil // its metadata. See 2166*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 2167*ee754c2dSkamil int res = REAL(clock_gettime)(clk_id, tp); 2168*ee754c2dSkamil if (!res) { 2169*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz); 2170*ee754c2dSkamil } 2171*ee754c2dSkamil return res; 2172*ee754c2dSkamil} 2173*ee754c2dSkamilnamespace __sanitizer { 2174*ee754c2dSkamilextern "C" { 2175*ee754c2dSkamilint real_clock_gettime(u32 clk_id, void *tp) { 2176*ee754c2dSkamil if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) 2177*ee754c2dSkamil return internal_clock_gettime(clk_id, tp); 2178*ee754c2dSkamil return REAL(clock_gettime)(clk_id, tp); 2179*ee754c2dSkamil} 2180*ee754c2dSkamil} // extern "C" 2181*ee754c2dSkamil} // namespace __sanitizer 2182*ee754c2dSkamilINTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) { 2183*ee754c2dSkamil void *ctx; 2184*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, clock_settime, clk_id, tp); 2185*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, tp, struct_timespec_sz); 2186*ee754c2dSkamil return REAL(clock_settime)(clk_id, tp); 2187*ee754c2dSkamil} 2188*ee754c2dSkamil#define INIT_CLOCK_GETTIME \ 2189*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(clock_getres); \ 2190*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(clock_gettime); \ 2191*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(clock_settime); 2192*ee754c2dSkamil#else 2193*ee754c2dSkamil#define INIT_CLOCK_GETTIME 2194*ee754c2dSkamil#endif 2195*ee754c2dSkamil 2196*ee754c2dSkamil#if SANITIZER_INTERCEPT_GETITIMER 2197*ee754c2dSkamilINTERCEPTOR(int, getitimer, int which, void *curr_value) { 2198*ee754c2dSkamil void *ctx; 2199*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getitimer, which, curr_value); 2200*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 2201*ee754c2dSkamil // its metadata. See 2202*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 2203*ee754c2dSkamil int res = REAL(getitimer)(which, curr_value); 2204*ee754c2dSkamil if (!res && curr_value) { 2205*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerval_sz); 2206*ee754c2dSkamil } 2207*ee754c2dSkamil return res; 2208*ee754c2dSkamil} 2209*ee754c2dSkamilINTERCEPTOR(int, setitimer, int which, const void *new_value, void *old_value) { 2210*ee754c2dSkamil void *ctx; 2211*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, setitimer, which, new_value, old_value); 2212*ee754c2dSkamil if (new_value) { 2213*ee754c2dSkamil // itimerval can contain padding that may be legitimately uninitialized 2214*ee754c2dSkamil const struct __sanitizer_itimerval *nv = 2215*ee754c2dSkamil (const struct __sanitizer_itimerval *)new_value; 2216*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_interval.tv_sec, 2217*ee754c2dSkamil sizeof(__sanitizer_time_t)); 2218*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_interval.tv_usec, 2219*ee754c2dSkamil sizeof(__sanitizer_suseconds_t)); 2220*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_value.tv_sec, 2221*ee754c2dSkamil sizeof(__sanitizer_time_t)); 2222*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_value.tv_usec, 2223*ee754c2dSkamil sizeof(__sanitizer_suseconds_t)); 2224*ee754c2dSkamil } 2225*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 2226*ee754c2dSkamil // its metadata. See 2227*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 2228*ee754c2dSkamil int res = REAL(setitimer)(which, new_value, old_value); 2229*ee754c2dSkamil if (!res && old_value) { 2230*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerval_sz); 2231*ee754c2dSkamil } 2232*ee754c2dSkamil return res; 2233*ee754c2dSkamil} 2234*ee754c2dSkamil#define INIT_GETITIMER \ 2235*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(getitimer); \ 2236*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(setitimer); 2237*ee754c2dSkamil#else 2238*ee754c2dSkamil#define INIT_GETITIMER 2239*ee754c2dSkamil#endif 2240*ee754c2dSkamil 2241*ee754c2dSkamil#if SANITIZER_INTERCEPT_GLOB 2242*ee754c2dSkamilstatic void unpoison_glob_t(void *ctx, __sanitizer_glob_t *pglob) { 2243*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob)); 2244*ee754c2dSkamil // +1 for NULL pointer at the end. 2245*ee754c2dSkamil if (pglob->gl_pathv) 2246*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE( 2247*ee754c2dSkamil ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv)); 2248*ee754c2dSkamil for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) { 2249*ee754c2dSkamil char *p = pglob->gl_pathv[i]; 2250*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, REAL(strlen)(p) + 1); 2251*ee754c2dSkamil } 2252*ee754c2dSkamil} 2253*ee754c2dSkamil 2254*ee754c2dSkamil#if SANITIZER_SOLARIS 2255*ee754c2dSkamilINTERCEPTOR(int, glob, const char *pattern, int flags, 2256*ee754c2dSkamil int (*errfunc)(const char *epath, int eerrno), 2257*ee754c2dSkamil __sanitizer_glob_t *pglob) { 2258*ee754c2dSkamil void *ctx; 2259*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob); 2260*ee754c2dSkamil COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0); 2261*ee754c2dSkamil int res = REAL(glob)(pattern, flags, errfunc, pglob); 2262*ee754c2dSkamil if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob); 2263*ee754c2dSkamil return res; 2264*ee754c2dSkamil} 2265*ee754c2dSkamil#else 2266*ee754c2dSkamilstatic THREADLOCAL __sanitizer_glob_t *pglob_copy; 2267*ee754c2dSkamil 2268*ee754c2dSkamilstatic void wrapped_gl_closedir(void *dir) { 2269*ee754c2dSkamil COMMON_INTERCEPTOR_UNPOISON_PARAM(1); 2270*ee754c2dSkamil pglob_copy->gl_closedir(dir); 2271*ee754c2dSkamil} 2272*ee754c2dSkamil 2273*ee754c2dSkamilstatic void *wrapped_gl_readdir(void *dir) { 2274*ee754c2dSkamil COMMON_INTERCEPTOR_UNPOISON_PARAM(1); 2275*ee754c2dSkamil return pglob_copy->gl_readdir(dir); 2276*ee754c2dSkamil} 2277*ee754c2dSkamil 2278*ee754c2dSkamilstatic void *wrapped_gl_opendir(const char *s) { 2279*ee754c2dSkamil COMMON_INTERCEPTOR_UNPOISON_PARAM(1); 2280*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1); 2281*ee754c2dSkamil return pglob_copy->gl_opendir(s); 2282*ee754c2dSkamil} 2283*ee754c2dSkamil 2284*ee754c2dSkamilstatic int wrapped_gl_lstat(const char *s, void *st) { 2285*ee754c2dSkamil COMMON_INTERCEPTOR_UNPOISON_PARAM(2); 2286*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1); 2287*ee754c2dSkamil return pglob_copy->gl_lstat(s, st); 2288*ee754c2dSkamil} 2289*ee754c2dSkamil 2290*ee754c2dSkamilstatic int wrapped_gl_stat(const char *s, void *st) { 2291*ee754c2dSkamil COMMON_INTERCEPTOR_UNPOISON_PARAM(2); 2292*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1); 2293*ee754c2dSkamil return pglob_copy->gl_stat(s, st); 2294*ee754c2dSkamil} 2295*ee754c2dSkamil 2296*ee754c2dSkamilstatic const __sanitizer_glob_t kGlobCopy = { 2297*ee754c2dSkamil 0, 0, 0, 2298*ee754c2dSkamil 0, wrapped_gl_closedir, wrapped_gl_readdir, 2299*ee754c2dSkamil wrapped_gl_opendir, wrapped_gl_lstat, wrapped_gl_stat}; 2300*ee754c2dSkamil 2301*ee754c2dSkamilINTERCEPTOR(int, glob, const char *pattern, int flags, 2302*ee754c2dSkamil int (*errfunc)(const char *epath, int eerrno), 2303*ee754c2dSkamil __sanitizer_glob_t *pglob) { 2304*ee754c2dSkamil void *ctx; 2305*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob); 2306*ee754c2dSkamil COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0); 2307*ee754c2dSkamil __sanitizer_glob_t glob_copy; 2308*ee754c2dSkamil internal_memcpy(&glob_copy, &kGlobCopy, sizeof(glob_copy)); 2309*ee754c2dSkamil if (flags & glob_altdirfunc) { 2310*ee754c2dSkamil Swap(pglob->gl_closedir, glob_copy.gl_closedir); 2311*ee754c2dSkamil Swap(pglob->gl_readdir, glob_copy.gl_readdir); 2312*ee754c2dSkamil Swap(pglob->gl_opendir, glob_copy.gl_opendir); 2313*ee754c2dSkamil Swap(pglob->gl_lstat, glob_copy.gl_lstat); 2314*ee754c2dSkamil Swap(pglob->gl_stat, glob_copy.gl_stat); 2315*ee754c2dSkamil pglob_copy = &glob_copy; 2316*ee754c2dSkamil } 2317*ee754c2dSkamil int res = REAL(glob)(pattern, flags, errfunc, pglob); 2318*ee754c2dSkamil if (flags & glob_altdirfunc) { 2319*ee754c2dSkamil Swap(pglob->gl_closedir, glob_copy.gl_closedir); 2320*ee754c2dSkamil Swap(pglob->gl_readdir, glob_copy.gl_readdir); 2321*ee754c2dSkamil Swap(pglob->gl_opendir, glob_copy.gl_opendir); 2322*ee754c2dSkamil Swap(pglob->gl_lstat, glob_copy.gl_lstat); 2323*ee754c2dSkamil Swap(pglob->gl_stat, glob_copy.gl_stat); 2324*ee754c2dSkamil } 2325*ee754c2dSkamil pglob_copy = 0; 2326*ee754c2dSkamil if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob); 2327*ee754c2dSkamil return res; 2328*ee754c2dSkamil} 2329*ee754c2dSkamil#endif // SANITIZER_SOLARIS 2330*ee754c2dSkamil#define INIT_GLOB \ 2331*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(glob); 2332*ee754c2dSkamil#else // SANITIZER_INTERCEPT_GLOB 2333*ee754c2dSkamil#define INIT_GLOB 2334*ee754c2dSkamil#endif // SANITIZER_INTERCEPT_GLOB 2335*ee754c2dSkamil 2336*ee754c2dSkamil#if SANITIZER_INTERCEPT_GLOB64 2337*ee754c2dSkamilINTERCEPTOR(int, glob64, const char *pattern, int flags, 2338*ee754c2dSkamil int (*errfunc)(const char *epath, int eerrno), 2339*ee754c2dSkamil __sanitizer_glob_t *pglob) { 2340*ee754c2dSkamil void *ctx; 2341*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, glob64, pattern, flags, errfunc, pglob); 2342*ee754c2dSkamil COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0); 2343*ee754c2dSkamil __sanitizer_glob_t glob_copy; 2344*ee754c2dSkamil internal_memcpy(&glob_copy, &kGlobCopy, sizeof(glob_copy)); 2345*ee754c2dSkamil if (flags & glob_altdirfunc) { 2346*ee754c2dSkamil Swap(pglob->gl_closedir, glob_copy.gl_closedir); 2347*ee754c2dSkamil Swap(pglob->gl_readdir, glob_copy.gl_readdir); 2348*ee754c2dSkamil Swap(pglob->gl_opendir, glob_copy.gl_opendir); 2349*ee754c2dSkamil Swap(pglob->gl_lstat, glob_copy.gl_lstat); 2350*ee754c2dSkamil Swap(pglob->gl_stat, glob_copy.gl_stat); 2351*ee754c2dSkamil pglob_copy = &glob_copy; 2352*ee754c2dSkamil } 2353*ee754c2dSkamil int res = REAL(glob64)(pattern, flags, errfunc, pglob); 2354*ee754c2dSkamil if (flags & glob_altdirfunc) { 2355*ee754c2dSkamil Swap(pglob->gl_closedir, glob_copy.gl_closedir); 2356*ee754c2dSkamil Swap(pglob->gl_readdir, glob_copy.gl_readdir); 2357*ee754c2dSkamil Swap(pglob->gl_opendir, glob_copy.gl_opendir); 2358*ee754c2dSkamil Swap(pglob->gl_lstat, glob_copy.gl_lstat); 2359*ee754c2dSkamil Swap(pglob->gl_stat, glob_copy.gl_stat); 2360*ee754c2dSkamil } 2361*ee754c2dSkamil pglob_copy = 0; 2362*ee754c2dSkamil if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob); 2363*ee754c2dSkamil return res; 2364*ee754c2dSkamil} 2365*ee754c2dSkamil#define INIT_GLOB64 \ 2366*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(glob64); 2367*ee754c2dSkamil#else // SANITIZER_INTERCEPT_GLOB64 2368*ee754c2dSkamil#define INIT_GLOB64 2369*ee754c2dSkamil#endif // SANITIZER_INTERCEPT_GLOB64 2370*ee754c2dSkamil 2371*ee754c2dSkamil#if SANITIZER_INTERCEPT_WAIT 2372*ee754c2dSkamil// According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version 2373*ee754c2dSkamil// suffixes on Darwin. See the declaration of INTERCEPTOR_WITH_SUFFIX for 2374*ee754c2dSkamil// details. 2375*ee754c2dSkamilINTERCEPTOR_WITH_SUFFIX(int, wait, int *status) { 2376*ee754c2dSkamil void *ctx; 2377*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, wait, status); 2378*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 2379*ee754c2dSkamil // its metadata. See 2380*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 2381*ee754c2dSkamil int res = REAL(wait)(status); 2382*ee754c2dSkamil if (res != -1 && status) 2383*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 2384*ee754c2dSkamil return res; 2385*ee754c2dSkamil} 2386*ee754c2dSkamil// On FreeBSD id_t is always 64-bit wide. 2387*ee754c2dSkamil#if SANITIZER_FREEBSD && (SANITIZER_WORDSIZE == 32) 2388*ee754c2dSkamilINTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, long long id, void *infop, 2389*ee754c2dSkamil int options) { 2390*ee754c2dSkamil#else 2391*ee754c2dSkamilINTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, int id, void *infop, 2392*ee754c2dSkamil int options) { 2393*ee754c2dSkamil#endif 2394*ee754c2dSkamil void *ctx; 2395*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, waitid, idtype, id, infop, options); 2396*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 2397*ee754c2dSkamil // its metadata. See 2398*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 2399*ee754c2dSkamil int res = REAL(waitid)(idtype, id, infop, options); 2400*ee754c2dSkamil if (res != -1 && infop) 2401*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, infop, siginfo_t_sz); 2402*ee754c2dSkamil return res; 2403*ee754c2dSkamil} 2404*ee754c2dSkamilINTERCEPTOR_WITH_SUFFIX(int, waitpid, int pid, int *status, int options) { 2405*ee754c2dSkamil void *ctx; 2406*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, waitpid, pid, status, options); 2407*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 2408*ee754c2dSkamil // its metadata. See 2409*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 2410*ee754c2dSkamil int res = REAL(waitpid)(pid, status, options); 2411*ee754c2dSkamil if (res != -1 && status) 2412*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 2413*ee754c2dSkamil return res; 2414*ee754c2dSkamil} 2415*ee754c2dSkamilINTERCEPTOR(int, wait3, int *status, int options, void *rusage) { 2416*ee754c2dSkamil void *ctx; 2417*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, wait3, status, options, rusage); 2418*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 2419*ee754c2dSkamil // its metadata. See 2420*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 2421*ee754c2dSkamil int res = REAL(wait3)(status, options, rusage); 2422*ee754c2dSkamil if (res != -1) { 2423*ee754c2dSkamil if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 2424*ee754c2dSkamil if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz); 2425*ee754c2dSkamil } 2426*ee754c2dSkamil return res; 2427*ee754c2dSkamil} 2428*ee754c2dSkamil#if SANITIZER_ANDROID 2429*ee754c2dSkamilINTERCEPTOR(int, __wait4, int pid, int *status, int options, void *rusage) { 2430*ee754c2dSkamil void *ctx; 2431*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, __wait4, pid, status, options, rusage); 2432*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 2433*ee754c2dSkamil // its metadata. See 2434*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 2435*ee754c2dSkamil int res = REAL(__wait4)(pid, status, options, rusage); 2436*ee754c2dSkamil if (res != -1) { 2437*ee754c2dSkamil if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 2438*ee754c2dSkamil if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz); 2439*ee754c2dSkamil } 2440*ee754c2dSkamil return res; 2441*ee754c2dSkamil} 2442*ee754c2dSkamil#define INIT_WAIT4 COMMON_INTERCEPT_FUNCTION(__wait4); 2443*ee754c2dSkamil#else 2444*ee754c2dSkamilINTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) { 2445*ee754c2dSkamil void *ctx; 2446*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, wait4, pid, status, options, rusage); 2447*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 2448*ee754c2dSkamil // its metadata. See 2449*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 2450*ee754c2dSkamil int res = REAL(wait4)(pid, status, options, rusage); 2451*ee754c2dSkamil if (res != -1) { 2452*ee754c2dSkamil if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 2453*ee754c2dSkamil if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz); 2454*ee754c2dSkamil } 2455*ee754c2dSkamil return res; 2456*ee754c2dSkamil} 2457*ee754c2dSkamil#define INIT_WAIT4 COMMON_INTERCEPT_FUNCTION(wait4); 2458*ee754c2dSkamil#endif // SANITIZER_ANDROID 2459*ee754c2dSkamil#define INIT_WAIT \ 2460*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(wait); \ 2461*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(waitid); \ 2462*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(waitpid); \ 2463*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(wait3); 2464*ee754c2dSkamil#else 2465*ee754c2dSkamil#define INIT_WAIT 2466*ee754c2dSkamil#define INIT_WAIT4 2467*ee754c2dSkamil#endif 2468*ee754c2dSkamil 2469*ee754c2dSkamil#if SANITIZER_INTERCEPT_INET 2470*ee754c2dSkamilINTERCEPTOR(char *, inet_ntop, int af, const void *src, char *dst, u32 size) { 2471*ee754c2dSkamil void *ctx; 2472*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, inet_ntop, af, src, dst, size); 2473*ee754c2dSkamil uptr sz = __sanitizer_in_addr_sz(af); 2474*ee754c2dSkamil if (sz) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sz); 2475*ee754c2dSkamil // FIXME: figure out read size based on the address family. 2476*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 2477*ee754c2dSkamil // its metadata. See 2478*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 2479*ee754c2dSkamil char *res = REAL(inet_ntop)(af, src, dst, size); 2480*ee754c2dSkamil if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 2481*ee754c2dSkamil return res; 2482*ee754c2dSkamil} 2483*ee754c2dSkamilINTERCEPTOR(int, inet_pton, int af, const char *src, void *dst) { 2484*ee754c2dSkamil void *ctx; 2485*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, inet_pton, af, src, dst); 2486*ee754c2dSkamil COMMON_INTERCEPTOR_READ_STRING(ctx, src, 0); 2487*ee754c2dSkamil // FIXME: figure out read size based on the address family. 2488*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 2489*ee754c2dSkamil // its metadata. See 2490*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 2491*ee754c2dSkamil int res = REAL(inet_pton)(af, src, dst); 2492*ee754c2dSkamil if (res == 1) { 2493*ee754c2dSkamil uptr sz = __sanitizer_in_addr_sz(af); 2494*ee754c2dSkamil if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz); 2495*ee754c2dSkamil } 2496*ee754c2dSkamil return res; 2497*ee754c2dSkamil} 2498*ee754c2dSkamil#define INIT_INET \ 2499*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(inet_ntop); \ 2500*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(inet_pton); 2501*ee754c2dSkamil#else 2502*ee754c2dSkamil#define INIT_INET 2503*ee754c2dSkamil#endif 2504*ee754c2dSkamil 2505*ee754c2dSkamil#if SANITIZER_INTERCEPT_INET 2506*ee754c2dSkamilINTERCEPTOR(int, inet_aton, const char *cp, void *dst) { 2507*ee754c2dSkamil void *ctx; 2508*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, inet_aton, cp, dst); 2509*ee754c2dSkamil if (cp) COMMON_INTERCEPTOR_READ_RANGE(ctx, cp, REAL(strlen)(cp) + 1); 2510*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 2511*ee754c2dSkamil // its metadata. See 2512*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 2513*ee754c2dSkamil int res = REAL(inet_aton)(cp, dst); 2514*ee754c2dSkamil if (res != 0) { 2515*ee754c2dSkamil uptr sz = __sanitizer_in_addr_sz(af_inet); 2516*ee754c2dSkamil if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz); 2517*ee754c2dSkamil } 2518*ee754c2dSkamil return res; 2519*ee754c2dSkamil} 2520*ee754c2dSkamil#define INIT_INET_ATON COMMON_INTERCEPT_FUNCTION(inet_aton); 2521*ee754c2dSkamil#else 2522*ee754c2dSkamil#define INIT_INET_ATON 2523*ee754c2dSkamil#endif 2524*ee754c2dSkamil 2525*ee754c2dSkamil#if SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM 2526*ee754c2dSkamilINTERCEPTOR(int, pthread_getschedparam, uptr thread, int *policy, int *param) { 2527*ee754c2dSkamil void *ctx; 2528*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, pthread_getschedparam, thread, policy, param); 2529*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 2530*ee754c2dSkamil // its metadata. See 2531*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 2532*ee754c2dSkamil int res = REAL(pthread_getschedparam)(thread, policy, param); 2533*ee754c2dSkamil if (res == 0) { 2534*ee754c2dSkamil if (policy) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, policy, sizeof(*policy)); 2535*ee754c2dSkamil if (param) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, sizeof(*param)); 2536*ee754c2dSkamil } 2537*ee754c2dSkamil return res; 2538*ee754c2dSkamil} 2539*ee754c2dSkamil#define INIT_PTHREAD_GETSCHEDPARAM \ 2540*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(pthread_getschedparam); 2541*ee754c2dSkamil#else 2542*ee754c2dSkamil#define INIT_PTHREAD_GETSCHEDPARAM 2543*ee754c2dSkamil#endif 2544*ee754c2dSkamil 2545*ee754c2dSkamil#if SANITIZER_INTERCEPT_GETADDRINFO 2546*ee754c2dSkamilINTERCEPTOR(int, getaddrinfo, char *node, char *service, 2547*ee754c2dSkamil struct __sanitizer_addrinfo *hints, 2548*ee754c2dSkamil struct __sanitizer_addrinfo **out) { 2549*ee754c2dSkamil void *ctx; 2550*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getaddrinfo, node, service, hints, out); 2551*ee754c2dSkamil if (node) COMMON_INTERCEPTOR_READ_RANGE(ctx, node, REAL(strlen)(node) + 1); 2552*ee754c2dSkamil if (service) 2553*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, service, REAL(strlen)(service) + 1); 2554*ee754c2dSkamil if (hints) 2555*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, hints, sizeof(__sanitizer_addrinfo)); 2556*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 2557*ee754c2dSkamil // its metadata. See 2558*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 2559*ee754c2dSkamil int res = REAL(getaddrinfo)(node, service, hints, out); 2560*ee754c2dSkamil if (res == 0 && out) { 2561*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, out, sizeof(*out)); 2562*ee754c2dSkamil struct __sanitizer_addrinfo *p = *out; 2563*ee754c2dSkamil while (p) { 2564*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); 2565*ee754c2dSkamil if (p->ai_addr) 2566*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_addr, p->ai_addrlen); 2567*ee754c2dSkamil if (p->ai_canonname) 2568*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_canonname, 2569*ee754c2dSkamil REAL(strlen)(p->ai_canonname) + 1); 2570*ee754c2dSkamil p = p->ai_next; 2571*ee754c2dSkamil } 2572*ee754c2dSkamil } 2573*ee754c2dSkamil return res; 2574*ee754c2dSkamil} 2575*ee754c2dSkamil#define INIT_GETADDRINFO COMMON_INTERCEPT_FUNCTION(getaddrinfo); 2576*ee754c2dSkamil#else 2577*ee754c2dSkamil#define INIT_GETADDRINFO 2578*ee754c2dSkamil#endif 2579*ee754c2dSkamil 2580*ee754c2dSkamil#if SANITIZER_INTERCEPT_GETNAMEINFO 2581*ee754c2dSkamilINTERCEPTOR(int, getnameinfo, void *sockaddr, unsigned salen, char *host, 2582*ee754c2dSkamil unsigned hostlen, char *serv, unsigned servlen, int flags) { 2583*ee754c2dSkamil void *ctx; 2584*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getnameinfo, sockaddr, salen, host, hostlen, 2585*ee754c2dSkamil serv, servlen, flags); 2586*ee754c2dSkamil // FIXME: consider adding READ_RANGE(sockaddr, salen) 2587*ee754c2dSkamil // There is padding in in_addr that may make this too noisy 2588*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 2589*ee754c2dSkamil // its metadata. See 2590*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 2591*ee754c2dSkamil int res = 2592*ee754c2dSkamil REAL(getnameinfo)(sockaddr, salen, host, hostlen, serv, servlen, flags); 2593*ee754c2dSkamil if (res == 0) { 2594*ee754c2dSkamil if (host && hostlen) 2595*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, host, REAL(strlen)(host) + 1); 2596*ee754c2dSkamil if (serv && servlen) 2597*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, serv, REAL(strlen)(serv) + 1); 2598*ee754c2dSkamil } 2599*ee754c2dSkamil return res; 2600*ee754c2dSkamil} 2601*ee754c2dSkamil#define INIT_GETNAMEINFO COMMON_INTERCEPT_FUNCTION(getnameinfo); 2602*ee754c2dSkamil#else 2603*ee754c2dSkamil#define INIT_GETNAMEINFO 2604*ee754c2dSkamil#endif 2605*ee754c2dSkamil 2606*ee754c2dSkamil#if SANITIZER_INTERCEPT_GETSOCKNAME 2607*ee754c2dSkamilINTERCEPTOR(int, getsockname, int sock_fd, void *addr, int *addrlen) { 2608*ee754c2dSkamil void *ctx; 2609*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getsockname, sock_fd, addr, addrlen); 2610*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 2611*ee754c2dSkamil int addrlen_in = *addrlen; 2612*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 2613*ee754c2dSkamil // its metadata. See 2614*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 2615*ee754c2dSkamil int res = REAL(getsockname)(sock_fd, addr, addrlen); 2616*ee754c2dSkamil if (res == 0) { 2617*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addrlen_in, *addrlen)); 2618*ee754c2dSkamil } 2619*ee754c2dSkamil return res; 2620*ee754c2dSkamil} 2621*ee754c2dSkamil#define INIT_GETSOCKNAME COMMON_INTERCEPT_FUNCTION(getsockname); 2622*ee754c2dSkamil#else 2623*ee754c2dSkamil#define INIT_GETSOCKNAME 2624*ee754c2dSkamil#endif 2625*ee754c2dSkamil 2626*ee754c2dSkamil#if SANITIZER_INTERCEPT_GETHOSTBYNAME || SANITIZER_INTERCEPT_GETHOSTBYNAME_R 2627*ee754c2dSkamilstatic void write_hostent(void *ctx, struct __sanitizer_hostent *h) { 2628*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h, sizeof(__sanitizer_hostent)); 2629*ee754c2dSkamil if (h->h_name) 2630*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h->h_name, REAL(strlen)(h->h_name) + 1); 2631*ee754c2dSkamil char **p = h->h_aliases; 2632*ee754c2dSkamil while (*p) { 2633*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1); 2634*ee754c2dSkamil ++p; 2635*ee754c2dSkamil } 2636*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE( 2637*ee754c2dSkamil ctx, h->h_aliases, (p - h->h_aliases + 1) * sizeof(*h->h_aliases)); 2638*ee754c2dSkamil p = h->h_addr_list; 2639*ee754c2dSkamil while (*p) { 2640*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, h->h_length); 2641*ee754c2dSkamil ++p; 2642*ee754c2dSkamil } 2643*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE( 2644*ee754c2dSkamil ctx, h->h_addr_list, (p - h->h_addr_list + 1) * sizeof(*h->h_addr_list)); 2645*ee754c2dSkamil} 2646*ee754c2dSkamil#endif 2647*ee754c2dSkamil 2648*ee754c2dSkamil#if SANITIZER_INTERCEPT_GETHOSTBYNAME 2649*ee754c2dSkamilINTERCEPTOR(struct __sanitizer_hostent *, gethostbyname, char *name) { 2650*ee754c2dSkamil void *ctx; 2651*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname, name); 2652*ee754c2dSkamil struct __sanitizer_hostent *res = REAL(gethostbyname)(name); 2653*ee754c2dSkamil if (res) write_hostent(ctx, res); 2654*ee754c2dSkamil return res; 2655*ee754c2dSkamil} 2656*ee754c2dSkamil 2657*ee754c2dSkamilINTERCEPTOR(struct __sanitizer_hostent *, gethostbyaddr, void *addr, int len, 2658*ee754c2dSkamil int type) { 2659*ee754c2dSkamil void *ctx; 2660*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr, addr, len, type); 2661*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len); 2662*ee754c2dSkamil struct __sanitizer_hostent *res = REAL(gethostbyaddr)(addr, len, type); 2663*ee754c2dSkamil if (res) write_hostent(ctx, res); 2664*ee754c2dSkamil return res; 2665*ee754c2dSkamil} 2666*ee754c2dSkamil 2667*ee754c2dSkamilINTERCEPTOR(struct __sanitizer_hostent *, gethostent, int fake) { 2668*ee754c2dSkamil void *ctx; 2669*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, gethostent, fake); 2670*ee754c2dSkamil struct __sanitizer_hostent *res = REAL(gethostent)(fake); 2671*ee754c2dSkamil if (res) write_hostent(ctx, res); 2672*ee754c2dSkamil return res; 2673*ee754c2dSkamil} 2674*ee754c2dSkamil#define INIT_GETHOSTBYNAME \ 2675*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(gethostent); \ 2676*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(gethostbyaddr); \ 2677*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(gethostbyname); 2678*ee754c2dSkamil#else 2679*ee754c2dSkamil#define INIT_GETHOSTBYNAME 2680*ee754c2dSkamil#endif // SANITIZER_INTERCEPT_GETHOSTBYNAME 2681*ee754c2dSkamil 2682*ee754c2dSkamil#if SANITIZER_INTERCEPT_GETHOSTBYNAME2 2683*ee754c2dSkamilINTERCEPTOR(struct __sanitizer_hostent *, gethostbyname2, char *name, int af) { 2684*ee754c2dSkamil void *ctx; 2685*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2, name, af); 2686*ee754c2dSkamil struct __sanitizer_hostent *res = REAL(gethostbyname2)(name, af); 2687*ee754c2dSkamil if (res) write_hostent(ctx, res); 2688*ee754c2dSkamil return res; 2689*ee754c2dSkamil} 2690*ee754c2dSkamil#define INIT_GETHOSTBYNAME2 COMMON_INTERCEPT_FUNCTION(gethostbyname2); 2691*ee754c2dSkamil#else 2692*ee754c2dSkamil#define INIT_GETHOSTBYNAME2 2693*ee754c2dSkamil#endif // SANITIZER_INTERCEPT_GETHOSTBYNAME2 2694*ee754c2dSkamil 2695*ee754c2dSkamil#if SANITIZER_INTERCEPT_GETHOSTBYNAME_R 2696*ee754c2dSkamilINTERCEPTOR(int, gethostbyname_r, char *name, struct __sanitizer_hostent *ret, 2697*ee754c2dSkamil char *buf, SIZE_T buflen, __sanitizer_hostent **result, 2698*ee754c2dSkamil int *h_errnop) { 2699*ee754c2dSkamil void *ctx; 2700*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname_r, name, ret, buf, buflen, result, 2701*ee754c2dSkamil h_errnop); 2702*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 2703*ee754c2dSkamil // its metadata. See 2704*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 2705*ee754c2dSkamil int res = REAL(gethostbyname_r)(name, ret, buf, buflen, result, h_errnop); 2706*ee754c2dSkamil if (result) { 2707*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 2708*ee754c2dSkamil if (res == 0 && *result) write_hostent(ctx, *result); 2709*ee754c2dSkamil } 2710*ee754c2dSkamil if (h_errnop) 2711*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 2712*ee754c2dSkamil return res; 2713*ee754c2dSkamil} 2714*ee754c2dSkamil#define INIT_GETHOSTBYNAME_R COMMON_INTERCEPT_FUNCTION(gethostbyname_r); 2715*ee754c2dSkamil#else 2716*ee754c2dSkamil#define INIT_GETHOSTBYNAME_R 2717*ee754c2dSkamil#endif 2718*ee754c2dSkamil 2719*ee754c2dSkamil#if SANITIZER_INTERCEPT_GETHOSTENT_R 2720*ee754c2dSkamilINTERCEPTOR(int, gethostent_r, struct __sanitizer_hostent *ret, char *buf, 2721*ee754c2dSkamil SIZE_T buflen, __sanitizer_hostent **result, int *h_errnop) { 2722*ee754c2dSkamil void *ctx; 2723*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, gethostent_r, ret, buf, buflen, result, 2724*ee754c2dSkamil h_errnop); 2725*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 2726*ee754c2dSkamil // its metadata. See 2727*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 2728*ee754c2dSkamil int res = REAL(gethostent_r)(ret, buf, buflen, result, h_errnop); 2729*ee754c2dSkamil if (result) { 2730*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 2731*ee754c2dSkamil if (res == 0 && *result) write_hostent(ctx, *result); 2732*ee754c2dSkamil } 2733*ee754c2dSkamil if (h_errnop) 2734*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 2735*ee754c2dSkamil return res; 2736*ee754c2dSkamil} 2737*ee754c2dSkamil#define INIT_GETHOSTENT_R \ 2738*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(gethostent_r); 2739*ee754c2dSkamil#else 2740*ee754c2dSkamil#define INIT_GETHOSTENT_R 2741*ee754c2dSkamil#endif 2742*ee754c2dSkamil 2743*ee754c2dSkamil#if SANITIZER_INTERCEPT_GETHOSTBYADDR_R 2744*ee754c2dSkamilINTERCEPTOR(int, gethostbyaddr_r, void *addr, int len, int type, 2745*ee754c2dSkamil struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen, 2746*ee754c2dSkamil __sanitizer_hostent **result, int *h_errnop) { 2747*ee754c2dSkamil void *ctx; 2748*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr_r, addr, len, type, ret, buf, 2749*ee754c2dSkamil buflen, result, h_errnop); 2750*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len); 2751*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 2752*ee754c2dSkamil // its metadata. See 2753*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 2754*ee754c2dSkamil int res = REAL(gethostbyaddr_r)(addr, len, type, ret, buf, buflen, result, 2755*ee754c2dSkamil h_errnop); 2756*ee754c2dSkamil if (result) { 2757*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 2758*ee754c2dSkamil if (res == 0 && *result) write_hostent(ctx, *result); 2759*ee754c2dSkamil } 2760*ee754c2dSkamil if (h_errnop) 2761*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 2762*ee754c2dSkamil return res; 2763*ee754c2dSkamil} 2764*ee754c2dSkamil#define INIT_GETHOSTBYADDR_R \ 2765*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(gethostbyaddr_r); 2766*ee754c2dSkamil#else 2767*ee754c2dSkamil#define INIT_GETHOSTBYADDR_R 2768*ee754c2dSkamil#endif 2769*ee754c2dSkamil 2770*ee754c2dSkamil#if SANITIZER_INTERCEPT_GETHOSTBYNAME2_R 2771*ee754c2dSkamilINTERCEPTOR(int, gethostbyname2_r, char *name, int af, 2772*ee754c2dSkamil struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen, 2773*ee754c2dSkamil __sanitizer_hostent **result, int *h_errnop) { 2774*ee754c2dSkamil void *ctx; 2775*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2_r, name, af, ret, buf, buflen, 2776*ee754c2dSkamil result, h_errnop); 2777*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 2778*ee754c2dSkamil // its metadata. See 2779*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 2780*ee754c2dSkamil int res = 2781*ee754c2dSkamil REAL(gethostbyname2_r)(name, af, ret, buf, buflen, result, h_errnop); 2782*ee754c2dSkamil if (result) { 2783*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 2784*ee754c2dSkamil if (res == 0 && *result) write_hostent(ctx, *result); 2785*ee754c2dSkamil } 2786*ee754c2dSkamil if (h_errnop) 2787*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 2788*ee754c2dSkamil return res; 2789*ee754c2dSkamil} 2790*ee754c2dSkamil#define INIT_GETHOSTBYNAME2_R \ 2791*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(gethostbyname2_r); 2792*ee754c2dSkamil#else 2793*ee754c2dSkamil#define INIT_GETHOSTBYNAME2_R 2794*ee754c2dSkamil#endif 2795*ee754c2dSkamil 2796*ee754c2dSkamil#if SANITIZER_INTERCEPT_GETSOCKOPT 2797*ee754c2dSkamilINTERCEPTOR(int, getsockopt, int sockfd, int level, int optname, void *optval, 2798*ee754c2dSkamil int *optlen) { 2799*ee754c2dSkamil void *ctx; 2800*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getsockopt, sockfd, level, optname, optval, 2801*ee754c2dSkamil optlen); 2802*ee754c2dSkamil if (optlen) COMMON_INTERCEPTOR_READ_RANGE(ctx, optlen, sizeof(*optlen)); 2803*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 2804*ee754c2dSkamil // its metadata. See 2805*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 2806*ee754c2dSkamil int res = REAL(getsockopt)(sockfd, level, optname, optval, optlen); 2807*ee754c2dSkamil if (res == 0) 2808*ee754c2dSkamil if (optval && optlen) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, optval, *optlen); 2809*ee754c2dSkamil return res; 2810*ee754c2dSkamil} 2811*ee754c2dSkamil#define INIT_GETSOCKOPT COMMON_INTERCEPT_FUNCTION(getsockopt); 2812*ee754c2dSkamil#else 2813*ee754c2dSkamil#define INIT_GETSOCKOPT 2814*ee754c2dSkamil#endif 2815*ee754c2dSkamil 2816*ee754c2dSkamil#if SANITIZER_INTERCEPT_ACCEPT 2817*ee754c2dSkamilINTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) { 2818*ee754c2dSkamil void *ctx; 2819*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, accept, fd, addr, addrlen); 2820*ee754c2dSkamil unsigned addrlen0 = 0; 2821*ee754c2dSkamil if (addrlen) { 2822*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 2823*ee754c2dSkamil addrlen0 = *addrlen; 2824*ee754c2dSkamil } 2825*ee754c2dSkamil int fd2 = REAL(accept)(fd, addr, addrlen); 2826*ee754c2dSkamil if (fd2 >= 0) { 2827*ee754c2dSkamil if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2); 2828*ee754c2dSkamil if (addr && addrlen) 2829*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0)); 2830*ee754c2dSkamil } 2831*ee754c2dSkamil return fd2; 2832*ee754c2dSkamil} 2833*ee754c2dSkamil#define INIT_ACCEPT COMMON_INTERCEPT_FUNCTION(accept); 2834*ee754c2dSkamil#else 2835*ee754c2dSkamil#define INIT_ACCEPT 2836*ee754c2dSkamil#endif 2837*ee754c2dSkamil 2838*ee754c2dSkamil#if SANITIZER_INTERCEPT_ACCEPT4 2839*ee754c2dSkamilINTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) { 2840*ee754c2dSkamil void *ctx; 2841*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, accept4, fd, addr, addrlen, f); 2842*ee754c2dSkamil unsigned addrlen0 = 0; 2843*ee754c2dSkamil if (addrlen) { 2844*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 2845*ee754c2dSkamil addrlen0 = *addrlen; 2846*ee754c2dSkamil } 2847*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 2848*ee754c2dSkamil // its metadata. See 2849*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 2850*ee754c2dSkamil int fd2 = REAL(accept4)(fd, addr, addrlen, f); 2851*ee754c2dSkamil if (fd2 >= 0) { 2852*ee754c2dSkamil if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2); 2853*ee754c2dSkamil if (addr && addrlen) 2854*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0)); 2855*ee754c2dSkamil } 2856*ee754c2dSkamil return fd2; 2857*ee754c2dSkamil} 2858*ee754c2dSkamil#define INIT_ACCEPT4 COMMON_INTERCEPT_FUNCTION(accept4); 2859*ee754c2dSkamil#else 2860*ee754c2dSkamil#define INIT_ACCEPT4 2861*ee754c2dSkamil#endif 2862*ee754c2dSkamil 2863*ee754c2dSkamil#if SANITIZER_INTERCEPT_PACCEPT 2864*ee754c2dSkamilINTERCEPTOR(int, paccept, int fd, void *addr, unsigned *addrlen, 2865*ee754c2dSkamil __sanitizer_sigset_t *set, int f) { 2866*ee754c2dSkamil void *ctx; 2867*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, paccept, fd, addr, addrlen, set, f); 2868*ee754c2dSkamil unsigned addrlen0 = 0; 2869*ee754c2dSkamil if (addrlen) { 2870*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 2871*ee754c2dSkamil addrlen0 = *addrlen; 2872*ee754c2dSkamil } 2873*ee754c2dSkamil if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set)); 2874*ee754c2dSkamil int fd2 = REAL(paccept)(fd, addr, addrlen, set, f); 2875*ee754c2dSkamil if (fd2 >= 0) { 2876*ee754c2dSkamil if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2); 2877*ee754c2dSkamil if (addr && addrlen) 2878*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0)); 2879*ee754c2dSkamil } 2880*ee754c2dSkamil return fd2; 2881*ee754c2dSkamil} 2882*ee754c2dSkamil#define INIT_PACCEPT COMMON_INTERCEPT_FUNCTION(paccept); 2883*ee754c2dSkamil#else 2884*ee754c2dSkamil#define INIT_PACCEPT 2885*ee754c2dSkamil#endif 2886*ee754c2dSkamil 2887*ee754c2dSkamil#if SANITIZER_INTERCEPT_MODF 2888*ee754c2dSkamilINTERCEPTOR(double, modf, double x, double *iptr) { 2889*ee754c2dSkamil void *ctx; 2890*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, modf, x, iptr); 2891*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 2892*ee754c2dSkamil // its metadata. See 2893*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 2894*ee754c2dSkamil double res = REAL(modf)(x, iptr); 2895*ee754c2dSkamil if (iptr) { 2896*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr)); 2897*ee754c2dSkamil } 2898*ee754c2dSkamil return res; 2899*ee754c2dSkamil} 2900*ee754c2dSkamilINTERCEPTOR(float, modff, float x, float *iptr) { 2901*ee754c2dSkamil void *ctx; 2902*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, modff, x, iptr); 2903*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 2904*ee754c2dSkamil // its metadata. See 2905*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 2906*ee754c2dSkamil float res = REAL(modff)(x, iptr); 2907*ee754c2dSkamil if (iptr) { 2908*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr)); 2909*ee754c2dSkamil } 2910*ee754c2dSkamil return res; 2911*ee754c2dSkamil} 2912*ee754c2dSkamilINTERCEPTOR(long double, modfl, long double x, long double *iptr) { 2913*ee754c2dSkamil void *ctx; 2914*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, modfl, x, iptr); 2915*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 2916*ee754c2dSkamil // its metadata. See 2917*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 2918*ee754c2dSkamil long double res = REAL(modfl)(x, iptr); 2919*ee754c2dSkamil if (iptr) { 2920*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr)); 2921*ee754c2dSkamil } 2922*ee754c2dSkamil return res; 2923*ee754c2dSkamil} 2924*ee754c2dSkamil#define INIT_MODF \ 2925*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(modf); \ 2926*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(modff); \ 2927*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION_LDBL(modfl); 2928*ee754c2dSkamil#else 2929*ee754c2dSkamil#define INIT_MODF 2930*ee754c2dSkamil#endif 2931*ee754c2dSkamil 2932*ee754c2dSkamil#if SANITIZER_INTERCEPT_RECVMSG || SANITIZER_INTERCEPT_RECVMMSG 2933*ee754c2dSkamilstatic void write_msghdr(void *ctx, struct __sanitizer_msghdr *msg, 2934*ee754c2dSkamil SSIZE_T maxlen) { 2935*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg, sizeof(*msg)); 2936*ee754c2dSkamil if (msg->msg_name && msg->msg_namelen) 2937*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_name, msg->msg_namelen); 2938*ee754c2dSkamil if (msg->msg_iov && msg->msg_iovlen) 2939*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_iov, 2940*ee754c2dSkamil sizeof(*msg->msg_iov) * msg->msg_iovlen); 2941*ee754c2dSkamil write_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen); 2942*ee754c2dSkamil if (msg->msg_control && msg->msg_controllen) 2943*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_control, msg->msg_controllen); 2944*ee754c2dSkamil} 2945*ee754c2dSkamil#endif 2946*ee754c2dSkamil 2947*ee754c2dSkamil#if SANITIZER_INTERCEPT_RECVMSG 2948*ee754c2dSkamilINTERCEPTOR(SSIZE_T, recvmsg, int fd, struct __sanitizer_msghdr *msg, 2949*ee754c2dSkamil int flags) { 2950*ee754c2dSkamil void *ctx; 2951*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, recvmsg, fd, msg, flags); 2952*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 2953*ee754c2dSkamil // its metadata. See 2954*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 2955*ee754c2dSkamil SSIZE_T res = REAL(recvmsg)(fd, msg, flags); 2956*ee754c2dSkamil if (res >= 0) { 2957*ee754c2dSkamil if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 2958*ee754c2dSkamil if (msg) { 2959*ee754c2dSkamil write_msghdr(ctx, msg, res); 2960*ee754c2dSkamil COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg); 2961*ee754c2dSkamil } 2962*ee754c2dSkamil } 2963*ee754c2dSkamil return res; 2964*ee754c2dSkamil} 2965*ee754c2dSkamil#define INIT_RECVMSG COMMON_INTERCEPT_FUNCTION(recvmsg); 2966*ee754c2dSkamil#else 2967*ee754c2dSkamil#define INIT_RECVMSG 2968*ee754c2dSkamil#endif 2969*ee754c2dSkamil 2970*ee754c2dSkamil#if SANITIZER_INTERCEPT_RECVMMSG 2971*ee754c2dSkamilINTERCEPTOR(int, recvmmsg, int fd, struct __sanitizer_mmsghdr *msgvec, 2972*ee754c2dSkamil unsigned int vlen, int flags, void *timeout) { 2973*ee754c2dSkamil void *ctx; 2974*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, recvmmsg, fd, msgvec, vlen, flags, timeout); 2975*ee754c2dSkamil if (timeout) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout, struct_timespec_sz); 2976*ee754c2dSkamil int res = REAL(recvmmsg)(fd, msgvec, vlen, flags, timeout); 2977*ee754c2dSkamil if (res >= 0) { 2978*ee754c2dSkamil if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 2979*ee754c2dSkamil for (int i = 0; i < res; ++i) { 2980*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &msgvec[i].msg_len, 2981*ee754c2dSkamil sizeof(msgvec[i].msg_len)); 2982*ee754c2dSkamil write_msghdr(ctx, &msgvec[i].msg_hdr, msgvec[i].msg_len); 2983*ee754c2dSkamil COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, &msgvec[i].msg_hdr); 2984*ee754c2dSkamil } 2985*ee754c2dSkamil } 2986*ee754c2dSkamil return res; 2987*ee754c2dSkamil} 2988*ee754c2dSkamil#define INIT_RECVMMSG COMMON_INTERCEPT_FUNCTION(recvmmsg); 2989*ee754c2dSkamil#else 2990*ee754c2dSkamil#define INIT_RECVMMSG 2991*ee754c2dSkamil#endif 2992*ee754c2dSkamil 2993*ee754c2dSkamil#if SANITIZER_INTERCEPT_SENDMSG || SANITIZER_INTERCEPT_SENDMMSG 2994*ee754c2dSkamilstatic void read_msghdr_control(void *ctx, void *control, uptr controllen) { 2995*ee754c2dSkamil const unsigned kCmsgDataOffset = 2996*ee754c2dSkamil RoundUpTo(sizeof(__sanitizer_cmsghdr), sizeof(uptr)); 2997*ee754c2dSkamil 2998*ee754c2dSkamil char *p = (char *)control; 2999*ee754c2dSkamil char *const control_end = p + controllen; 3000*ee754c2dSkamil while (true) { 3001*ee754c2dSkamil if (p + sizeof(__sanitizer_cmsghdr) > control_end) break; 3002*ee754c2dSkamil __sanitizer_cmsghdr *cmsg = (__sanitizer_cmsghdr *)p; 3003*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, &cmsg->cmsg_len, sizeof(cmsg->cmsg_len)); 3004*ee754c2dSkamil 3005*ee754c2dSkamil if (p + RoundUpTo(cmsg->cmsg_len, sizeof(uptr)) > control_end) break; 3006*ee754c2dSkamil 3007*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, &cmsg->cmsg_level, 3008*ee754c2dSkamil sizeof(cmsg->cmsg_level)); 3009*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, &cmsg->cmsg_type, 3010*ee754c2dSkamil sizeof(cmsg->cmsg_type)); 3011*ee754c2dSkamil 3012*ee754c2dSkamil if (cmsg->cmsg_len > kCmsgDataOffset) { 3013*ee754c2dSkamil char *data = p + kCmsgDataOffset; 3014*ee754c2dSkamil unsigned data_len = cmsg->cmsg_len - kCmsgDataOffset; 3015*ee754c2dSkamil if (data_len > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, data, data_len); 3016*ee754c2dSkamil } 3017*ee754c2dSkamil 3018*ee754c2dSkamil p += RoundUpTo(cmsg->cmsg_len, sizeof(uptr)); 3019*ee754c2dSkamil } 3020*ee754c2dSkamil} 3021*ee754c2dSkamil 3022*ee754c2dSkamilstatic void read_msghdr(void *ctx, struct __sanitizer_msghdr *msg, 3023*ee754c2dSkamil SSIZE_T maxlen) { 3024*ee754c2dSkamil#define R(f) \ 3025*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, &msg->msg_##f, sizeof(msg->msg_##f)) 3026*ee754c2dSkamil R(name); 3027*ee754c2dSkamil R(namelen); 3028*ee754c2dSkamil R(iov); 3029*ee754c2dSkamil R(iovlen); 3030*ee754c2dSkamil R(control); 3031*ee754c2dSkamil R(controllen); 3032*ee754c2dSkamil R(flags); 3033*ee754c2dSkamil#undef R 3034*ee754c2dSkamil if (msg->msg_name && msg->msg_namelen) 3035*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, msg->msg_name, msg->msg_namelen); 3036*ee754c2dSkamil if (msg->msg_iov && msg->msg_iovlen) 3037*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, msg->msg_iov, 3038*ee754c2dSkamil sizeof(*msg->msg_iov) * msg->msg_iovlen); 3039*ee754c2dSkamil read_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen); 3040*ee754c2dSkamil if (msg->msg_control && msg->msg_controllen) 3041*ee754c2dSkamil read_msghdr_control(ctx, msg->msg_control, msg->msg_controllen); 3042*ee754c2dSkamil} 3043*ee754c2dSkamil#endif 3044*ee754c2dSkamil 3045*ee754c2dSkamil#if SANITIZER_INTERCEPT_SENDMSG 3046*ee754c2dSkamilINTERCEPTOR(SSIZE_T, sendmsg, int fd, struct __sanitizer_msghdr *msg, 3047*ee754c2dSkamil int flags) { 3048*ee754c2dSkamil void *ctx; 3049*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, sendmsg, fd, msg, flags); 3050*ee754c2dSkamil if (fd >= 0) { 3051*ee754c2dSkamil COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 3052*ee754c2dSkamil COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 3053*ee754c2dSkamil } 3054*ee754c2dSkamil SSIZE_T res = REAL(sendmsg)(fd, msg, flags); 3055*ee754c2dSkamil if (common_flags()->intercept_send && res >= 0 && msg) 3056*ee754c2dSkamil read_msghdr(ctx, msg, res); 3057*ee754c2dSkamil return res; 3058*ee754c2dSkamil} 3059*ee754c2dSkamil#define INIT_SENDMSG COMMON_INTERCEPT_FUNCTION(sendmsg); 3060*ee754c2dSkamil#else 3061*ee754c2dSkamil#define INIT_SENDMSG 3062*ee754c2dSkamil#endif 3063*ee754c2dSkamil 3064*ee754c2dSkamil#if SANITIZER_INTERCEPT_SENDMMSG 3065*ee754c2dSkamilINTERCEPTOR(int, sendmmsg, int fd, struct __sanitizer_mmsghdr *msgvec, 3066*ee754c2dSkamil unsigned vlen, int flags) { 3067*ee754c2dSkamil void *ctx; 3068*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, sendmmsg, fd, msgvec, vlen, flags); 3069*ee754c2dSkamil if (fd >= 0) { 3070*ee754c2dSkamil COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 3071*ee754c2dSkamil COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 3072*ee754c2dSkamil } 3073*ee754c2dSkamil int res = REAL(sendmmsg)(fd, msgvec, vlen, flags); 3074*ee754c2dSkamil if (res >= 0 && msgvec) 3075*ee754c2dSkamil for (int i = 0; i < res; ++i) { 3076*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &msgvec[i].msg_len, 3077*ee754c2dSkamil sizeof(msgvec[i].msg_len)); 3078*ee754c2dSkamil if (common_flags()->intercept_send) 3079*ee754c2dSkamil read_msghdr(ctx, &msgvec[i].msg_hdr, msgvec[i].msg_len); 3080*ee754c2dSkamil } 3081*ee754c2dSkamil return res; 3082*ee754c2dSkamil} 3083*ee754c2dSkamil#define INIT_SENDMMSG COMMON_INTERCEPT_FUNCTION(sendmmsg); 3084*ee754c2dSkamil#else 3085*ee754c2dSkamil#define INIT_SENDMMSG 3086*ee754c2dSkamil#endif 3087*ee754c2dSkamil 3088*ee754c2dSkamil#if SANITIZER_INTERCEPT_GETPEERNAME 3089*ee754c2dSkamilINTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) { 3090*ee754c2dSkamil void *ctx; 3091*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getpeername, sockfd, addr, addrlen); 3092*ee754c2dSkamil unsigned addr_sz; 3093*ee754c2dSkamil if (addrlen) addr_sz = *addrlen; 3094*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 3095*ee754c2dSkamil // its metadata. See 3096*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 3097*ee754c2dSkamil int res = REAL(getpeername)(sockfd, addr, addrlen); 3098*ee754c2dSkamil if (!res && addr && addrlen) 3099*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen)); 3100*ee754c2dSkamil return res; 3101*ee754c2dSkamil} 3102*ee754c2dSkamil#define INIT_GETPEERNAME COMMON_INTERCEPT_FUNCTION(getpeername); 3103*ee754c2dSkamil#else 3104*ee754c2dSkamil#define INIT_GETPEERNAME 3105*ee754c2dSkamil#endif 3106*ee754c2dSkamil 3107*ee754c2dSkamil#if SANITIZER_INTERCEPT_SYSINFO 3108*ee754c2dSkamilINTERCEPTOR(int, sysinfo, void *info) { 3109*ee754c2dSkamil void *ctx; 3110*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 3111*ee754c2dSkamil // its metadata. See 3112*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 3113*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, sysinfo, info); 3114*ee754c2dSkamil int res = REAL(sysinfo)(info); 3115*ee754c2dSkamil if (!res && info) 3116*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, struct_sysinfo_sz); 3117*ee754c2dSkamil return res; 3118*ee754c2dSkamil} 3119*ee754c2dSkamil#define INIT_SYSINFO COMMON_INTERCEPT_FUNCTION(sysinfo); 3120*ee754c2dSkamil#else 3121*ee754c2dSkamil#define INIT_SYSINFO 3122*ee754c2dSkamil#endif 3123*ee754c2dSkamil 3124*ee754c2dSkamil#if SANITIZER_INTERCEPT_READDIR 3125*ee754c2dSkamilINTERCEPTOR(__sanitizer_dirent *, opendir, const char *path) { 3126*ee754c2dSkamil void *ctx; 3127*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, opendir, path); 3128*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 3129*ee754c2dSkamil __sanitizer_dirent *res = REAL(opendir)(path); 3130*ee754c2dSkamil if (res) 3131*ee754c2dSkamil COMMON_INTERCEPTOR_DIR_ACQUIRE(ctx, path); 3132*ee754c2dSkamil return res; 3133*ee754c2dSkamil} 3134*ee754c2dSkamil 3135*ee754c2dSkamilINTERCEPTOR(__sanitizer_dirent *, readdir, void *dirp) { 3136*ee754c2dSkamil void *ctx; 3137*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, readdir, dirp); 3138*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 3139*ee754c2dSkamil // its metadata. See 3140*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 3141*ee754c2dSkamil __sanitizer_dirent *res = REAL(readdir)(dirp); 3142*ee754c2dSkamil if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen); 3143*ee754c2dSkamil return res; 3144*ee754c2dSkamil} 3145*ee754c2dSkamil 3146*ee754c2dSkamilINTERCEPTOR(int, readdir_r, void *dirp, __sanitizer_dirent *entry, 3147*ee754c2dSkamil __sanitizer_dirent **result) { 3148*ee754c2dSkamil void *ctx; 3149*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, readdir_r, dirp, entry, result); 3150*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 3151*ee754c2dSkamil // its metadata. See 3152*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 3153*ee754c2dSkamil int res = REAL(readdir_r)(dirp, entry, result); 3154*ee754c2dSkamil if (!res) { 3155*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 3156*ee754c2dSkamil if (*result) 3157*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen); 3158*ee754c2dSkamil } 3159*ee754c2dSkamil return res; 3160*ee754c2dSkamil} 3161*ee754c2dSkamil 3162*ee754c2dSkamil#define INIT_READDIR \ 3163*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(opendir); \ 3164*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(readdir); \ 3165*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(readdir_r); 3166*ee754c2dSkamil#else 3167*ee754c2dSkamil#define INIT_READDIR 3168*ee754c2dSkamil#endif 3169*ee754c2dSkamil 3170*ee754c2dSkamil#if SANITIZER_INTERCEPT_READDIR64 3171*ee754c2dSkamilINTERCEPTOR(__sanitizer_dirent64 *, readdir64, void *dirp) { 3172*ee754c2dSkamil void *ctx; 3173*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, readdir64, dirp); 3174*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 3175*ee754c2dSkamil // its metadata. See 3176*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 3177*ee754c2dSkamil __sanitizer_dirent64 *res = REAL(readdir64)(dirp); 3178*ee754c2dSkamil if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen); 3179*ee754c2dSkamil return res; 3180*ee754c2dSkamil} 3181*ee754c2dSkamil 3182*ee754c2dSkamilINTERCEPTOR(int, readdir64_r, void *dirp, __sanitizer_dirent64 *entry, 3183*ee754c2dSkamil __sanitizer_dirent64 **result) { 3184*ee754c2dSkamil void *ctx; 3185*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, readdir64_r, dirp, entry, result); 3186*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 3187*ee754c2dSkamil // its metadata. See 3188*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 3189*ee754c2dSkamil int res = REAL(readdir64_r)(dirp, entry, result); 3190*ee754c2dSkamil if (!res) { 3191*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 3192*ee754c2dSkamil if (*result) 3193*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen); 3194*ee754c2dSkamil } 3195*ee754c2dSkamil return res; 3196*ee754c2dSkamil} 3197*ee754c2dSkamil#define INIT_READDIR64 \ 3198*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(readdir64); \ 3199*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(readdir64_r); 3200*ee754c2dSkamil#else 3201*ee754c2dSkamil#define INIT_READDIR64 3202*ee754c2dSkamil#endif 3203*ee754c2dSkamil 3204*ee754c2dSkamil#if SANITIZER_INTERCEPT_PTRACE 3205*ee754c2dSkamilINTERCEPTOR(uptr, ptrace, int request, int pid, void *addr, void *data) { 3206*ee754c2dSkamil void *ctx; 3207*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, ptrace, request, pid, addr, data); 3208*ee754c2dSkamil __sanitizer_iovec local_iovec; 3209*ee754c2dSkamil 3210*ee754c2dSkamil if (data) { 3211*ee754c2dSkamil if (request == ptrace_setregs) 3212*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_regs_struct_sz); 3213*ee754c2dSkamil else if (request == ptrace_setfpregs) 3214*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpregs_struct_sz); 3215*ee754c2dSkamil else if (request == ptrace_setfpxregs) 3216*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpxregs_struct_sz); 3217*ee754c2dSkamil else if (request == ptrace_setvfpregs) 3218*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_vfpregs_struct_sz); 3219*ee754c2dSkamil else if (request == ptrace_setsiginfo) 3220*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, data, siginfo_t_sz); 3221*ee754c2dSkamil // Some kernel might zero the iovec::iov_base in case of invalid 3222*ee754c2dSkamil // write access. In this case copy the invalid address for further 3223*ee754c2dSkamil // inspection. 3224*ee754c2dSkamil else if (request == ptrace_setregset || request == ptrace_getregset) { 3225*ee754c2dSkamil __sanitizer_iovec *iovec = (__sanitizer_iovec*)data; 3226*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec)); 3227*ee754c2dSkamil local_iovec = *iovec; 3228*ee754c2dSkamil if (request == ptrace_setregset) 3229*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec->iov_base, iovec->iov_len); 3230*ee754c2dSkamil } 3231*ee754c2dSkamil } 3232*ee754c2dSkamil 3233*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 3234*ee754c2dSkamil // its metadata. See 3235*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 3236*ee754c2dSkamil uptr res = REAL(ptrace)(request, pid, addr, data); 3237*ee754c2dSkamil 3238*ee754c2dSkamil if (!res && data) { 3239*ee754c2dSkamil // Note that PEEK* requests assign different meaning to the return value. 3240*ee754c2dSkamil // This function does not handle them (nor does it need to). 3241*ee754c2dSkamil if (request == ptrace_getregs) 3242*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_regs_struct_sz); 3243*ee754c2dSkamil else if (request == ptrace_getfpregs) 3244*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpregs_struct_sz); 3245*ee754c2dSkamil else if (request == ptrace_getfpxregs) 3246*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpxregs_struct_sz); 3247*ee754c2dSkamil else if (request == ptrace_getvfpregs) 3248*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_vfpregs_struct_sz); 3249*ee754c2dSkamil else if (request == ptrace_getsiginfo) 3250*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, siginfo_t_sz); 3251*ee754c2dSkamil else if (request == ptrace_geteventmsg) 3252*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, sizeof(unsigned long)); 3253*ee754c2dSkamil else if (request == ptrace_getregset) { 3254*ee754c2dSkamil __sanitizer_iovec *iovec = (__sanitizer_iovec*)data; 3255*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec, sizeof(*iovec)); 3256*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, local_iovec.iov_base, 3257*ee754c2dSkamil local_iovec.iov_len); 3258*ee754c2dSkamil } 3259*ee754c2dSkamil } 3260*ee754c2dSkamil return res; 3261*ee754c2dSkamil} 3262*ee754c2dSkamil 3263*ee754c2dSkamil#define INIT_PTRACE COMMON_INTERCEPT_FUNCTION(ptrace); 3264*ee754c2dSkamil#else 3265*ee754c2dSkamil#define INIT_PTRACE 3266*ee754c2dSkamil#endif 3267*ee754c2dSkamil 3268*ee754c2dSkamil#if SANITIZER_INTERCEPT_SETLOCALE 3269*ee754c2dSkamilstatic void unpoison_ctype_arrays(void *ctx) { 3270*ee754c2dSkamil#if SANITIZER_NETBSD 3271*ee754c2dSkamil // These arrays contain 256 regular elements in unsigned char range + 1 EOF 3272*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, _ctype_tab_, 257 * sizeof(short)); 3273*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, _toupper_tab_, 257 * sizeof(short)); 3274*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, _tolower_tab_, 257 * sizeof(short)); 3275*ee754c2dSkamil#endif 3276*ee754c2dSkamil} 3277*ee754c2dSkamil 3278*ee754c2dSkamilINTERCEPTOR(char *, setlocale, int category, char *locale) { 3279*ee754c2dSkamil void *ctx; 3280*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, setlocale, category, locale); 3281*ee754c2dSkamil if (locale) 3282*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, locale, REAL(strlen)(locale) + 1); 3283*ee754c2dSkamil char *res = REAL(setlocale)(category, locale); 3284*ee754c2dSkamil if (res) { 3285*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 3286*ee754c2dSkamil unpoison_ctype_arrays(ctx); 3287*ee754c2dSkamil } 3288*ee754c2dSkamil return res; 3289*ee754c2dSkamil} 3290*ee754c2dSkamil 3291*ee754c2dSkamil#define INIT_SETLOCALE COMMON_INTERCEPT_FUNCTION(setlocale); 3292*ee754c2dSkamil#else 3293*ee754c2dSkamil#define INIT_SETLOCALE 3294*ee754c2dSkamil#endif 3295*ee754c2dSkamil 3296*ee754c2dSkamil#if SANITIZER_INTERCEPT_GETCWD 3297*ee754c2dSkamilINTERCEPTOR(char *, getcwd, char *buf, SIZE_T size) { 3298*ee754c2dSkamil void *ctx; 3299*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getcwd, buf, size); 3300*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 3301*ee754c2dSkamil // its metadata. See 3302*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 3303*ee754c2dSkamil char *res = REAL(getcwd)(buf, size); 3304*ee754c2dSkamil if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 3305*ee754c2dSkamil return res; 3306*ee754c2dSkamil} 3307*ee754c2dSkamil#define INIT_GETCWD COMMON_INTERCEPT_FUNCTION(getcwd); 3308*ee754c2dSkamil#else 3309*ee754c2dSkamil#define INIT_GETCWD 3310*ee754c2dSkamil#endif 3311*ee754c2dSkamil 3312*ee754c2dSkamil#if SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME 3313*ee754c2dSkamilINTERCEPTOR(char *, get_current_dir_name, int fake) { 3314*ee754c2dSkamil void *ctx; 3315*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, get_current_dir_name, fake); 3316*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 3317*ee754c2dSkamil // its metadata. See 3318*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 3319*ee754c2dSkamil char *res = REAL(get_current_dir_name)(fake); 3320*ee754c2dSkamil if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 3321*ee754c2dSkamil return res; 3322*ee754c2dSkamil} 3323*ee754c2dSkamil 3324*ee754c2dSkamil#define INIT_GET_CURRENT_DIR_NAME \ 3325*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(get_current_dir_name); 3326*ee754c2dSkamil#else 3327*ee754c2dSkamil#define INIT_GET_CURRENT_DIR_NAME 3328*ee754c2dSkamil#endif 3329*ee754c2dSkamil 3330*ee754c2dSkamilUNUSED static inline void FixRealStrtolEndptr(const char *nptr, char **endptr) { 3331*ee754c2dSkamil CHECK(endptr); 3332*ee754c2dSkamil if (nptr == *endptr) { 3333*ee754c2dSkamil // No digits were found at strtol call, we need to find out the last 3334*ee754c2dSkamil // symbol accessed by strtoll on our own. 3335*ee754c2dSkamil // We get this symbol by skipping leading blanks and optional +/- sign. 3336*ee754c2dSkamil while (IsSpace(*nptr)) nptr++; 3337*ee754c2dSkamil if (*nptr == '+' || *nptr == '-') nptr++; 3338*ee754c2dSkamil *endptr = const_cast<char *>(nptr); 3339*ee754c2dSkamil } 3340*ee754c2dSkamil CHECK(*endptr >= nptr); 3341*ee754c2dSkamil} 3342*ee754c2dSkamil 3343*ee754c2dSkamilUNUSED static inline void StrtolFixAndCheck(void *ctx, const char *nptr, 3344*ee754c2dSkamil char **endptr, char *real_endptr, int base) { 3345*ee754c2dSkamil if (endptr) { 3346*ee754c2dSkamil *endptr = real_endptr; 3347*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr)); 3348*ee754c2dSkamil } 3349*ee754c2dSkamil // If base has unsupported value, strtol can exit with EINVAL 3350*ee754c2dSkamil // without reading any characters. So do additional checks only 3351*ee754c2dSkamil // if base is valid. 3352*ee754c2dSkamil bool is_valid_base = (base == 0) || (2 <= base && base <= 36); 3353*ee754c2dSkamil if (is_valid_base) { 3354*ee754c2dSkamil FixRealStrtolEndptr(nptr, &real_endptr); 3355*ee754c2dSkamil } 3356*ee754c2dSkamil COMMON_INTERCEPTOR_READ_STRING(ctx, nptr, is_valid_base ? 3357*ee754c2dSkamil (real_endptr - nptr) + 1 : 0); 3358*ee754c2dSkamil} 3359*ee754c2dSkamil 3360*ee754c2dSkamil 3361*ee754c2dSkamil#if SANITIZER_INTERCEPT_STRTOIMAX 3362*ee754c2dSkamilINTERCEPTOR(INTMAX_T, strtoimax, const char *nptr, char **endptr, int base) { 3363*ee754c2dSkamil void *ctx; 3364*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strtoimax, nptr, endptr, base); 3365*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 3366*ee754c2dSkamil // its metadata. See 3367*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 3368*ee754c2dSkamil char *real_endptr; 3369*ee754c2dSkamil INTMAX_T res = REAL(strtoimax)(nptr, &real_endptr, base); 3370*ee754c2dSkamil StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base); 3371*ee754c2dSkamil return res; 3372*ee754c2dSkamil} 3373*ee754c2dSkamil 3374*ee754c2dSkamilINTERCEPTOR(UINTMAX_T, strtoumax, const char *nptr, char **endptr, int base) { 3375*ee754c2dSkamil void *ctx; 3376*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strtoumax, nptr, endptr, base); 3377*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 3378*ee754c2dSkamil // its metadata. See 3379*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 3380*ee754c2dSkamil char *real_endptr; 3381*ee754c2dSkamil UINTMAX_T res = REAL(strtoumax)(nptr, &real_endptr, base); 3382*ee754c2dSkamil StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base); 3383*ee754c2dSkamil return res; 3384*ee754c2dSkamil} 3385*ee754c2dSkamil 3386*ee754c2dSkamil#define INIT_STRTOIMAX \ 3387*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(strtoimax); \ 3388*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(strtoumax); 3389*ee754c2dSkamil#else 3390*ee754c2dSkamil#define INIT_STRTOIMAX 3391*ee754c2dSkamil#endif 3392*ee754c2dSkamil 3393*ee754c2dSkamil#if SANITIZER_INTERCEPT_MBSTOWCS 3394*ee754c2dSkamilINTERCEPTOR(SIZE_T, mbstowcs, wchar_t *dest, const char *src, SIZE_T len) { 3395*ee754c2dSkamil void *ctx; 3396*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, mbstowcs, dest, src, len); 3397*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 3398*ee754c2dSkamil // its metadata. See 3399*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 3400*ee754c2dSkamil SIZE_T res = REAL(mbstowcs)(dest, src, len); 3401*ee754c2dSkamil if (res != (SIZE_T) - 1 && dest) { 3402*ee754c2dSkamil SIZE_T write_cnt = res + (res < len); 3403*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t)); 3404*ee754c2dSkamil } 3405*ee754c2dSkamil return res; 3406*ee754c2dSkamil} 3407*ee754c2dSkamil 3408*ee754c2dSkamilINTERCEPTOR(SIZE_T, mbsrtowcs, wchar_t *dest, const char **src, SIZE_T len, 3409*ee754c2dSkamil void *ps) { 3410*ee754c2dSkamil void *ctx; 3411*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, mbsrtowcs, dest, src, len, ps); 3412*ee754c2dSkamil if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 3413*ee754c2dSkamil if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 3414*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 3415*ee754c2dSkamil // its metadata. See 3416*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 3417*ee754c2dSkamil SIZE_T res = REAL(mbsrtowcs)(dest, src, len, ps); 3418*ee754c2dSkamil if (res != (SIZE_T)(-1) && dest && src) { 3419*ee754c2dSkamil // This function, and several others, may or may not write the terminating 3420*ee754c2dSkamil // \0 character. They write it iff they clear *src. 3421*ee754c2dSkamil SIZE_T write_cnt = res + !*src; 3422*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t)); 3423*ee754c2dSkamil } 3424*ee754c2dSkamil return res; 3425*ee754c2dSkamil} 3426*ee754c2dSkamil 3427*ee754c2dSkamil#define INIT_MBSTOWCS \ 3428*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(mbstowcs); \ 3429*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(mbsrtowcs); 3430*ee754c2dSkamil#else 3431*ee754c2dSkamil#define INIT_MBSTOWCS 3432*ee754c2dSkamil#endif 3433*ee754c2dSkamil 3434*ee754c2dSkamil#if SANITIZER_INTERCEPT_MBSNRTOWCS 3435*ee754c2dSkamilINTERCEPTOR(SIZE_T, mbsnrtowcs, wchar_t *dest, const char **src, SIZE_T nms, 3436*ee754c2dSkamil SIZE_T len, void *ps) { 3437*ee754c2dSkamil void *ctx; 3438*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, mbsnrtowcs, dest, src, nms, len, ps); 3439*ee754c2dSkamil if (src) { 3440*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 3441*ee754c2dSkamil if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms); 3442*ee754c2dSkamil } 3443*ee754c2dSkamil if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 3444*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 3445*ee754c2dSkamil // its metadata. See 3446*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 3447*ee754c2dSkamil SIZE_T res = REAL(mbsnrtowcs)(dest, src, nms, len, ps); 3448*ee754c2dSkamil if (res != (SIZE_T)(-1) && dest && src) { 3449*ee754c2dSkamil SIZE_T write_cnt = res + !*src; 3450*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t)); 3451*ee754c2dSkamil } 3452*ee754c2dSkamil return res; 3453*ee754c2dSkamil} 3454*ee754c2dSkamil 3455*ee754c2dSkamil#define INIT_MBSNRTOWCS COMMON_INTERCEPT_FUNCTION(mbsnrtowcs); 3456*ee754c2dSkamil#else 3457*ee754c2dSkamil#define INIT_MBSNRTOWCS 3458*ee754c2dSkamil#endif 3459*ee754c2dSkamil 3460*ee754c2dSkamil#if SANITIZER_INTERCEPT_WCSTOMBS 3461*ee754c2dSkamilINTERCEPTOR(SIZE_T, wcstombs, char *dest, const wchar_t *src, SIZE_T len) { 3462*ee754c2dSkamil void *ctx; 3463*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, wcstombs, dest, src, len); 3464*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 3465*ee754c2dSkamil // its metadata. See 3466*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 3467*ee754c2dSkamil SIZE_T res = REAL(wcstombs)(dest, src, len); 3468*ee754c2dSkamil if (res != (SIZE_T) - 1 && dest) { 3469*ee754c2dSkamil SIZE_T write_cnt = res + (res < len); 3470*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt); 3471*ee754c2dSkamil } 3472*ee754c2dSkamil return res; 3473*ee754c2dSkamil} 3474*ee754c2dSkamil 3475*ee754c2dSkamilINTERCEPTOR(SIZE_T, wcsrtombs, char *dest, const wchar_t **src, SIZE_T len, 3476*ee754c2dSkamil void *ps) { 3477*ee754c2dSkamil void *ctx; 3478*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, wcsrtombs, dest, src, len, ps); 3479*ee754c2dSkamil if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 3480*ee754c2dSkamil if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 3481*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 3482*ee754c2dSkamil // its metadata. See 3483*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 3484*ee754c2dSkamil SIZE_T res = REAL(wcsrtombs)(dest, src, len, ps); 3485*ee754c2dSkamil if (res != (SIZE_T) - 1 && dest && src) { 3486*ee754c2dSkamil SIZE_T write_cnt = res + !*src; 3487*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt); 3488*ee754c2dSkamil } 3489*ee754c2dSkamil return res; 3490*ee754c2dSkamil} 3491*ee754c2dSkamil 3492*ee754c2dSkamil#define INIT_WCSTOMBS \ 3493*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(wcstombs); \ 3494*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(wcsrtombs); 3495*ee754c2dSkamil#else 3496*ee754c2dSkamil#define INIT_WCSTOMBS 3497*ee754c2dSkamil#endif 3498*ee754c2dSkamil 3499*ee754c2dSkamil#if SANITIZER_INTERCEPT_WCSNRTOMBS 3500*ee754c2dSkamilINTERCEPTOR(SIZE_T, wcsnrtombs, char *dest, const wchar_t **src, SIZE_T nms, 3501*ee754c2dSkamil SIZE_T len, void *ps) { 3502*ee754c2dSkamil void *ctx; 3503*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, wcsnrtombs, dest, src, nms, len, ps); 3504*ee754c2dSkamil if (src) { 3505*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 3506*ee754c2dSkamil if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms); 3507*ee754c2dSkamil } 3508*ee754c2dSkamil if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 3509*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 3510*ee754c2dSkamil // its metadata. See 3511*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 3512*ee754c2dSkamil SIZE_T res = REAL(wcsnrtombs)(dest, src, nms, len, ps); 3513*ee754c2dSkamil if (res != ((SIZE_T)-1) && dest && src) { 3514*ee754c2dSkamil SIZE_T write_cnt = res + !*src; 3515*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt); 3516*ee754c2dSkamil } 3517*ee754c2dSkamil return res; 3518*ee754c2dSkamil} 3519*ee754c2dSkamil 3520*ee754c2dSkamil#define INIT_WCSNRTOMBS COMMON_INTERCEPT_FUNCTION(wcsnrtombs); 3521*ee754c2dSkamil#else 3522*ee754c2dSkamil#define INIT_WCSNRTOMBS 3523*ee754c2dSkamil#endif 3524*ee754c2dSkamil 3525*ee754c2dSkamil 3526*ee754c2dSkamil#if SANITIZER_INTERCEPT_WCRTOMB 3527*ee754c2dSkamilINTERCEPTOR(SIZE_T, wcrtomb, char *dest, wchar_t src, void *ps) { 3528*ee754c2dSkamil void *ctx; 3529*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, wcrtomb, dest, src, ps); 3530*ee754c2dSkamil if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 3531*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 3532*ee754c2dSkamil // its metadata. See 3533*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 3534*ee754c2dSkamil SIZE_T res = REAL(wcrtomb)(dest, src, ps); 3535*ee754c2dSkamil if (res != ((SIZE_T)-1) && dest) { 3536*ee754c2dSkamil SIZE_T write_cnt = res; 3537*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt); 3538*ee754c2dSkamil } 3539*ee754c2dSkamil return res; 3540*ee754c2dSkamil} 3541*ee754c2dSkamil 3542*ee754c2dSkamil#define INIT_WCRTOMB COMMON_INTERCEPT_FUNCTION(wcrtomb); 3543*ee754c2dSkamil#else 3544*ee754c2dSkamil#define INIT_WCRTOMB 3545*ee754c2dSkamil#endif 3546*ee754c2dSkamil 3547*ee754c2dSkamil#if SANITIZER_INTERCEPT_TCGETATTR 3548*ee754c2dSkamilINTERCEPTOR(int, tcgetattr, int fd, void *termios_p) { 3549*ee754c2dSkamil void *ctx; 3550*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, tcgetattr, fd, termios_p); 3551*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 3552*ee754c2dSkamil // its metadata. See 3553*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 3554*ee754c2dSkamil int res = REAL(tcgetattr)(fd, termios_p); 3555*ee754c2dSkamil if (!res && termios_p) 3556*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, termios_p, struct_termios_sz); 3557*ee754c2dSkamil return res; 3558*ee754c2dSkamil} 3559*ee754c2dSkamil 3560*ee754c2dSkamil#define INIT_TCGETATTR COMMON_INTERCEPT_FUNCTION(tcgetattr); 3561*ee754c2dSkamil#else 3562*ee754c2dSkamil#define INIT_TCGETATTR 3563*ee754c2dSkamil#endif 3564*ee754c2dSkamil 3565*ee754c2dSkamil#if SANITIZER_INTERCEPT_REALPATH 3566*ee754c2dSkamilINTERCEPTOR(char *, realpath, const char *path, char *resolved_path) { 3567*ee754c2dSkamil void *ctx; 3568*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, realpath, path, resolved_path); 3569*ee754c2dSkamil if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 3570*ee754c2dSkamil 3571*ee754c2dSkamil // Workaround a bug in glibc where dlsym(RTLD_NEXT, ...) returns the oldest 3572*ee754c2dSkamil // version of a versioned symbol. For realpath(), this gives us something 3573*ee754c2dSkamil // (called __old_realpath) that does not handle NULL in the second argument. 3574*ee754c2dSkamil // Handle it as part of the interceptor. 3575*ee754c2dSkamil char *allocated_path = nullptr; 3576*ee754c2dSkamil if (!resolved_path) 3577*ee754c2dSkamil allocated_path = resolved_path = (char *)WRAP(malloc)(path_max + 1); 3578*ee754c2dSkamil 3579*ee754c2dSkamil char *res = REAL(realpath)(path, resolved_path); 3580*ee754c2dSkamil if (allocated_path && !res) WRAP(free)(allocated_path); 3581*ee754c2dSkamil if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 3582*ee754c2dSkamil return res; 3583*ee754c2dSkamil} 3584*ee754c2dSkamil#define INIT_REALPATH COMMON_INTERCEPT_FUNCTION(realpath); 3585*ee754c2dSkamil#else 3586*ee754c2dSkamil#define INIT_REALPATH 3587*ee754c2dSkamil#endif 3588*ee754c2dSkamil 3589*ee754c2dSkamil#if SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME 3590*ee754c2dSkamilINTERCEPTOR(char *, canonicalize_file_name, const char *path) { 3591*ee754c2dSkamil void *ctx; 3592*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, canonicalize_file_name, path); 3593*ee754c2dSkamil if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 3594*ee754c2dSkamil char *res = REAL(canonicalize_file_name)(path); 3595*ee754c2dSkamil if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 3596*ee754c2dSkamil return res; 3597*ee754c2dSkamil} 3598*ee754c2dSkamil#define INIT_CANONICALIZE_FILE_NAME \ 3599*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(canonicalize_file_name); 3600*ee754c2dSkamil#else 3601*ee754c2dSkamil#define INIT_CANONICALIZE_FILE_NAME 3602*ee754c2dSkamil#endif 3603*ee754c2dSkamil 3604*ee754c2dSkamil#if SANITIZER_INTERCEPT_CONFSTR 3605*ee754c2dSkamilINTERCEPTOR(SIZE_T, confstr, int name, char *buf, SIZE_T len) { 3606*ee754c2dSkamil void *ctx; 3607*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, confstr, name, buf, len); 3608*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 3609*ee754c2dSkamil // its metadata. See 3610*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 3611*ee754c2dSkamil SIZE_T res = REAL(confstr)(name, buf, len); 3612*ee754c2dSkamil if (buf && res) 3613*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res < len ? res : len); 3614*ee754c2dSkamil return res; 3615*ee754c2dSkamil} 3616*ee754c2dSkamil#define INIT_CONFSTR COMMON_INTERCEPT_FUNCTION(confstr); 3617*ee754c2dSkamil#else 3618*ee754c2dSkamil#define INIT_CONFSTR 3619*ee754c2dSkamil#endif 3620*ee754c2dSkamil 3621*ee754c2dSkamil#if SANITIZER_INTERCEPT_SCHED_GETAFFINITY 3622*ee754c2dSkamilINTERCEPTOR(int, sched_getaffinity, int pid, SIZE_T cpusetsize, void *mask) { 3623*ee754c2dSkamil void *ctx; 3624*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, sched_getaffinity, pid, cpusetsize, mask); 3625*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 3626*ee754c2dSkamil // its metadata. See 3627*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 3628*ee754c2dSkamil int res = REAL(sched_getaffinity)(pid, cpusetsize, mask); 3629*ee754c2dSkamil if (mask && !res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mask, cpusetsize); 3630*ee754c2dSkamil return res; 3631*ee754c2dSkamil} 3632*ee754c2dSkamil#define INIT_SCHED_GETAFFINITY COMMON_INTERCEPT_FUNCTION(sched_getaffinity); 3633*ee754c2dSkamil#else 3634*ee754c2dSkamil#define INIT_SCHED_GETAFFINITY 3635*ee754c2dSkamil#endif 3636*ee754c2dSkamil 3637*ee754c2dSkamil#if SANITIZER_INTERCEPT_SCHED_GETPARAM 3638*ee754c2dSkamilINTERCEPTOR(int, sched_getparam, int pid, void *param) { 3639*ee754c2dSkamil void *ctx; 3640*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, sched_getparam, pid, param); 3641*ee754c2dSkamil int res = REAL(sched_getparam)(pid, param); 3642*ee754c2dSkamil if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, struct_sched_param_sz); 3643*ee754c2dSkamil return res; 3644*ee754c2dSkamil} 3645*ee754c2dSkamil#define INIT_SCHED_GETPARAM COMMON_INTERCEPT_FUNCTION(sched_getparam); 3646*ee754c2dSkamil#else 3647*ee754c2dSkamil#define INIT_SCHED_GETPARAM 3648*ee754c2dSkamil#endif 3649*ee754c2dSkamil 3650*ee754c2dSkamil#if SANITIZER_INTERCEPT_STRERROR 3651*ee754c2dSkamilINTERCEPTOR(char *, strerror, int errnum) { 3652*ee754c2dSkamil void *ctx; 3653*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strerror, errnum); 3654*ee754c2dSkamil char *res = REAL(strerror)(errnum); 3655*ee754c2dSkamil if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1); 3656*ee754c2dSkamil return res; 3657*ee754c2dSkamil} 3658*ee754c2dSkamil#define INIT_STRERROR COMMON_INTERCEPT_FUNCTION(strerror); 3659*ee754c2dSkamil#else 3660*ee754c2dSkamil#define INIT_STRERROR 3661*ee754c2dSkamil#endif 3662*ee754c2dSkamil 3663*ee754c2dSkamil#if SANITIZER_INTERCEPT_STRERROR_R 3664*ee754c2dSkamil// There are 2 versions of strerror_r: 3665*ee754c2dSkamil// * POSIX version returns 0 on success, negative error code on failure, 3666*ee754c2dSkamil// writes message to buf. 3667*ee754c2dSkamil// * GNU version returns message pointer, which points to either buf or some 3668*ee754c2dSkamil// static storage. 3669*ee754c2dSkamil#if ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE) || \ 3670*ee754c2dSkamil SANITIZER_MAC || SANITIZER_ANDROID || SANITIZER_NETBSD || \ 3671*ee754c2dSkamil SANITIZER_FREEBSD || SANITIZER_OPENBSD 3672*ee754c2dSkamil// POSIX version. Spec is not clear on whether buf is NULL-terminated. 3673*ee754c2dSkamil// At least on OSX, buf contents are valid even when the call fails. 3674*ee754c2dSkamilINTERCEPTOR(int, strerror_r, int errnum, char *buf, SIZE_T buflen) { 3675*ee754c2dSkamil void *ctx; 3676*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strerror_r, errnum, buf, buflen); 3677*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 3678*ee754c2dSkamil // its metadata. See 3679*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 3680*ee754c2dSkamil int res = REAL(strerror_r)(errnum, buf, buflen); 3681*ee754c2dSkamil 3682*ee754c2dSkamil SIZE_T sz = internal_strnlen(buf, buflen); 3683*ee754c2dSkamil if (sz < buflen) ++sz; 3684*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz); 3685*ee754c2dSkamil return res; 3686*ee754c2dSkamil} 3687*ee754c2dSkamil#else 3688*ee754c2dSkamil// GNU version. 3689*ee754c2dSkamilINTERCEPTOR(char *, strerror_r, int errnum, char *buf, SIZE_T buflen) { 3690*ee754c2dSkamil void *ctx; 3691*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strerror_r, errnum, buf, buflen); 3692*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 3693*ee754c2dSkamil // its metadata. See 3694*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 3695*ee754c2dSkamil char *res = REAL(strerror_r)(errnum, buf, buflen); 3696*ee754c2dSkamil if (res == buf) 3697*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 3698*ee754c2dSkamil else 3699*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1); 3700*ee754c2dSkamil return res; 3701*ee754c2dSkamil} 3702*ee754c2dSkamil#endif //(_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE || 3703*ee754c2dSkamil //SANITIZER_MAC 3704*ee754c2dSkamil#define INIT_STRERROR_R COMMON_INTERCEPT_FUNCTION(strerror_r); 3705*ee754c2dSkamil#else 3706*ee754c2dSkamil#define INIT_STRERROR_R 3707*ee754c2dSkamil#endif 3708*ee754c2dSkamil 3709*ee754c2dSkamil#if SANITIZER_INTERCEPT_XPG_STRERROR_R 3710*ee754c2dSkamilINTERCEPTOR(int, __xpg_strerror_r, int errnum, char *buf, SIZE_T buflen) { 3711*ee754c2dSkamil void *ctx; 3712*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, __xpg_strerror_r, errnum, buf, buflen); 3713*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 3714*ee754c2dSkamil // its metadata. See 3715*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 3716*ee754c2dSkamil int res = REAL(__xpg_strerror_r)(errnum, buf, buflen); 3717*ee754c2dSkamil // This version always returns a null-terminated string. 3718*ee754c2dSkamil if (buf && buflen) 3719*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, REAL(strlen)(buf) + 1); 3720*ee754c2dSkamil return res; 3721*ee754c2dSkamil} 3722*ee754c2dSkamil#define INIT_XPG_STRERROR_R COMMON_INTERCEPT_FUNCTION(__xpg_strerror_r); 3723*ee754c2dSkamil#else 3724*ee754c2dSkamil#define INIT_XPG_STRERROR_R 3725*ee754c2dSkamil#endif 3726*ee754c2dSkamil 3727*ee754c2dSkamil#if SANITIZER_INTERCEPT_SCANDIR 3728*ee754c2dSkamiltypedef int (*scandir_filter_f)(const struct __sanitizer_dirent *); 3729*ee754c2dSkamiltypedef int (*scandir_compar_f)(const struct __sanitizer_dirent **, 3730*ee754c2dSkamil const struct __sanitizer_dirent **); 3731*ee754c2dSkamil 3732*ee754c2dSkamilstatic THREADLOCAL scandir_filter_f scandir_filter; 3733*ee754c2dSkamilstatic THREADLOCAL scandir_compar_f scandir_compar; 3734*ee754c2dSkamil 3735*ee754c2dSkamilstatic int wrapped_scandir_filter(const struct __sanitizer_dirent *dir) { 3736*ee754c2dSkamil COMMON_INTERCEPTOR_UNPOISON_PARAM(1); 3737*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(dir, dir->d_reclen); 3738*ee754c2dSkamil return scandir_filter(dir); 3739*ee754c2dSkamil} 3740*ee754c2dSkamil 3741*ee754c2dSkamilstatic int wrapped_scandir_compar(const struct __sanitizer_dirent **a, 3742*ee754c2dSkamil const struct __sanitizer_dirent **b) { 3743*ee754c2dSkamil COMMON_INTERCEPTOR_UNPOISON_PARAM(2); 3744*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, sizeof(*a)); 3745*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(*a, (*a)->d_reclen); 3746*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, sizeof(*b)); 3747*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(*b, (*b)->d_reclen); 3748*ee754c2dSkamil return scandir_compar(a, b); 3749*ee754c2dSkamil} 3750*ee754c2dSkamil 3751*ee754c2dSkamilINTERCEPTOR(int, scandir, char *dirp, __sanitizer_dirent ***namelist, 3752*ee754c2dSkamil scandir_filter_f filter, scandir_compar_f compar) { 3753*ee754c2dSkamil void *ctx; 3754*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, scandir, dirp, namelist, filter, compar); 3755*ee754c2dSkamil if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1); 3756*ee754c2dSkamil scandir_filter = filter; 3757*ee754c2dSkamil scandir_compar = compar; 3758*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 3759*ee754c2dSkamil // its metadata. See 3760*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 3761*ee754c2dSkamil int res = REAL(scandir)(dirp, namelist, 3762*ee754c2dSkamil filter ? wrapped_scandir_filter : nullptr, 3763*ee754c2dSkamil compar ? wrapped_scandir_compar : nullptr); 3764*ee754c2dSkamil scandir_filter = nullptr; 3765*ee754c2dSkamil scandir_compar = nullptr; 3766*ee754c2dSkamil if (namelist && res > 0) { 3767*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist)); 3768*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res); 3769*ee754c2dSkamil for (int i = 0; i < res; ++i) 3770*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i], 3771*ee754c2dSkamil (*namelist)[i]->d_reclen); 3772*ee754c2dSkamil } 3773*ee754c2dSkamil return res; 3774*ee754c2dSkamil} 3775*ee754c2dSkamil#define INIT_SCANDIR COMMON_INTERCEPT_FUNCTION(scandir); 3776*ee754c2dSkamil#else 3777*ee754c2dSkamil#define INIT_SCANDIR 3778*ee754c2dSkamil#endif 3779*ee754c2dSkamil 3780*ee754c2dSkamil#if SANITIZER_INTERCEPT_SCANDIR64 3781*ee754c2dSkamiltypedef int (*scandir64_filter_f)(const struct __sanitizer_dirent64 *); 3782*ee754c2dSkamiltypedef int (*scandir64_compar_f)(const struct __sanitizer_dirent64 **, 3783*ee754c2dSkamil const struct __sanitizer_dirent64 **); 3784*ee754c2dSkamil 3785*ee754c2dSkamilstatic THREADLOCAL scandir64_filter_f scandir64_filter; 3786*ee754c2dSkamilstatic THREADLOCAL scandir64_compar_f scandir64_compar; 3787*ee754c2dSkamil 3788*ee754c2dSkamilstatic int wrapped_scandir64_filter(const struct __sanitizer_dirent64 *dir) { 3789*ee754c2dSkamil COMMON_INTERCEPTOR_UNPOISON_PARAM(1); 3790*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(dir, dir->d_reclen); 3791*ee754c2dSkamil return scandir64_filter(dir); 3792*ee754c2dSkamil} 3793*ee754c2dSkamil 3794*ee754c2dSkamilstatic int wrapped_scandir64_compar(const struct __sanitizer_dirent64 **a, 3795*ee754c2dSkamil const struct __sanitizer_dirent64 **b) { 3796*ee754c2dSkamil COMMON_INTERCEPTOR_UNPOISON_PARAM(2); 3797*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, sizeof(*a)); 3798*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(*a, (*a)->d_reclen); 3799*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, sizeof(*b)); 3800*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(*b, (*b)->d_reclen); 3801*ee754c2dSkamil return scandir64_compar(a, b); 3802*ee754c2dSkamil} 3803*ee754c2dSkamil 3804*ee754c2dSkamilINTERCEPTOR(int, scandir64, char *dirp, __sanitizer_dirent64 ***namelist, 3805*ee754c2dSkamil scandir64_filter_f filter, scandir64_compar_f compar) { 3806*ee754c2dSkamil void *ctx; 3807*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, scandir64, dirp, namelist, filter, compar); 3808*ee754c2dSkamil if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1); 3809*ee754c2dSkamil scandir64_filter = filter; 3810*ee754c2dSkamil scandir64_compar = compar; 3811*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 3812*ee754c2dSkamil // its metadata. See 3813*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 3814*ee754c2dSkamil int res = 3815*ee754c2dSkamil REAL(scandir64)(dirp, namelist, 3816*ee754c2dSkamil filter ? wrapped_scandir64_filter : nullptr, 3817*ee754c2dSkamil compar ? wrapped_scandir64_compar : nullptr); 3818*ee754c2dSkamil scandir64_filter = nullptr; 3819*ee754c2dSkamil scandir64_compar = nullptr; 3820*ee754c2dSkamil if (namelist && res > 0) { 3821*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist)); 3822*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res); 3823*ee754c2dSkamil for (int i = 0; i < res; ++i) 3824*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i], 3825*ee754c2dSkamil (*namelist)[i]->d_reclen); 3826*ee754c2dSkamil } 3827*ee754c2dSkamil return res; 3828*ee754c2dSkamil} 3829*ee754c2dSkamil#define INIT_SCANDIR64 COMMON_INTERCEPT_FUNCTION(scandir64); 3830*ee754c2dSkamil#else 3831*ee754c2dSkamil#define INIT_SCANDIR64 3832*ee754c2dSkamil#endif 3833*ee754c2dSkamil 3834*ee754c2dSkamil#if SANITIZER_INTERCEPT_GETGROUPS 3835*ee754c2dSkamilINTERCEPTOR(int, getgroups, int size, u32 *lst) { 3836*ee754c2dSkamil void *ctx; 3837*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getgroups, size, lst); 3838*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 3839*ee754c2dSkamil // its metadata. See 3840*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 3841*ee754c2dSkamil int res = REAL(getgroups)(size, lst); 3842*ee754c2dSkamil if (res >= 0 && lst && size > 0) 3843*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lst, res * sizeof(*lst)); 3844*ee754c2dSkamil return res; 3845*ee754c2dSkamil} 3846*ee754c2dSkamil#define INIT_GETGROUPS COMMON_INTERCEPT_FUNCTION(getgroups); 3847*ee754c2dSkamil#else 3848*ee754c2dSkamil#define INIT_GETGROUPS 3849*ee754c2dSkamil#endif 3850*ee754c2dSkamil 3851*ee754c2dSkamil#if SANITIZER_INTERCEPT_POLL 3852*ee754c2dSkamilstatic void read_pollfd(void *ctx, __sanitizer_pollfd *fds, 3853*ee754c2dSkamil __sanitizer_nfds_t nfds) { 3854*ee754c2dSkamil for (unsigned i = 0; i < nfds; ++i) { 3855*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].fd, sizeof(fds[i].fd)); 3856*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].events, sizeof(fds[i].events)); 3857*ee754c2dSkamil } 3858*ee754c2dSkamil} 3859*ee754c2dSkamil 3860*ee754c2dSkamilstatic void write_pollfd(void *ctx, __sanitizer_pollfd *fds, 3861*ee754c2dSkamil __sanitizer_nfds_t nfds) { 3862*ee754c2dSkamil for (unsigned i = 0; i < nfds; ++i) 3863*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &fds[i].revents, 3864*ee754c2dSkamil sizeof(fds[i].revents)); 3865*ee754c2dSkamil} 3866*ee754c2dSkamil 3867*ee754c2dSkamilINTERCEPTOR(int, poll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds, 3868*ee754c2dSkamil int timeout) { 3869*ee754c2dSkamil void *ctx; 3870*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, poll, fds, nfds, timeout); 3871*ee754c2dSkamil if (fds && nfds) read_pollfd(ctx, fds, nfds); 3872*ee754c2dSkamil int res = COMMON_INTERCEPTOR_BLOCK_REAL(poll)(fds, nfds, timeout); 3873*ee754c2dSkamil if (fds && nfds) write_pollfd(ctx, fds, nfds); 3874*ee754c2dSkamil return res; 3875*ee754c2dSkamil} 3876*ee754c2dSkamil#define INIT_POLL COMMON_INTERCEPT_FUNCTION(poll); 3877*ee754c2dSkamil#else 3878*ee754c2dSkamil#define INIT_POLL 3879*ee754c2dSkamil#endif 3880*ee754c2dSkamil 3881*ee754c2dSkamil#if SANITIZER_INTERCEPT_PPOLL 3882*ee754c2dSkamilINTERCEPTOR(int, ppoll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds, 3883*ee754c2dSkamil void *timeout_ts, __sanitizer_sigset_t *sigmask) { 3884*ee754c2dSkamil void *ctx; 3885*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, ppoll, fds, nfds, timeout_ts, sigmask); 3886*ee754c2dSkamil if (fds && nfds) read_pollfd(ctx, fds, nfds); 3887*ee754c2dSkamil if (timeout_ts) 3888*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout_ts, struct_timespec_sz); 3889*ee754c2dSkamil if (sigmask) COMMON_INTERCEPTOR_READ_RANGE(ctx, sigmask, sizeof(*sigmask)); 3890*ee754c2dSkamil int res = 3891*ee754c2dSkamil COMMON_INTERCEPTOR_BLOCK_REAL(ppoll)(fds, nfds, timeout_ts, sigmask); 3892*ee754c2dSkamil if (fds && nfds) write_pollfd(ctx, fds, nfds); 3893*ee754c2dSkamil return res; 3894*ee754c2dSkamil} 3895*ee754c2dSkamil#define INIT_PPOLL COMMON_INTERCEPT_FUNCTION(ppoll); 3896*ee754c2dSkamil#else 3897*ee754c2dSkamil#define INIT_PPOLL 3898*ee754c2dSkamil#endif 3899*ee754c2dSkamil 3900*ee754c2dSkamil#if SANITIZER_INTERCEPT_WORDEXP 3901*ee754c2dSkamilINTERCEPTOR(int, wordexp, char *s, __sanitizer_wordexp_t *p, int flags) { 3902*ee754c2dSkamil void *ctx; 3903*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, wordexp, s, p, flags); 3904*ee754c2dSkamil if (s) COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1); 3905*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 3906*ee754c2dSkamil // its metadata. See 3907*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 3908*ee754c2dSkamil int res = REAL(wordexp)(s, p, flags); 3909*ee754c2dSkamil if (!res && p) { 3910*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); 3911*ee754c2dSkamil if (p->we_wordc) 3912*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->we_wordv, 3913*ee754c2dSkamil sizeof(*p->we_wordv) * p->we_wordc); 3914*ee754c2dSkamil for (uptr i = 0; i < p->we_wordc; ++i) { 3915*ee754c2dSkamil char *w = p->we_wordv[i]; 3916*ee754c2dSkamil if (w) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, w, REAL(strlen)(w) + 1); 3917*ee754c2dSkamil } 3918*ee754c2dSkamil } 3919*ee754c2dSkamil return res; 3920*ee754c2dSkamil} 3921*ee754c2dSkamil#define INIT_WORDEXP COMMON_INTERCEPT_FUNCTION(wordexp); 3922*ee754c2dSkamil#else 3923*ee754c2dSkamil#define INIT_WORDEXP 3924*ee754c2dSkamil#endif 3925*ee754c2dSkamil 3926*ee754c2dSkamil#if SANITIZER_INTERCEPT_SIGWAIT 3927*ee754c2dSkamilINTERCEPTOR(int, sigwait, __sanitizer_sigset_t *set, int *sig) { 3928*ee754c2dSkamil void *ctx; 3929*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, sigwait, set, sig); 3930*ee754c2dSkamil if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set)); 3931*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 3932*ee754c2dSkamil // its metadata. See 3933*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 3934*ee754c2dSkamil int res = REAL(sigwait)(set, sig); 3935*ee754c2dSkamil if (!res && sig) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sig, sizeof(*sig)); 3936*ee754c2dSkamil return res; 3937*ee754c2dSkamil} 3938*ee754c2dSkamil#define INIT_SIGWAIT COMMON_INTERCEPT_FUNCTION(sigwait); 3939*ee754c2dSkamil#else 3940*ee754c2dSkamil#define INIT_SIGWAIT 3941*ee754c2dSkamil#endif 3942*ee754c2dSkamil 3943*ee754c2dSkamil#if SANITIZER_INTERCEPT_SIGWAITINFO 3944*ee754c2dSkamilINTERCEPTOR(int, sigwaitinfo, __sanitizer_sigset_t *set, void *info) { 3945*ee754c2dSkamil void *ctx; 3946*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, sigwaitinfo, set, info); 3947*ee754c2dSkamil if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set)); 3948*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 3949*ee754c2dSkamil // its metadata. See 3950*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 3951*ee754c2dSkamil int res = REAL(sigwaitinfo)(set, info); 3952*ee754c2dSkamil if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz); 3953*ee754c2dSkamil return res; 3954*ee754c2dSkamil} 3955*ee754c2dSkamil#define INIT_SIGWAITINFO COMMON_INTERCEPT_FUNCTION(sigwaitinfo); 3956*ee754c2dSkamil#else 3957*ee754c2dSkamil#define INIT_SIGWAITINFO 3958*ee754c2dSkamil#endif 3959*ee754c2dSkamil 3960*ee754c2dSkamil#if SANITIZER_INTERCEPT_SIGTIMEDWAIT 3961*ee754c2dSkamilINTERCEPTOR(int, sigtimedwait, __sanitizer_sigset_t *set, void *info, 3962*ee754c2dSkamil void *timeout) { 3963*ee754c2dSkamil void *ctx; 3964*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, sigtimedwait, set, info, timeout); 3965*ee754c2dSkamil if (timeout) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout, struct_timespec_sz); 3966*ee754c2dSkamil if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set)); 3967*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 3968*ee754c2dSkamil // its metadata. See 3969*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 3970*ee754c2dSkamil int res = REAL(sigtimedwait)(set, info, timeout); 3971*ee754c2dSkamil if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz); 3972*ee754c2dSkamil return res; 3973*ee754c2dSkamil} 3974*ee754c2dSkamil#define INIT_SIGTIMEDWAIT COMMON_INTERCEPT_FUNCTION(sigtimedwait); 3975*ee754c2dSkamil#else 3976*ee754c2dSkamil#define INIT_SIGTIMEDWAIT 3977*ee754c2dSkamil#endif 3978*ee754c2dSkamil 3979*ee754c2dSkamil#if SANITIZER_INTERCEPT_SIGSETOPS 3980*ee754c2dSkamilINTERCEPTOR(int, sigemptyset, __sanitizer_sigset_t *set) { 3981*ee754c2dSkamil void *ctx; 3982*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, sigemptyset, set); 3983*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 3984*ee754c2dSkamil // its metadata. See 3985*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 3986*ee754c2dSkamil int res = REAL(sigemptyset)(set); 3987*ee754c2dSkamil if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set)); 3988*ee754c2dSkamil return res; 3989*ee754c2dSkamil} 3990*ee754c2dSkamil 3991*ee754c2dSkamilINTERCEPTOR(int, sigfillset, __sanitizer_sigset_t *set) { 3992*ee754c2dSkamil void *ctx; 3993*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, sigfillset, set); 3994*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 3995*ee754c2dSkamil // its metadata. See 3996*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 3997*ee754c2dSkamil int res = REAL(sigfillset)(set); 3998*ee754c2dSkamil if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set)); 3999*ee754c2dSkamil return res; 4000*ee754c2dSkamil} 4001*ee754c2dSkamil#define INIT_SIGSETOPS \ 4002*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(sigemptyset); \ 4003*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(sigfillset); 4004*ee754c2dSkamil#else 4005*ee754c2dSkamil#define INIT_SIGSETOPS 4006*ee754c2dSkamil#endif 4007*ee754c2dSkamil 4008*ee754c2dSkamil#if SANITIZER_INTERCEPT_SIGPENDING 4009*ee754c2dSkamilINTERCEPTOR(int, sigpending, __sanitizer_sigset_t *set) { 4010*ee754c2dSkamil void *ctx; 4011*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, sigpending, set); 4012*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 4013*ee754c2dSkamil // its metadata. See 4014*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 4015*ee754c2dSkamil int res = REAL(sigpending)(set); 4016*ee754c2dSkamil if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set)); 4017*ee754c2dSkamil return res; 4018*ee754c2dSkamil} 4019*ee754c2dSkamil#define INIT_SIGPENDING COMMON_INTERCEPT_FUNCTION(sigpending); 4020*ee754c2dSkamil#else 4021*ee754c2dSkamil#define INIT_SIGPENDING 4022*ee754c2dSkamil#endif 4023*ee754c2dSkamil 4024*ee754c2dSkamil#if SANITIZER_INTERCEPT_SIGPROCMASK 4025*ee754c2dSkamilINTERCEPTOR(int, sigprocmask, int how, __sanitizer_sigset_t *set, 4026*ee754c2dSkamil __sanitizer_sigset_t *oldset) { 4027*ee754c2dSkamil void *ctx; 4028*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, sigprocmask, how, set, oldset); 4029*ee754c2dSkamil if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set)); 4030*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 4031*ee754c2dSkamil // its metadata. See 4032*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 4033*ee754c2dSkamil int res = REAL(sigprocmask)(how, set, oldset); 4034*ee754c2dSkamil if (!res && oldset) 4035*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset)); 4036*ee754c2dSkamil return res; 4037*ee754c2dSkamil} 4038*ee754c2dSkamil#define INIT_SIGPROCMASK COMMON_INTERCEPT_FUNCTION(sigprocmask); 4039*ee754c2dSkamil#else 4040*ee754c2dSkamil#define INIT_SIGPROCMASK 4041*ee754c2dSkamil#endif 4042*ee754c2dSkamil 4043*ee754c2dSkamil#if SANITIZER_INTERCEPT_BACKTRACE 4044*ee754c2dSkamilINTERCEPTOR(int, backtrace, void **buffer, int size) { 4045*ee754c2dSkamil void *ctx; 4046*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, backtrace, buffer, size); 4047*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 4048*ee754c2dSkamil // its metadata. See 4049*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 4050*ee754c2dSkamil int res = REAL(backtrace)(buffer, size); 4051*ee754c2dSkamil if (res && buffer) 4052*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buffer, res * sizeof(*buffer)); 4053*ee754c2dSkamil return res; 4054*ee754c2dSkamil} 4055*ee754c2dSkamil 4056*ee754c2dSkamilINTERCEPTOR(char **, backtrace_symbols, void **buffer, int size) { 4057*ee754c2dSkamil void *ctx; 4058*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, backtrace_symbols, buffer, size); 4059*ee754c2dSkamil if (buffer && size) 4060*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, size * sizeof(*buffer)); 4061*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 4062*ee754c2dSkamil // its metadata. See 4063*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 4064*ee754c2dSkamil char **res = REAL(backtrace_symbols)(buffer, size); 4065*ee754c2dSkamil if (res && size) { 4066*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, size * sizeof(*res)); 4067*ee754c2dSkamil for (int i = 0; i < size; ++i) 4068*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res[i], REAL(strlen(res[i])) + 1); 4069*ee754c2dSkamil } 4070*ee754c2dSkamil return res; 4071*ee754c2dSkamil} 4072*ee754c2dSkamil#define INIT_BACKTRACE \ 4073*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(backtrace); \ 4074*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(backtrace_symbols); 4075*ee754c2dSkamil#else 4076*ee754c2dSkamil#define INIT_BACKTRACE 4077*ee754c2dSkamil#endif 4078*ee754c2dSkamil 4079*ee754c2dSkamil#if SANITIZER_INTERCEPT__EXIT 4080*ee754c2dSkamilINTERCEPTOR(void, _exit, int status) { 4081*ee754c2dSkamil void *ctx; 4082*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, _exit, status); 4083*ee754c2dSkamil COMMON_INTERCEPTOR_USER_CALLBACK_START(); 4084*ee754c2dSkamil int status1 = COMMON_INTERCEPTOR_ON_EXIT(ctx); 4085*ee754c2dSkamil COMMON_INTERCEPTOR_USER_CALLBACK_END(); 4086*ee754c2dSkamil if (status == 0) status = status1; 4087*ee754c2dSkamil REAL(_exit)(status); 4088*ee754c2dSkamil} 4089*ee754c2dSkamil#define INIT__EXIT COMMON_INTERCEPT_FUNCTION(_exit); 4090*ee754c2dSkamil#else 4091*ee754c2dSkamil#define INIT__EXIT 4092*ee754c2dSkamil#endif 4093*ee754c2dSkamil 4094*ee754c2dSkamil#if SANITIZER_INTERCEPT_PTHREAD_MUTEX 4095*ee754c2dSkamilINTERCEPTOR(int, pthread_mutex_lock, void *m) { 4096*ee754c2dSkamil void *ctx; 4097*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_lock, m); 4098*ee754c2dSkamil COMMON_INTERCEPTOR_MUTEX_PRE_LOCK(ctx, m); 4099*ee754c2dSkamil int res = REAL(pthread_mutex_lock)(m); 4100*ee754c2dSkamil if (res == errno_EOWNERDEAD) 4101*ee754c2dSkamil COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m); 4102*ee754c2dSkamil if (res == 0 || res == errno_EOWNERDEAD) 4103*ee754c2dSkamil COMMON_INTERCEPTOR_MUTEX_POST_LOCK(ctx, m); 4104*ee754c2dSkamil if (res == errno_EINVAL) 4105*ee754c2dSkamil COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m); 4106*ee754c2dSkamil return res; 4107*ee754c2dSkamil} 4108*ee754c2dSkamil 4109*ee754c2dSkamilINTERCEPTOR(int, pthread_mutex_unlock, void *m) { 4110*ee754c2dSkamil void *ctx; 4111*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_unlock, m); 4112*ee754c2dSkamil COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m); 4113*ee754c2dSkamil int res = REAL(pthread_mutex_unlock)(m); 4114*ee754c2dSkamil if (res == errno_EINVAL) 4115*ee754c2dSkamil COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m); 4116*ee754c2dSkamil return res; 4117*ee754c2dSkamil} 4118*ee754c2dSkamil 4119*ee754c2dSkamil#define INIT_PTHREAD_MUTEX_LOCK COMMON_INTERCEPT_FUNCTION(pthread_mutex_lock) 4120*ee754c2dSkamil#define INIT_PTHREAD_MUTEX_UNLOCK \ 4121*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(pthread_mutex_unlock) 4122*ee754c2dSkamil#else 4123*ee754c2dSkamil#define INIT_PTHREAD_MUTEX_LOCK 4124*ee754c2dSkamil#define INIT_PTHREAD_MUTEX_UNLOCK 4125*ee754c2dSkamil#endif 4126*ee754c2dSkamil 4127*ee754c2dSkamil#if SANITIZER_INTERCEPT___PTHREAD_MUTEX 4128*ee754c2dSkamilINTERCEPTOR(int, __pthread_mutex_lock, void *m) { 4129*ee754c2dSkamil return WRAP(pthread_mutex_lock)(m); 4130*ee754c2dSkamil} 4131*ee754c2dSkamil 4132*ee754c2dSkamilINTERCEPTOR(int, __pthread_mutex_unlock, void *m) { 4133*ee754c2dSkamil return WRAP(pthread_mutex_unlock)(m); 4134*ee754c2dSkamil} 4135*ee754c2dSkamil 4136*ee754c2dSkamil#define INIT___PTHREAD_MUTEX_LOCK \ 4137*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(__pthread_mutex_lock) 4138*ee754c2dSkamil#define INIT___PTHREAD_MUTEX_UNLOCK \ 4139*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(__pthread_mutex_unlock) 4140*ee754c2dSkamil#else 4141*ee754c2dSkamil#define INIT___PTHREAD_MUTEX_LOCK 4142*ee754c2dSkamil#define INIT___PTHREAD_MUTEX_UNLOCK 4143*ee754c2dSkamil#endif 4144*ee754c2dSkamil 4145*ee754c2dSkamil#if SANITIZER_INTERCEPT___LIBC_MUTEX 4146*ee754c2dSkamilINTERCEPTOR(int, __libc_mutex_lock, void *m) 4147*ee754c2dSkamilALIAS(WRAPPER_NAME(pthread_mutex_lock)); 4148*ee754c2dSkamil 4149*ee754c2dSkamilINTERCEPTOR(int, __libc_mutex_unlock, void *m) 4150*ee754c2dSkamilALIAS(WRAPPER_NAME(pthread_mutex_unlock)); 4151*ee754c2dSkamil 4152*ee754c2dSkamilINTERCEPTOR(int, __libc_thr_setcancelstate, int state, int *oldstate) 4153*ee754c2dSkamilALIAS(WRAPPER_NAME(pthread_setcancelstate)); 4154*ee754c2dSkamil 4155*ee754c2dSkamil#define INIT___LIBC_MUTEX_LOCK COMMON_INTERCEPT_FUNCTION(__libc_mutex_lock) 4156*ee754c2dSkamil#define INIT___LIBC_MUTEX_UNLOCK COMMON_INTERCEPT_FUNCTION(__libc_mutex_unlock) 4157*ee754c2dSkamil#define INIT___LIBC_THR_SETCANCELSTATE \ 4158*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(__libc_thr_setcancelstate) 4159*ee754c2dSkamil#else 4160*ee754c2dSkamil#define INIT___LIBC_MUTEX_LOCK 4161*ee754c2dSkamil#define INIT___LIBC_MUTEX_UNLOCK 4162*ee754c2dSkamil#define INIT___LIBC_THR_SETCANCELSTATE 4163*ee754c2dSkamil#endif 4164*ee754c2dSkamil 4165*ee754c2dSkamil#if SANITIZER_INTERCEPT_GETMNTENT || SANITIZER_INTERCEPT_GETMNTENT_R 4166*ee754c2dSkamilstatic void write_mntent(void *ctx, __sanitizer_mntent *mnt) { 4167*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt, sizeof(*mnt)); 4168*ee754c2dSkamil if (mnt->mnt_fsname) 4169*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_fsname, 4170*ee754c2dSkamil REAL(strlen)(mnt->mnt_fsname) + 1); 4171*ee754c2dSkamil if (mnt->mnt_dir) 4172*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_dir, 4173*ee754c2dSkamil REAL(strlen)(mnt->mnt_dir) + 1); 4174*ee754c2dSkamil if (mnt->mnt_type) 4175*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_type, 4176*ee754c2dSkamil REAL(strlen)(mnt->mnt_type) + 1); 4177*ee754c2dSkamil if (mnt->mnt_opts) 4178*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_opts, 4179*ee754c2dSkamil REAL(strlen)(mnt->mnt_opts) + 1); 4180*ee754c2dSkamil} 4181*ee754c2dSkamil#endif 4182*ee754c2dSkamil 4183*ee754c2dSkamil#if SANITIZER_INTERCEPT_GETMNTENT 4184*ee754c2dSkamilINTERCEPTOR(__sanitizer_mntent *, getmntent, void *fp) { 4185*ee754c2dSkamil void *ctx; 4186*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getmntent, fp); 4187*ee754c2dSkamil __sanitizer_mntent *res = REAL(getmntent)(fp); 4188*ee754c2dSkamil if (res) write_mntent(ctx, res); 4189*ee754c2dSkamil return res; 4190*ee754c2dSkamil} 4191*ee754c2dSkamil#define INIT_GETMNTENT COMMON_INTERCEPT_FUNCTION(getmntent); 4192*ee754c2dSkamil#else 4193*ee754c2dSkamil#define INIT_GETMNTENT 4194*ee754c2dSkamil#endif 4195*ee754c2dSkamil 4196*ee754c2dSkamil#if SANITIZER_INTERCEPT_GETMNTENT_R 4197*ee754c2dSkamilINTERCEPTOR(__sanitizer_mntent *, getmntent_r, void *fp, 4198*ee754c2dSkamil __sanitizer_mntent *mntbuf, char *buf, int buflen) { 4199*ee754c2dSkamil void *ctx; 4200*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getmntent_r, fp, mntbuf, buf, buflen); 4201*ee754c2dSkamil __sanitizer_mntent *res = REAL(getmntent_r)(fp, mntbuf, buf, buflen); 4202*ee754c2dSkamil if (res) write_mntent(ctx, res); 4203*ee754c2dSkamil return res; 4204*ee754c2dSkamil} 4205*ee754c2dSkamil#define INIT_GETMNTENT_R COMMON_INTERCEPT_FUNCTION(getmntent_r); 4206*ee754c2dSkamil#else 4207*ee754c2dSkamil#define INIT_GETMNTENT_R 4208*ee754c2dSkamil#endif 4209*ee754c2dSkamil 4210*ee754c2dSkamil#if SANITIZER_INTERCEPT_STATFS 4211*ee754c2dSkamilINTERCEPTOR(int, statfs, char *path, void *buf) { 4212*ee754c2dSkamil void *ctx; 4213*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, statfs, path, buf); 4214*ee754c2dSkamil if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 4215*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 4216*ee754c2dSkamil // its metadata. See 4217*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 4218*ee754c2dSkamil int res = REAL(statfs)(path, buf); 4219*ee754c2dSkamil if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz); 4220*ee754c2dSkamil return res; 4221*ee754c2dSkamil} 4222*ee754c2dSkamilINTERCEPTOR(int, fstatfs, int fd, void *buf) { 4223*ee754c2dSkamil void *ctx; 4224*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, fstatfs, fd, buf); 4225*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 4226*ee754c2dSkamil // its metadata. See 4227*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 4228*ee754c2dSkamil int res = REAL(fstatfs)(fd, buf); 4229*ee754c2dSkamil if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz); 4230*ee754c2dSkamil return res; 4231*ee754c2dSkamil} 4232*ee754c2dSkamil#define INIT_STATFS \ 4233*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(statfs); \ 4234*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(fstatfs); 4235*ee754c2dSkamil#else 4236*ee754c2dSkamil#define INIT_STATFS 4237*ee754c2dSkamil#endif 4238*ee754c2dSkamil 4239*ee754c2dSkamil#if SANITIZER_INTERCEPT_STATFS64 4240*ee754c2dSkamilINTERCEPTOR(int, statfs64, char *path, void *buf) { 4241*ee754c2dSkamil void *ctx; 4242*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, statfs64, path, buf); 4243*ee754c2dSkamil if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 4244*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 4245*ee754c2dSkamil // its metadata. See 4246*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 4247*ee754c2dSkamil int res = REAL(statfs64)(path, buf); 4248*ee754c2dSkamil if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz); 4249*ee754c2dSkamil return res; 4250*ee754c2dSkamil} 4251*ee754c2dSkamilINTERCEPTOR(int, fstatfs64, int fd, void *buf) { 4252*ee754c2dSkamil void *ctx; 4253*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, fstatfs64, fd, buf); 4254*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 4255*ee754c2dSkamil // its metadata. See 4256*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 4257*ee754c2dSkamil int res = REAL(fstatfs64)(fd, buf); 4258*ee754c2dSkamil if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz); 4259*ee754c2dSkamil return res; 4260*ee754c2dSkamil} 4261*ee754c2dSkamil#define INIT_STATFS64 \ 4262*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(statfs64); \ 4263*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(fstatfs64); 4264*ee754c2dSkamil#else 4265*ee754c2dSkamil#define INIT_STATFS64 4266*ee754c2dSkamil#endif 4267*ee754c2dSkamil 4268*ee754c2dSkamil#if SANITIZER_INTERCEPT_STATVFS 4269*ee754c2dSkamilINTERCEPTOR(int, statvfs, char *path, void *buf) { 4270*ee754c2dSkamil void *ctx; 4271*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, statvfs, path, buf); 4272*ee754c2dSkamil if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 4273*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 4274*ee754c2dSkamil // its metadata. See 4275*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 4276*ee754c2dSkamil int res = REAL(statvfs)(path, buf); 4277*ee754c2dSkamil if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz); 4278*ee754c2dSkamil return res; 4279*ee754c2dSkamil} 4280*ee754c2dSkamilINTERCEPTOR(int, fstatvfs, int fd, void *buf) { 4281*ee754c2dSkamil void *ctx; 4282*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs, fd, buf); 4283*ee754c2dSkamil COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 4284*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 4285*ee754c2dSkamil // its metadata. See 4286*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 4287*ee754c2dSkamil int res = REAL(fstatvfs)(fd, buf); 4288*ee754c2dSkamil if (!res) { 4289*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz); 4290*ee754c2dSkamil if (fd >= 0) 4291*ee754c2dSkamil COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 4292*ee754c2dSkamil } 4293*ee754c2dSkamil return res; 4294*ee754c2dSkamil} 4295*ee754c2dSkamil#define INIT_STATVFS \ 4296*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(statvfs); \ 4297*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(fstatvfs); 4298*ee754c2dSkamil#else 4299*ee754c2dSkamil#define INIT_STATVFS 4300*ee754c2dSkamil#endif 4301*ee754c2dSkamil 4302*ee754c2dSkamil#if SANITIZER_INTERCEPT_STATVFS64 4303*ee754c2dSkamilINTERCEPTOR(int, statvfs64, char *path, void *buf) { 4304*ee754c2dSkamil void *ctx; 4305*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, statvfs64, path, buf); 4306*ee754c2dSkamil if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 4307*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 4308*ee754c2dSkamil // its metadata. See 4309*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 4310*ee754c2dSkamil int res = REAL(statvfs64)(path, buf); 4311*ee754c2dSkamil if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz); 4312*ee754c2dSkamil return res; 4313*ee754c2dSkamil} 4314*ee754c2dSkamilINTERCEPTOR(int, fstatvfs64, int fd, void *buf) { 4315*ee754c2dSkamil void *ctx; 4316*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs64, fd, buf); 4317*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 4318*ee754c2dSkamil // its metadata. See 4319*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 4320*ee754c2dSkamil int res = REAL(fstatvfs64)(fd, buf); 4321*ee754c2dSkamil if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz); 4322*ee754c2dSkamil return res; 4323*ee754c2dSkamil} 4324*ee754c2dSkamil#define INIT_STATVFS64 \ 4325*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(statvfs64); \ 4326*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(fstatvfs64); 4327*ee754c2dSkamil#else 4328*ee754c2dSkamil#define INIT_STATVFS64 4329*ee754c2dSkamil#endif 4330*ee754c2dSkamil 4331*ee754c2dSkamil#if SANITIZER_INTERCEPT_INITGROUPS 4332*ee754c2dSkamilINTERCEPTOR(int, initgroups, char *user, u32 group) { 4333*ee754c2dSkamil void *ctx; 4334*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, initgroups, user, group); 4335*ee754c2dSkamil if (user) COMMON_INTERCEPTOR_READ_RANGE(ctx, user, REAL(strlen)(user) + 1); 4336*ee754c2dSkamil int res = REAL(initgroups)(user, group); 4337*ee754c2dSkamil return res; 4338*ee754c2dSkamil} 4339*ee754c2dSkamil#define INIT_INITGROUPS COMMON_INTERCEPT_FUNCTION(initgroups); 4340*ee754c2dSkamil#else 4341*ee754c2dSkamil#define INIT_INITGROUPS 4342*ee754c2dSkamil#endif 4343*ee754c2dSkamil 4344*ee754c2dSkamil#if SANITIZER_INTERCEPT_ETHER_NTOA_ATON 4345*ee754c2dSkamilINTERCEPTOR(char *, ether_ntoa, __sanitizer_ether_addr *addr) { 4346*ee754c2dSkamil void *ctx; 4347*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa, addr); 4348*ee754c2dSkamil if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr)); 4349*ee754c2dSkamil char *res = REAL(ether_ntoa)(addr); 4350*ee754c2dSkamil if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1); 4351*ee754c2dSkamil return res; 4352*ee754c2dSkamil} 4353*ee754c2dSkamilINTERCEPTOR(__sanitizer_ether_addr *, ether_aton, char *buf) { 4354*ee754c2dSkamil void *ctx; 4355*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, ether_aton, buf); 4356*ee754c2dSkamil if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1); 4357*ee754c2dSkamil __sanitizer_ether_addr *res = REAL(ether_aton)(buf); 4358*ee754c2dSkamil if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, sizeof(*res)); 4359*ee754c2dSkamil return res; 4360*ee754c2dSkamil} 4361*ee754c2dSkamil#define INIT_ETHER_NTOA_ATON \ 4362*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(ether_ntoa); \ 4363*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(ether_aton); 4364*ee754c2dSkamil#else 4365*ee754c2dSkamil#define INIT_ETHER_NTOA_ATON 4366*ee754c2dSkamil#endif 4367*ee754c2dSkamil 4368*ee754c2dSkamil#if SANITIZER_INTERCEPT_ETHER_HOST 4369*ee754c2dSkamilINTERCEPTOR(int, ether_ntohost, char *hostname, __sanitizer_ether_addr *addr) { 4370*ee754c2dSkamil void *ctx; 4371*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, ether_ntohost, hostname, addr); 4372*ee754c2dSkamil if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr)); 4373*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 4374*ee754c2dSkamil // its metadata. See 4375*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 4376*ee754c2dSkamil int res = REAL(ether_ntohost)(hostname, addr); 4377*ee754c2dSkamil if (!res && hostname) 4378*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1); 4379*ee754c2dSkamil return res; 4380*ee754c2dSkamil} 4381*ee754c2dSkamilINTERCEPTOR(int, ether_hostton, char *hostname, __sanitizer_ether_addr *addr) { 4382*ee754c2dSkamil void *ctx; 4383*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, ether_hostton, hostname, addr); 4384*ee754c2dSkamil if (hostname) 4385*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1); 4386*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 4387*ee754c2dSkamil // its metadata. See 4388*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 4389*ee754c2dSkamil int res = REAL(ether_hostton)(hostname, addr); 4390*ee754c2dSkamil if (!res && addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr)); 4391*ee754c2dSkamil return res; 4392*ee754c2dSkamil} 4393*ee754c2dSkamilINTERCEPTOR(int, ether_line, char *line, __sanitizer_ether_addr *addr, 4394*ee754c2dSkamil char *hostname) { 4395*ee754c2dSkamil void *ctx; 4396*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, ether_line, line, addr, hostname); 4397*ee754c2dSkamil if (line) COMMON_INTERCEPTOR_READ_RANGE(ctx, line, REAL(strlen)(line) + 1); 4398*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 4399*ee754c2dSkamil // its metadata. See 4400*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 4401*ee754c2dSkamil int res = REAL(ether_line)(line, addr, hostname); 4402*ee754c2dSkamil if (!res) { 4403*ee754c2dSkamil if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr)); 4404*ee754c2dSkamil if (hostname) 4405*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1); 4406*ee754c2dSkamil } 4407*ee754c2dSkamil return res; 4408*ee754c2dSkamil} 4409*ee754c2dSkamil#define INIT_ETHER_HOST \ 4410*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(ether_ntohost); \ 4411*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(ether_hostton); \ 4412*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(ether_line); 4413*ee754c2dSkamil#else 4414*ee754c2dSkamil#define INIT_ETHER_HOST 4415*ee754c2dSkamil#endif 4416*ee754c2dSkamil 4417*ee754c2dSkamil#if SANITIZER_INTERCEPT_ETHER_R 4418*ee754c2dSkamilINTERCEPTOR(char *, ether_ntoa_r, __sanitizer_ether_addr *addr, char *buf) { 4419*ee754c2dSkamil void *ctx; 4420*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa_r, addr, buf); 4421*ee754c2dSkamil if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr)); 4422*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 4423*ee754c2dSkamil // its metadata. See 4424*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 4425*ee754c2dSkamil char *res = REAL(ether_ntoa_r)(addr, buf); 4426*ee754c2dSkamil if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 4427*ee754c2dSkamil return res; 4428*ee754c2dSkamil} 4429*ee754c2dSkamilINTERCEPTOR(__sanitizer_ether_addr *, ether_aton_r, char *buf, 4430*ee754c2dSkamil __sanitizer_ether_addr *addr) { 4431*ee754c2dSkamil void *ctx; 4432*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, ether_aton_r, buf, addr); 4433*ee754c2dSkamil if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1); 4434*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 4435*ee754c2dSkamil // its metadata. See 4436*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 4437*ee754c2dSkamil __sanitizer_ether_addr *res = REAL(ether_aton_r)(buf, addr); 4438*ee754c2dSkamil if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(*res)); 4439*ee754c2dSkamil return res; 4440*ee754c2dSkamil} 4441*ee754c2dSkamil#define INIT_ETHER_R \ 4442*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(ether_ntoa_r); \ 4443*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(ether_aton_r); 4444*ee754c2dSkamil#else 4445*ee754c2dSkamil#define INIT_ETHER_R 4446*ee754c2dSkamil#endif 4447*ee754c2dSkamil 4448*ee754c2dSkamil#if SANITIZER_INTERCEPT_SHMCTL 4449*ee754c2dSkamilINTERCEPTOR(int, shmctl, int shmid, int cmd, void *buf) { 4450*ee754c2dSkamil void *ctx; 4451*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, shmctl, shmid, cmd, buf); 4452*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 4453*ee754c2dSkamil // its metadata. See 4454*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 4455*ee754c2dSkamil int res = REAL(shmctl)(shmid, cmd, buf); 4456*ee754c2dSkamil if (res >= 0) { 4457*ee754c2dSkamil unsigned sz = 0; 4458*ee754c2dSkamil if (cmd == shmctl_ipc_stat || cmd == shmctl_shm_stat) 4459*ee754c2dSkamil sz = sizeof(__sanitizer_shmid_ds); 4460*ee754c2dSkamil else if (cmd == shmctl_ipc_info) 4461*ee754c2dSkamil sz = struct_shminfo_sz; 4462*ee754c2dSkamil else if (cmd == shmctl_shm_info) 4463*ee754c2dSkamil sz = struct_shm_info_sz; 4464*ee754c2dSkamil if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz); 4465*ee754c2dSkamil } 4466*ee754c2dSkamil return res; 4467*ee754c2dSkamil} 4468*ee754c2dSkamil#define INIT_SHMCTL COMMON_INTERCEPT_FUNCTION(shmctl); 4469*ee754c2dSkamil#else 4470*ee754c2dSkamil#define INIT_SHMCTL 4471*ee754c2dSkamil#endif 4472*ee754c2dSkamil 4473*ee754c2dSkamil#if SANITIZER_INTERCEPT_RANDOM_R 4474*ee754c2dSkamilINTERCEPTOR(int, random_r, void *buf, u32 *result) { 4475*ee754c2dSkamil void *ctx; 4476*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, random_r, buf, result); 4477*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 4478*ee754c2dSkamil // its metadata. See 4479*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 4480*ee754c2dSkamil int res = REAL(random_r)(buf, result); 4481*ee754c2dSkamil if (!res && result) 4482*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 4483*ee754c2dSkamil return res; 4484*ee754c2dSkamil} 4485*ee754c2dSkamil#define INIT_RANDOM_R COMMON_INTERCEPT_FUNCTION(random_r); 4486*ee754c2dSkamil#else 4487*ee754c2dSkamil#define INIT_RANDOM_R 4488*ee754c2dSkamil#endif 4489*ee754c2dSkamil 4490*ee754c2dSkamil// FIXME: under ASan the REAL() call below may write to freed memory and corrupt 4491*ee754c2dSkamil// its metadata. See 4492*ee754c2dSkamil// https://github.com/google/sanitizers/issues/321. 4493*ee754c2dSkamil#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET || \ 4494*ee754c2dSkamil SANITIZER_INTERCEPT_PTHREAD_ATTR_GET_SCHED || \ 4495*ee754c2dSkamil SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSSCHED || \ 4496*ee754c2dSkamil SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GET || \ 4497*ee754c2dSkamil SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GET || \ 4498*ee754c2dSkamil SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GET || \ 4499*ee754c2dSkamil SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GET 4500*ee754c2dSkamil#define INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(fn, sz) \ 4501*ee754c2dSkamil INTERCEPTOR(int, fn, void *attr, void *r) { \ 4502*ee754c2dSkamil void *ctx; \ 4503*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, fn, attr, r); \ 4504*ee754c2dSkamil int res = REAL(fn)(attr, r); \ 4505*ee754c2dSkamil if (!res && r) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, r, sz); \ 4506*ee754c2dSkamil return res; \ 4507*ee754c2dSkamil } 4508*ee754c2dSkamil#define INTERCEPTOR_PTHREAD_ATTR_GET(what, sz) \ 4509*ee754c2dSkamil INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_attr_get##what, sz) 4510*ee754c2dSkamil#define INTERCEPTOR_PTHREAD_MUTEXATTR_GET(what, sz) \ 4511*ee754c2dSkamil INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_mutexattr_get##what, sz) 4512*ee754c2dSkamil#define INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(what, sz) \ 4513*ee754c2dSkamil INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_rwlockattr_get##what, sz) 4514*ee754c2dSkamil#define INTERCEPTOR_PTHREAD_CONDATTR_GET(what, sz) \ 4515*ee754c2dSkamil INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_condattr_get##what, sz) 4516*ee754c2dSkamil#define INTERCEPTOR_PTHREAD_BARRIERATTR_GET(what, sz) \ 4517*ee754c2dSkamil INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_barrierattr_get##what, sz) 4518*ee754c2dSkamil#endif 4519*ee754c2dSkamil 4520*ee754c2dSkamil#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET 4521*ee754c2dSkamilINTERCEPTOR_PTHREAD_ATTR_GET(detachstate, sizeof(int)) 4522*ee754c2dSkamilINTERCEPTOR_PTHREAD_ATTR_GET(guardsize, sizeof(SIZE_T)) 4523*ee754c2dSkamilINTERCEPTOR_PTHREAD_ATTR_GET(scope, sizeof(int)) 4524*ee754c2dSkamilINTERCEPTOR_PTHREAD_ATTR_GET(stacksize, sizeof(SIZE_T)) 4525*ee754c2dSkamilINTERCEPTOR(int, pthread_attr_getstack, void *attr, void **addr, SIZE_T *size) { 4526*ee754c2dSkamil void *ctx; 4527*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getstack, attr, addr, size); 4528*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 4529*ee754c2dSkamil // its metadata. See 4530*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 4531*ee754c2dSkamil int res = REAL(pthread_attr_getstack)(attr, addr, size); 4532*ee754c2dSkamil if (!res) { 4533*ee754c2dSkamil if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr)); 4534*ee754c2dSkamil if (size) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, size, sizeof(*size)); 4535*ee754c2dSkamil } 4536*ee754c2dSkamil return res; 4537*ee754c2dSkamil} 4538*ee754c2dSkamil 4539*ee754c2dSkamil// We may need to call the real pthread_attr_getstack from the run-time 4540*ee754c2dSkamil// in sanitizer_common, but we don't want to include the interception headers 4541*ee754c2dSkamil// there. So, just define this function here. 4542*ee754c2dSkamilnamespace __sanitizer { 4543*ee754c2dSkamilextern "C" { 4544*ee754c2dSkamilint real_pthread_attr_getstack(void *attr, void **addr, SIZE_T *size) { 4545*ee754c2dSkamil return REAL(pthread_attr_getstack)(attr, addr, size); 4546*ee754c2dSkamil} 4547*ee754c2dSkamil} // extern "C" 4548*ee754c2dSkamil} // namespace __sanitizer 4549*ee754c2dSkamil 4550*ee754c2dSkamil#define INIT_PTHREAD_ATTR_GET \ 4551*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(pthread_attr_getdetachstate); \ 4552*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(pthread_attr_getguardsize); \ 4553*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(pthread_attr_getscope); \ 4554*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(pthread_attr_getstacksize); \ 4555*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(pthread_attr_getstack); 4556*ee754c2dSkamil#else 4557*ee754c2dSkamil#define INIT_PTHREAD_ATTR_GET 4558*ee754c2dSkamil#endif 4559*ee754c2dSkamil 4560*ee754c2dSkamil#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET_SCHED 4561*ee754c2dSkamilINTERCEPTOR_PTHREAD_ATTR_GET(schedparam, struct_sched_param_sz) 4562*ee754c2dSkamilINTERCEPTOR_PTHREAD_ATTR_GET(schedpolicy, sizeof(int)) 4563*ee754c2dSkamil 4564*ee754c2dSkamil#define INIT_PTHREAD_ATTR_GET_SCHED \ 4565*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedparam); \ 4566*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedpolicy); 4567*ee754c2dSkamil#else 4568*ee754c2dSkamil#define INIT_PTHREAD_ATTR_GET_SCHED 4569*ee754c2dSkamil#endif 4570*ee754c2dSkamil 4571*ee754c2dSkamil#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSCHED 4572*ee754c2dSkamilINTERCEPTOR_PTHREAD_ATTR_GET(inheritsched, sizeof(int)) 4573*ee754c2dSkamil 4574*ee754c2dSkamil#define INIT_PTHREAD_ATTR_GETINHERITSCHED \ 4575*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(pthread_attr_getinheritsched); 4576*ee754c2dSkamil#else 4577*ee754c2dSkamil#define INIT_PTHREAD_ATTR_GETINHERITSCHED 4578*ee754c2dSkamil#endif 4579*ee754c2dSkamil 4580*ee754c2dSkamil#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETAFFINITY_NP 4581*ee754c2dSkamilINTERCEPTOR(int, pthread_attr_getaffinity_np, void *attr, SIZE_T cpusetsize, 4582*ee754c2dSkamil void *cpuset) { 4583*ee754c2dSkamil void *ctx; 4584*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getaffinity_np, attr, cpusetsize, 4585*ee754c2dSkamil cpuset); 4586*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 4587*ee754c2dSkamil // its metadata. See 4588*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 4589*ee754c2dSkamil int res = REAL(pthread_attr_getaffinity_np)(attr, cpusetsize, cpuset); 4590*ee754c2dSkamil if (!res && cpusetsize && cpuset) 4591*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cpuset, cpusetsize); 4592*ee754c2dSkamil return res; 4593*ee754c2dSkamil} 4594*ee754c2dSkamil 4595*ee754c2dSkamil#define INIT_PTHREAD_ATTR_GETAFFINITY_NP \ 4596*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(pthread_attr_getaffinity_np); 4597*ee754c2dSkamil#else 4598*ee754c2dSkamil#define INIT_PTHREAD_ATTR_GETAFFINITY_NP 4599*ee754c2dSkamil#endif 4600*ee754c2dSkamil 4601*ee754c2dSkamil#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPSHARED 4602*ee754c2dSkamilINTERCEPTOR_PTHREAD_MUTEXATTR_GET(pshared, sizeof(int)) 4603*ee754c2dSkamil#define INIT_PTHREAD_MUTEXATTR_GETPSHARED \ 4604*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getpshared); 4605*ee754c2dSkamil#else 4606*ee754c2dSkamil#define INIT_PTHREAD_MUTEXATTR_GETPSHARED 4607*ee754c2dSkamil#endif 4608*ee754c2dSkamil 4609*ee754c2dSkamil#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETTYPE 4610*ee754c2dSkamilINTERCEPTOR_PTHREAD_MUTEXATTR_GET(type, sizeof(int)) 4611*ee754c2dSkamil#define INIT_PTHREAD_MUTEXATTR_GETTYPE \ 4612*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_gettype); 4613*ee754c2dSkamil#else 4614*ee754c2dSkamil#define INIT_PTHREAD_MUTEXATTR_GETTYPE 4615*ee754c2dSkamil#endif 4616*ee754c2dSkamil 4617*ee754c2dSkamil#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPROTOCOL 4618*ee754c2dSkamilINTERCEPTOR_PTHREAD_MUTEXATTR_GET(protocol, sizeof(int)) 4619*ee754c2dSkamil#define INIT_PTHREAD_MUTEXATTR_GETPROTOCOL \ 4620*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getprotocol); 4621*ee754c2dSkamil#else 4622*ee754c2dSkamil#define INIT_PTHREAD_MUTEXATTR_GETPROTOCOL 4623*ee754c2dSkamil#endif 4624*ee754c2dSkamil 4625*ee754c2dSkamil#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPRIOCEILING 4626*ee754c2dSkamilINTERCEPTOR_PTHREAD_MUTEXATTR_GET(prioceiling, sizeof(int)) 4627*ee754c2dSkamil#define INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING \ 4628*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getprioceiling); 4629*ee754c2dSkamil#else 4630*ee754c2dSkamil#define INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING 4631*ee754c2dSkamil#endif 4632*ee754c2dSkamil 4633*ee754c2dSkamil#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST 4634*ee754c2dSkamilINTERCEPTOR_PTHREAD_MUTEXATTR_GET(robust, sizeof(int)) 4635*ee754c2dSkamil#define INIT_PTHREAD_MUTEXATTR_GETROBUST \ 4636*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getrobust); 4637*ee754c2dSkamil#else 4638*ee754c2dSkamil#define INIT_PTHREAD_MUTEXATTR_GETROBUST 4639*ee754c2dSkamil#endif 4640*ee754c2dSkamil 4641*ee754c2dSkamil#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST_NP 4642*ee754c2dSkamilINTERCEPTOR_PTHREAD_MUTEXATTR_GET(robust_np, sizeof(int)) 4643*ee754c2dSkamil#define INIT_PTHREAD_MUTEXATTR_GETROBUST_NP \ 4644*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getrobust_np); 4645*ee754c2dSkamil#else 4646*ee754c2dSkamil#define INIT_PTHREAD_MUTEXATTR_GETROBUST_NP 4647*ee754c2dSkamil#endif 4648*ee754c2dSkamil 4649*ee754c2dSkamil#if SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETPSHARED 4650*ee754c2dSkamilINTERCEPTOR_PTHREAD_RWLOCKATTR_GET(pshared, sizeof(int)) 4651*ee754c2dSkamil#define INIT_PTHREAD_RWLOCKATTR_GETPSHARED \ 4652*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(pthread_rwlockattr_getpshared); 4653*ee754c2dSkamil#else 4654*ee754c2dSkamil#define INIT_PTHREAD_RWLOCKATTR_GETPSHARED 4655*ee754c2dSkamil#endif 4656*ee754c2dSkamil 4657*ee754c2dSkamil#if SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETKIND_NP 4658*ee754c2dSkamilINTERCEPTOR_PTHREAD_RWLOCKATTR_GET(kind_np, sizeof(int)) 4659*ee754c2dSkamil#define INIT_PTHREAD_RWLOCKATTR_GETKIND_NP \ 4660*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(pthread_rwlockattr_getkind_np); 4661*ee754c2dSkamil#else 4662*ee754c2dSkamil#define INIT_PTHREAD_RWLOCKATTR_GETKIND_NP 4663*ee754c2dSkamil#endif 4664*ee754c2dSkamil 4665*ee754c2dSkamil#if SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETPSHARED 4666*ee754c2dSkamilINTERCEPTOR_PTHREAD_CONDATTR_GET(pshared, sizeof(int)) 4667*ee754c2dSkamil#define INIT_PTHREAD_CONDATTR_GETPSHARED \ 4668*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(pthread_condattr_getpshared); 4669*ee754c2dSkamil#else 4670*ee754c2dSkamil#define INIT_PTHREAD_CONDATTR_GETPSHARED 4671*ee754c2dSkamil#endif 4672*ee754c2dSkamil 4673*ee754c2dSkamil#if SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETCLOCK 4674*ee754c2dSkamilINTERCEPTOR_PTHREAD_CONDATTR_GET(clock, sizeof(int)) 4675*ee754c2dSkamil#define INIT_PTHREAD_CONDATTR_GETCLOCK \ 4676*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(pthread_condattr_getclock); 4677*ee754c2dSkamil#else 4678*ee754c2dSkamil#define INIT_PTHREAD_CONDATTR_GETCLOCK 4679*ee754c2dSkamil#endif 4680*ee754c2dSkamil 4681*ee754c2dSkamil#if SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GETPSHARED 4682*ee754c2dSkamilINTERCEPTOR_PTHREAD_BARRIERATTR_GET(pshared, sizeof(int)) // !mac !android 4683*ee754c2dSkamil#define INIT_PTHREAD_BARRIERATTR_GETPSHARED \ 4684*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(pthread_barrierattr_getpshared); 4685*ee754c2dSkamil#else 4686*ee754c2dSkamil#define INIT_PTHREAD_BARRIERATTR_GETPSHARED 4687*ee754c2dSkamil#endif 4688*ee754c2dSkamil 4689*ee754c2dSkamil#if SANITIZER_INTERCEPT_TMPNAM 4690*ee754c2dSkamilINTERCEPTOR(char *, tmpnam, char *s) { 4691*ee754c2dSkamil void *ctx; 4692*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, tmpnam, s); 4693*ee754c2dSkamil char *res = REAL(tmpnam)(s); 4694*ee754c2dSkamil if (res) { 4695*ee754c2dSkamil if (s) 4696*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 4697*ee754c2dSkamil // its metadata. See 4698*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 4699*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1); 4700*ee754c2dSkamil else 4701*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1); 4702*ee754c2dSkamil } 4703*ee754c2dSkamil return res; 4704*ee754c2dSkamil} 4705*ee754c2dSkamil#define INIT_TMPNAM COMMON_INTERCEPT_FUNCTION(tmpnam); 4706*ee754c2dSkamil#else 4707*ee754c2dSkamil#define INIT_TMPNAM 4708*ee754c2dSkamil#endif 4709*ee754c2dSkamil 4710*ee754c2dSkamil#if SANITIZER_INTERCEPT_TMPNAM_R 4711*ee754c2dSkamilINTERCEPTOR(char *, tmpnam_r, char *s) { 4712*ee754c2dSkamil void *ctx; 4713*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, tmpnam_r, s); 4714*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 4715*ee754c2dSkamil // its metadata. See 4716*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 4717*ee754c2dSkamil char *res = REAL(tmpnam_r)(s); 4718*ee754c2dSkamil if (res && s) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1); 4719*ee754c2dSkamil return res; 4720*ee754c2dSkamil} 4721*ee754c2dSkamil#define INIT_TMPNAM_R COMMON_INTERCEPT_FUNCTION(tmpnam_r); 4722*ee754c2dSkamil#else 4723*ee754c2dSkamil#define INIT_TMPNAM_R 4724*ee754c2dSkamil#endif 4725*ee754c2dSkamil 4726*ee754c2dSkamil#if SANITIZER_INTERCEPT_TTYNAME_R 4727*ee754c2dSkamilINTERCEPTOR(int, ttyname_r, int fd, char *name, SIZE_T namesize) { 4728*ee754c2dSkamil void *ctx; 4729*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, ttyname_r, fd, name, namesize); 4730*ee754c2dSkamil int res = REAL(ttyname_r)(fd, name, namesize); 4731*ee754c2dSkamil if (res == 0) 4732*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, REAL(strlen)(name) + 1); 4733*ee754c2dSkamil return res; 4734*ee754c2dSkamil} 4735*ee754c2dSkamil#define INIT_TTYNAME_R COMMON_INTERCEPT_FUNCTION(ttyname_r); 4736*ee754c2dSkamil#else 4737*ee754c2dSkamil#define INIT_TTYNAME_R 4738*ee754c2dSkamil#endif 4739*ee754c2dSkamil 4740*ee754c2dSkamil#if SANITIZER_INTERCEPT_TEMPNAM 4741*ee754c2dSkamilINTERCEPTOR(char *, tempnam, char *dir, char *pfx) { 4742*ee754c2dSkamil void *ctx; 4743*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, tempnam, dir, pfx); 4744*ee754c2dSkamil if (dir) COMMON_INTERCEPTOR_READ_RANGE(ctx, dir, REAL(strlen)(dir) + 1); 4745*ee754c2dSkamil if (pfx) COMMON_INTERCEPTOR_READ_RANGE(ctx, pfx, REAL(strlen)(pfx) + 1); 4746*ee754c2dSkamil char *res = REAL(tempnam)(dir, pfx); 4747*ee754c2dSkamil if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1); 4748*ee754c2dSkamil return res; 4749*ee754c2dSkamil} 4750*ee754c2dSkamil#define INIT_TEMPNAM COMMON_INTERCEPT_FUNCTION(tempnam); 4751*ee754c2dSkamil#else 4752*ee754c2dSkamil#define INIT_TEMPNAM 4753*ee754c2dSkamil#endif 4754*ee754c2dSkamil 4755*ee754c2dSkamil#if SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP && !SANITIZER_NETBSD 4756*ee754c2dSkamilINTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name) { 4757*ee754c2dSkamil void *ctx; 4758*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, pthread_setname_np, thread, name); 4759*ee754c2dSkamil COMMON_INTERCEPTOR_READ_STRING(ctx, name, 0); 4760*ee754c2dSkamil COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name); 4761*ee754c2dSkamil return REAL(pthread_setname_np)(thread, name); 4762*ee754c2dSkamil} 4763*ee754c2dSkamil#define INIT_PTHREAD_SETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_setname_np); 4764*ee754c2dSkamil#elif SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP && SANITIZER_NETBSD 4765*ee754c2dSkamilINTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name, void *arg) { 4766*ee754c2dSkamil void *ctx; 4767*ee754c2dSkamil char newname[32]; // PTHREAD_MAX_NAMELEN_NP=32 4768*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, pthread_setname_np, thread, name, arg); 4769*ee754c2dSkamil COMMON_INTERCEPTOR_READ_STRING(ctx, name, 0); 4770*ee754c2dSkamil internal_snprintf(newname, sizeof(newname), name, arg); 4771*ee754c2dSkamil COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, newname); 4772*ee754c2dSkamil return REAL(pthread_setname_np)(thread, name, arg); 4773*ee754c2dSkamil} 4774*ee754c2dSkamil#define INIT_PTHREAD_SETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_setname_np); 4775*ee754c2dSkamil#else 4776*ee754c2dSkamil#define INIT_PTHREAD_SETNAME_NP 4777*ee754c2dSkamil#endif 4778*ee754c2dSkamil 4779*ee754c2dSkamil#if SANITIZER_INTERCEPT_PTHREAD_GETNAME_NP 4780*ee754c2dSkamilINTERCEPTOR(int, pthread_getname_np, uptr thread, char *name, SIZE_T len) { 4781*ee754c2dSkamil void *ctx; 4782*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, pthread_getname_np, thread, name, len); 4783*ee754c2dSkamil int res = REAL(pthread_getname_np)(thread, name, len); 4784*ee754c2dSkamil if (!res) 4785*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, internal_strnlen(name, len) + 1); 4786*ee754c2dSkamil return res; 4787*ee754c2dSkamil} 4788*ee754c2dSkamil#define INIT_PTHREAD_GETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_getname_np); 4789*ee754c2dSkamil#else 4790*ee754c2dSkamil#define INIT_PTHREAD_GETNAME_NP 4791*ee754c2dSkamil#endif 4792*ee754c2dSkamil 4793*ee754c2dSkamil#if SANITIZER_INTERCEPT_SINCOS 4794*ee754c2dSkamilINTERCEPTOR(void, sincos, double x, double *sin, double *cos) { 4795*ee754c2dSkamil void *ctx; 4796*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, sincos, x, sin, cos); 4797*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 4798*ee754c2dSkamil // its metadata. See 4799*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 4800*ee754c2dSkamil REAL(sincos)(x, sin, cos); 4801*ee754c2dSkamil if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin)); 4802*ee754c2dSkamil if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos)); 4803*ee754c2dSkamil} 4804*ee754c2dSkamilINTERCEPTOR(void, sincosf, float x, float *sin, float *cos) { 4805*ee754c2dSkamil void *ctx; 4806*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, sincosf, x, sin, cos); 4807*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 4808*ee754c2dSkamil // its metadata. See 4809*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 4810*ee754c2dSkamil REAL(sincosf)(x, sin, cos); 4811*ee754c2dSkamil if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin)); 4812*ee754c2dSkamil if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos)); 4813*ee754c2dSkamil} 4814*ee754c2dSkamilINTERCEPTOR(void, sincosl, long double x, long double *sin, long double *cos) { 4815*ee754c2dSkamil void *ctx; 4816*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, sincosl, x, sin, cos); 4817*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 4818*ee754c2dSkamil // its metadata. See 4819*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 4820*ee754c2dSkamil REAL(sincosl)(x, sin, cos); 4821*ee754c2dSkamil if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin)); 4822*ee754c2dSkamil if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos)); 4823*ee754c2dSkamil} 4824*ee754c2dSkamil#define INIT_SINCOS \ 4825*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(sincos); \ 4826*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(sincosf); \ 4827*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION_LDBL(sincosl); 4828*ee754c2dSkamil#else 4829*ee754c2dSkamil#define INIT_SINCOS 4830*ee754c2dSkamil#endif 4831*ee754c2dSkamil 4832*ee754c2dSkamil#if SANITIZER_INTERCEPT_REMQUO 4833*ee754c2dSkamilINTERCEPTOR(double, remquo, double x, double y, int *quo) { 4834*ee754c2dSkamil void *ctx; 4835*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, remquo, x, y, quo); 4836*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 4837*ee754c2dSkamil // its metadata. See 4838*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 4839*ee754c2dSkamil double res = REAL(remquo)(x, y, quo); 4840*ee754c2dSkamil if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo)); 4841*ee754c2dSkamil return res; 4842*ee754c2dSkamil} 4843*ee754c2dSkamilINTERCEPTOR(float, remquof, float x, float y, int *quo) { 4844*ee754c2dSkamil void *ctx; 4845*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, remquof, x, y, quo); 4846*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 4847*ee754c2dSkamil // its metadata. See 4848*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 4849*ee754c2dSkamil float res = REAL(remquof)(x, y, quo); 4850*ee754c2dSkamil if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo)); 4851*ee754c2dSkamil return res; 4852*ee754c2dSkamil} 4853*ee754c2dSkamil#define INIT_REMQUO \ 4854*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(remquo); \ 4855*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(remquof); 4856*ee754c2dSkamil#else 4857*ee754c2dSkamil#define INIT_REMQUO 4858*ee754c2dSkamil#endif 4859*ee754c2dSkamil 4860*ee754c2dSkamil#if SANITIZER_INTERCEPT_REMQUOL 4861*ee754c2dSkamilINTERCEPTOR(long double, remquol, long double x, long double y, int *quo) { 4862*ee754c2dSkamil void *ctx; 4863*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, remquol, x, y, quo); 4864*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 4865*ee754c2dSkamil // its metadata. See 4866*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 4867*ee754c2dSkamil long double res = REAL(remquol)(x, y, quo); 4868*ee754c2dSkamil if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo)); 4869*ee754c2dSkamil return res; 4870*ee754c2dSkamil} 4871*ee754c2dSkamil#define INIT_REMQUOL \ 4872*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION_LDBL(remquol); 4873*ee754c2dSkamil#else 4874*ee754c2dSkamil#define INIT_REMQUOL 4875*ee754c2dSkamil#endif 4876*ee754c2dSkamil 4877*ee754c2dSkamil#if SANITIZER_INTERCEPT_LGAMMA 4878*ee754c2dSkamilextern int signgam; 4879*ee754c2dSkamilINTERCEPTOR(double, lgamma, double x) { 4880*ee754c2dSkamil void *ctx; 4881*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, lgamma, x); 4882*ee754c2dSkamil double res = REAL(lgamma)(x); 4883*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam)); 4884*ee754c2dSkamil return res; 4885*ee754c2dSkamil} 4886*ee754c2dSkamilINTERCEPTOR(float, lgammaf, float x) { 4887*ee754c2dSkamil void *ctx; 4888*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, lgammaf, x); 4889*ee754c2dSkamil float res = REAL(lgammaf)(x); 4890*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam)); 4891*ee754c2dSkamil return res; 4892*ee754c2dSkamil} 4893*ee754c2dSkamil#define INIT_LGAMMA \ 4894*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(lgamma); \ 4895*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(lgammaf); 4896*ee754c2dSkamil#else 4897*ee754c2dSkamil#define INIT_LGAMMA 4898*ee754c2dSkamil#endif 4899*ee754c2dSkamil 4900*ee754c2dSkamil#if SANITIZER_INTERCEPT_LGAMMAL 4901*ee754c2dSkamilINTERCEPTOR(long double, lgammal, long double x) { 4902*ee754c2dSkamil void *ctx; 4903*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, lgammal, x); 4904*ee754c2dSkamil long double res = REAL(lgammal)(x); 4905*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam)); 4906*ee754c2dSkamil return res; 4907*ee754c2dSkamil} 4908*ee754c2dSkamil#define INIT_LGAMMAL \ 4909*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION_LDBL(lgammal); 4910*ee754c2dSkamil#else 4911*ee754c2dSkamil#define INIT_LGAMMAL 4912*ee754c2dSkamil#endif 4913*ee754c2dSkamil 4914*ee754c2dSkamil#if SANITIZER_INTERCEPT_LGAMMA_R 4915*ee754c2dSkamilINTERCEPTOR(double, lgamma_r, double x, int *signp) { 4916*ee754c2dSkamil void *ctx; 4917*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, lgamma_r, x, signp); 4918*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 4919*ee754c2dSkamil // its metadata. See 4920*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 4921*ee754c2dSkamil double res = REAL(lgamma_r)(x, signp); 4922*ee754c2dSkamil if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp)); 4923*ee754c2dSkamil return res; 4924*ee754c2dSkamil} 4925*ee754c2dSkamilINTERCEPTOR(float, lgammaf_r, float x, int *signp) { 4926*ee754c2dSkamil void *ctx; 4927*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, lgammaf_r, x, signp); 4928*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 4929*ee754c2dSkamil // its metadata. See 4930*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 4931*ee754c2dSkamil float res = REAL(lgammaf_r)(x, signp); 4932*ee754c2dSkamil if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp)); 4933*ee754c2dSkamil return res; 4934*ee754c2dSkamil} 4935*ee754c2dSkamil#define INIT_LGAMMA_R \ 4936*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(lgamma_r); \ 4937*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(lgammaf_r); 4938*ee754c2dSkamil#else 4939*ee754c2dSkamil#define INIT_LGAMMA_R 4940*ee754c2dSkamil#endif 4941*ee754c2dSkamil 4942*ee754c2dSkamil#if SANITIZER_INTERCEPT_LGAMMAL_R 4943*ee754c2dSkamilINTERCEPTOR(long double, lgammal_r, long double x, int *signp) { 4944*ee754c2dSkamil void *ctx; 4945*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, lgammal_r, x, signp); 4946*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 4947*ee754c2dSkamil // its metadata. See 4948*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 4949*ee754c2dSkamil long double res = REAL(lgammal_r)(x, signp); 4950*ee754c2dSkamil if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp)); 4951*ee754c2dSkamil return res; 4952*ee754c2dSkamil} 4953*ee754c2dSkamil#define INIT_LGAMMAL_R COMMON_INTERCEPT_FUNCTION_LDBL(lgammal_r); 4954*ee754c2dSkamil#else 4955*ee754c2dSkamil#define INIT_LGAMMAL_R 4956*ee754c2dSkamil#endif 4957*ee754c2dSkamil 4958*ee754c2dSkamil#if SANITIZER_INTERCEPT_DRAND48_R 4959*ee754c2dSkamilINTERCEPTOR(int, drand48_r, void *buffer, double *result) { 4960*ee754c2dSkamil void *ctx; 4961*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, drand48_r, buffer, result); 4962*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 4963*ee754c2dSkamil // its metadata. See 4964*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 4965*ee754c2dSkamil int res = REAL(drand48_r)(buffer, result); 4966*ee754c2dSkamil if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 4967*ee754c2dSkamil return res; 4968*ee754c2dSkamil} 4969*ee754c2dSkamilINTERCEPTOR(int, lrand48_r, void *buffer, long *result) { 4970*ee754c2dSkamil void *ctx; 4971*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, lrand48_r, buffer, result); 4972*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 4973*ee754c2dSkamil // its metadata. See 4974*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 4975*ee754c2dSkamil int res = REAL(lrand48_r)(buffer, result); 4976*ee754c2dSkamil if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 4977*ee754c2dSkamil return res; 4978*ee754c2dSkamil} 4979*ee754c2dSkamil#define INIT_DRAND48_R \ 4980*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(drand48_r); \ 4981*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(lrand48_r); 4982*ee754c2dSkamil#else 4983*ee754c2dSkamil#define INIT_DRAND48_R 4984*ee754c2dSkamil#endif 4985*ee754c2dSkamil 4986*ee754c2dSkamil#if SANITIZER_INTERCEPT_RAND_R 4987*ee754c2dSkamilINTERCEPTOR(int, rand_r, unsigned *seedp) { 4988*ee754c2dSkamil void *ctx; 4989*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, rand_r, seedp); 4990*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, seedp, sizeof(*seedp)); 4991*ee754c2dSkamil return REAL(rand_r)(seedp); 4992*ee754c2dSkamil} 4993*ee754c2dSkamil#define INIT_RAND_R COMMON_INTERCEPT_FUNCTION(rand_r); 4994*ee754c2dSkamil#else 4995*ee754c2dSkamil#define INIT_RAND_R 4996*ee754c2dSkamil#endif 4997*ee754c2dSkamil 4998*ee754c2dSkamil#if SANITIZER_INTERCEPT_GETLINE 4999*ee754c2dSkamilINTERCEPTOR(SSIZE_T, getline, char **lineptr, SIZE_T *n, void *stream) { 5000*ee754c2dSkamil void *ctx; 5001*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getline, lineptr, n, stream); 5002*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 5003*ee754c2dSkamil // its metadata. See 5004*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 5005*ee754c2dSkamil SSIZE_T res = REAL(getline)(lineptr, n, stream); 5006*ee754c2dSkamil if (res > 0) { 5007*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr)); 5008*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n)); 5009*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1); 5010*ee754c2dSkamil } 5011*ee754c2dSkamil return res; 5012*ee754c2dSkamil} 5013*ee754c2dSkamil 5014*ee754c2dSkamil// FIXME: under ASan the call below may write to freed memory and corrupt its 5015*ee754c2dSkamil// metadata. See 5016*ee754c2dSkamil// https://github.com/google/sanitizers/issues/321. 5017*ee754c2dSkamil#define GETDELIM_INTERCEPTOR_IMPL(vname) \ 5018*ee754c2dSkamil { \ 5019*ee754c2dSkamil void *ctx; \ 5020*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, vname, lineptr, n, delim, stream); \ 5021*ee754c2dSkamil SSIZE_T res = REAL(vname)(lineptr, n, delim, stream); \ 5022*ee754c2dSkamil if (res > 0) { \ 5023*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr)); \ 5024*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n)); \ 5025*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1); \ 5026*ee754c2dSkamil } \ 5027*ee754c2dSkamil return res; \ 5028*ee754c2dSkamil } 5029*ee754c2dSkamil 5030*ee754c2dSkamilINTERCEPTOR(SSIZE_T, __getdelim, char **lineptr, SIZE_T *n, int delim, 5031*ee754c2dSkamil void *stream) 5032*ee754c2dSkamilGETDELIM_INTERCEPTOR_IMPL(__getdelim) 5033*ee754c2dSkamil 5034*ee754c2dSkamil// There's no __getdelim() on FreeBSD so we supply the getdelim() interceptor 5035*ee754c2dSkamil// with its own body. 5036*ee754c2dSkamilINTERCEPTOR(SSIZE_T, getdelim, char **lineptr, SIZE_T *n, int delim, 5037*ee754c2dSkamil void *stream) 5038*ee754c2dSkamilGETDELIM_INTERCEPTOR_IMPL(getdelim) 5039*ee754c2dSkamil 5040*ee754c2dSkamil#define INIT_GETLINE \ 5041*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(getline); \ 5042*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(__getdelim); \ 5043*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(getdelim); 5044*ee754c2dSkamil#else 5045*ee754c2dSkamil#define INIT_GETLINE 5046*ee754c2dSkamil#endif 5047*ee754c2dSkamil 5048*ee754c2dSkamil#if SANITIZER_INTERCEPT_ICONV 5049*ee754c2dSkamilINTERCEPTOR(SIZE_T, iconv, void *cd, char **inbuf, SIZE_T *inbytesleft, 5050*ee754c2dSkamil char **outbuf, SIZE_T *outbytesleft) { 5051*ee754c2dSkamil void *ctx; 5052*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, iconv, cd, inbuf, inbytesleft, outbuf, 5053*ee754c2dSkamil outbytesleft); 5054*ee754c2dSkamil if (inbytesleft) 5055*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, inbytesleft, sizeof(*inbytesleft)); 5056*ee754c2dSkamil if (inbuf && inbytesleft) 5057*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, *inbuf, *inbytesleft); 5058*ee754c2dSkamil if (outbytesleft) 5059*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, outbytesleft, sizeof(*outbytesleft)); 5060*ee754c2dSkamil void *outbuf_orig = outbuf ? *outbuf : nullptr; 5061*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 5062*ee754c2dSkamil // its metadata. See 5063*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 5064*ee754c2dSkamil SIZE_T res = REAL(iconv)(cd, inbuf, inbytesleft, outbuf, outbytesleft); 5065*ee754c2dSkamil if (outbuf && *outbuf > outbuf_orig) { 5066*ee754c2dSkamil SIZE_T sz = (char *)*outbuf - (char *)outbuf_orig; 5067*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, outbuf_orig, sz); 5068*ee754c2dSkamil } 5069*ee754c2dSkamil return res; 5070*ee754c2dSkamil} 5071*ee754c2dSkamil#define INIT_ICONV COMMON_INTERCEPT_FUNCTION(iconv); 5072*ee754c2dSkamil#else 5073*ee754c2dSkamil#define INIT_ICONV 5074*ee754c2dSkamil#endif 5075*ee754c2dSkamil 5076*ee754c2dSkamil#if SANITIZER_INTERCEPT_TIMES 5077*ee754c2dSkamilINTERCEPTOR(__sanitizer_clock_t, times, void *tms) { 5078*ee754c2dSkamil void *ctx; 5079*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, times, tms); 5080*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 5081*ee754c2dSkamil // its metadata. See 5082*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 5083*ee754c2dSkamil __sanitizer_clock_t res = REAL(times)(tms); 5084*ee754c2dSkamil if (res != (__sanitizer_clock_t)-1 && tms) 5085*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tms, struct_tms_sz); 5086*ee754c2dSkamil return res; 5087*ee754c2dSkamil} 5088*ee754c2dSkamil#define INIT_TIMES COMMON_INTERCEPT_FUNCTION(times); 5089*ee754c2dSkamil#else 5090*ee754c2dSkamil#define INIT_TIMES 5091*ee754c2dSkamil#endif 5092*ee754c2dSkamil 5093*ee754c2dSkamil#if SANITIZER_INTERCEPT_TLS_GET_ADDR 5094*ee754c2dSkamil#if !SANITIZER_S390 5095*ee754c2dSkamil#define INIT_TLS_GET_ADDR COMMON_INTERCEPT_FUNCTION(__tls_get_addr) 5096*ee754c2dSkamil// If you see any crashes around this functions, there are 2 known issues with 5097*ee754c2dSkamil// it: 1. __tls_get_addr can be called with mis-aligned stack due to: 5098*ee754c2dSkamil// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58066 5099*ee754c2dSkamil// 2. It can be called recursively if sanitizer code uses __tls_get_addr 5100*ee754c2dSkamil// to access thread local variables (it should not happen normally, 5101*ee754c2dSkamil// because sanitizers use initial-exec tls model). 5102*ee754c2dSkamilINTERCEPTOR(void *, __tls_get_addr, void *arg) { 5103*ee754c2dSkamil void *ctx; 5104*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, __tls_get_addr, arg); 5105*ee754c2dSkamil void *res = REAL(__tls_get_addr)(arg); 5106*ee754c2dSkamil uptr tls_begin, tls_end; 5107*ee754c2dSkamil COMMON_INTERCEPTOR_GET_TLS_RANGE(&tls_begin, &tls_end); 5108*ee754c2dSkamil DTLS::DTV *dtv = DTLS_on_tls_get_addr(arg, res, tls_begin, tls_end); 5109*ee754c2dSkamil if (dtv) { 5110*ee754c2dSkamil // New DTLS block has been allocated. 5111*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE((void *)dtv->beg, dtv->size); 5112*ee754c2dSkamil } 5113*ee754c2dSkamil return res; 5114*ee754c2dSkamil} 5115*ee754c2dSkamil#if SANITIZER_PPC 5116*ee754c2dSkamil// On PowerPC, we also need to intercept __tls_get_addr_opt, which has 5117*ee754c2dSkamil// mostly the same semantics as __tls_get_addr, but its presence enables 5118*ee754c2dSkamil// some optimizations in linker (which are safe to ignore here). 5119*ee754c2dSkamilextern "C" __attribute__((alias("__interceptor___tls_get_addr"), 5120*ee754c2dSkamil visibility("default"))) 5121*ee754c2dSkamilvoid *__tls_get_addr_opt(void *arg); 5122*ee754c2dSkamil#endif 5123*ee754c2dSkamil#else // SANITIZER_S390 5124*ee754c2dSkamil// On s390, we have to intercept two functions here: 5125*ee754c2dSkamil// - __tls_get_addr_internal, which is a glibc-internal function that is like 5126*ee754c2dSkamil// the usual __tls_get_addr, but returns a TP-relative offset instead of 5127*ee754c2dSkamil// a proper pointer. It is used by dlsym for TLS symbols. 5128*ee754c2dSkamil// - __tls_get_offset, which is like the above, but also takes a GOT-relative 5129*ee754c2dSkamil// descriptor offset as an argument instead of a pointer. GOT address 5130*ee754c2dSkamil// is passed in r12, so it's necessary to write it in assembly. This is 5131*ee754c2dSkamil// the function used by the compiler. 5132*ee754c2dSkamilextern "C" uptr __tls_get_offset_wrapper(void *arg, uptr (*fn)(void *arg)); 5133*ee754c2dSkamil#define INIT_TLS_GET_ADDR COMMON_INTERCEPT_FUNCTION(__tls_get_offset) 5134*ee754c2dSkamilDEFINE_REAL(uptr, __tls_get_offset, void *arg) 5135*ee754c2dSkamilextern "C" uptr __tls_get_offset(void *arg); 5136*ee754c2dSkamilextern "C" uptr __interceptor___tls_get_offset(void *arg); 5137*ee754c2dSkamilINTERCEPTOR(uptr, __tls_get_addr_internal, void *arg) { 5138*ee754c2dSkamil void *ctx; 5139*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, __tls_get_addr_internal, arg); 5140*ee754c2dSkamil uptr res = __tls_get_offset_wrapper(arg, REAL(__tls_get_offset)); 5141*ee754c2dSkamil uptr tp = reinterpret_cast<uptr>(__builtin_thread_pointer()); 5142*ee754c2dSkamil void *ptr = reinterpret_cast<void *>(res + tp); 5143*ee754c2dSkamil uptr tls_begin, tls_end; 5144*ee754c2dSkamil COMMON_INTERCEPTOR_GET_TLS_RANGE(&tls_begin, &tls_end); 5145*ee754c2dSkamil DTLS::DTV *dtv = DTLS_on_tls_get_addr(arg, ptr, tls_begin, tls_end); 5146*ee754c2dSkamil if (dtv) { 5147*ee754c2dSkamil // New DTLS block has been allocated. 5148*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE((void *)dtv->beg, dtv->size); 5149*ee754c2dSkamil } 5150*ee754c2dSkamil return res; 5151*ee754c2dSkamil} 5152*ee754c2dSkamil// We need a hidden symbol aliasing the above, so that we can jump 5153*ee754c2dSkamil// directly to it from the assembly below. 5154*ee754c2dSkamilextern "C" __attribute__((alias("__interceptor___tls_get_addr_internal"), 5155*ee754c2dSkamil visibility("hidden"))) 5156*ee754c2dSkamiluptr __tls_get_addr_hidden(void *arg); 5157*ee754c2dSkamil// Now carefully intercept __tls_get_offset. 5158*ee754c2dSkamilasm( 5159*ee754c2dSkamil ".text\n" 5160*ee754c2dSkamil// The __intercept_ version has to exist, so that gen_dynamic_list.py 5161*ee754c2dSkamil// exports our symbol. 5162*ee754c2dSkamil ".weak __tls_get_offset\n" 5163*ee754c2dSkamil ".type __tls_get_offset, @function\n" 5164*ee754c2dSkamil "__tls_get_offset:\n" 5165*ee754c2dSkamil ".global __interceptor___tls_get_offset\n" 5166*ee754c2dSkamil ".type __interceptor___tls_get_offset, @function\n" 5167*ee754c2dSkamil "__interceptor___tls_get_offset:\n" 5168*ee754c2dSkamil#ifdef __s390x__ 5169*ee754c2dSkamil "la %r2, 0(%r2,%r12)\n" 5170*ee754c2dSkamil "jg __tls_get_addr_hidden\n" 5171*ee754c2dSkamil#else 5172*ee754c2dSkamil "basr %r3,0\n" 5173*ee754c2dSkamil "0: la %r2,0(%r2,%r12)\n" 5174*ee754c2dSkamil "l %r4,1f-0b(%r3)\n" 5175*ee754c2dSkamil "b 0(%r4,%r3)\n" 5176*ee754c2dSkamil "1: .long __tls_get_addr_hidden - 0b\n" 5177*ee754c2dSkamil#endif 5178*ee754c2dSkamil ".size __interceptor___tls_get_offset, .-__interceptor___tls_get_offset\n" 5179*ee754c2dSkamil// Assembly wrapper to call REAL(__tls_get_offset)(arg) 5180*ee754c2dSkamil ".type __tls_get_offset_wrapper, @function\n" 5181*ee754c2dSkamil "__tls_get_offset_wrapper:\n" 5182*ee754c2dSkamil#ifdef __s390x__ 5183*ee754c2dSkamil "sgr %r2,%r12\n" 5184*ee754c2dSkamil#else 5185*ee754c2dSkamil "sr %r2,%r12\n" 5186*ee754c2dSkamil#endif 5187*ee754c2dSkamil "br %r3\n" 5188*ee754c2dSkamil ".size __tls_get_offset_wrapper, .-__tls_get_offset_wrapper\n" 5189*ee754c2dSkamil); 5190*ee754c2dSkamil#endif // SANITIZER_S390 5191*ee754c2dSkamil#else 5192*ee754c2dSkamil#define INIT_TLS_GET_ADDR 5193*ee754c2dSkamil#endif 5194*ee754c2dSkamil 5195*ee754c2dSkamil#if SANITIZER_INTERCEPT_LISTXATTR 5196*ee754c2dSkamilINTERCEPTOR(SSIZE_T, listxattr, const char *path, char *list, SIZE_T size) { 5197*ee754c2dSkamil void *ctx; 5198*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, listxattr, path, list, size); 5199*ee754c2dSkamil if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 5200*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 5201*ee754c2dSkamil // its metadata. See 5202*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 5203*ee754c2dSkamil SSIZE_T res = REAL(listxattr)(path, list, size); 5204*ee754c2dSkamil // Here and below, size == 0 is a special case where nothing is written to the 5205*ee754c2dSkamil // buffer, and res contains the desired buffer size. 5206*ee754c2dSkamil if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res); 5207*ee754c2dSkamil return res; 5208*ee754c2dSkamil} 5209*ee754c2dSkamilINTERCEPTOR(SSIZE_T, llistxattr, const char *path, char *list, SIZE_T size) { 5210*ee754c2dSkamil void *ctx; 5211*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, llistxattr, path, list, size); 5212*ee754c2dSkamil if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 5213*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 5214*ee754c2dSkamil // its metadata. See 5215*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 5216*ee754c2dSkamil SSIZE_T res = REAL(llistxattr)(path, list, size); 5217*ee754c2dSkamil if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res); 5218*ee754c2dSkamil return res; 5219*ee754c2dSkamil} 5220*ee754c2dSkamilINTERCEPTOR(SSIZE_T, flistxattr, int fd, char *list, SIZE_T size) { 5221*ee754c2dSkamil void *ctx; 5222*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, flistxattr, fd, list, size); 5223*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 5224*ee754c2dSkamil // its metadata. See 5225*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 5226*ee754c2dSkamil SSIZE_T res = REAL(flistxattr)(fd, list, size); 5227*ee754c2dSkamil if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res); 5228*ee754c2dSkamil return res; 5229*ee754c2dSkamil} 5230*ee754c2dSkamil#define INIT_LISTXATTR \ 5231*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(listxattr); \ 5232*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(llistxattr); \ 5233*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(flistxattr); 5234*ee754c2dSkamil#else 5235*ee754c2dSkamil#define INIT_LISTXATTR 5236*ee754c2dSkamil#endif 5237*ee754c2dSkamil 5238*ee754c2dSkamil#if SANITIZER_INTERCEPT_GETXATTR 5239*ee754c2dSkamilINTERCEPTOR(SSIZE_T, getxattr, const char *path, const char *name, char *value, 5240*ee754c2dSkamil SIZE_T size) { 5241*ee754c2dSkamil void *ctx; 5242*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getxattr, path, name, value, size); 5243*ee754c2dSkamil if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 5244*ee754c2dSkamil if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 5245*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 5246*ee754c2dSkamil // its metadata. See 5247*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 5248*ee754c2dSkamil SSIZE_T res = REAL(getxattr)(path, name, value, size); 5249*ee754c2dSkamil if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res); 5250*ee754c2dSkamil return res; 5251*ee754c2dSkamil} 5252*ee754c2dSkamilINTERCEPTOR(SSIZE_T, lgetxattr, const char *path, const char *name, char *value, 5253*ee754c2dSkamil SIZE_T size) { 5254*ee754c2dSkamil void *ctx; 5255*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, lgetxattr, path, name, value, size); 5256*ee754c2dSkamil if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 5257*ee754c2dSkamil if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 5258*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 5259*ee754c2dSkamil // its metadata. See 5260*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 5261*ee754c2dSkamil SSIZE_T res = REAL(lgetxattr)(path, name, value, size); 5262*ee754c2dSkamil if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res); 5263*ee754c2dSkamil return res; 5264*ee754c2dSkamil} 5265*ee754c2dSkamilINTERCEPTOR(SSIZE_T, fgetxattr, int fd, const char *name, char *value, 5266*ee754c2dSkamil SIZE_T size) { 5267*ee754c2dSkamil void *ctx; 5268*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, fgetxattr, fd, name, value, size); 5269*ee754c2dSkamil if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 5270*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 5271*ee754c2dSkamil // its metadata. See 5272*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 5273*ee754c2dSkamil SSIZE_T res = REAL(fgetxattr)(fd, name, value, size); 5274*ee754c2dSkamil if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res); 5275*ee754c2dSkamil return res; 5276*ee754c2dSkamil} 5277*ee754c2dSkamil#define INIT_GETXATTR \ 5278*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(getxattr); \ 5279*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(lgetxattr); \ 5280*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(fgetxattr); 5281*ee754c2dSkamil#else 5282*ee754c2dSkamil#define INIT_GETXATTR 5283*ee754c2dSkamil#endif 5284*ee754c2dSkamil 5285*ee754c2dSkamil#if SANITIZER_INTERCEPT_GETRESID 5286*ee754c2dSkamilINTERCEPTOR(int, getresuid, void *ruid, void *euid, void *suid) { 5287*ee754c2dSkamil void *ctx; 5288*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getresuid, ruid, euid, suid); 5289*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 5290*ee754c2dSkamil // its metadata. See 5291*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 5292*ee754c2dSkamil int res = REAL(getresuid)(ruid, euid, suid); 5293*ee754c2dSkamil if (res >= 0) { 5294*ee754c2dSkamil if (ruid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ruid, uid_t_sz); 5295*ee754c2dSkamil if (euid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, euid, uid_t_sz); 5296*ee754c2dSkamil if (suid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, suid, uid_t_sz); 5297*ee754c2dSkamil } 5298*ee754c2dSkamil return res; 5299*ee754c2dSkamil} 5300*ee754c2dSkamilINTERCEPTOR(int, getresgid, void *rgid, void *egid, void *sgid) { 5301*ee754c2dSkamil void *ctx; 5302*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getresgid, rgid, egid, sgid); 5303*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 5304*ee754c2dSkamil // its metadata. See 5305*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 5306*ee754c2dSkamil int res = REAL(getresgid)(rgid, egid, sgid); 5307*ee754c2dSkamil if (res >= 0) { 5308*ee754c2dSkamil if (rgid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rgid, gid_t_sz); 5309*ee754c2dSkamil if (egid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, egid, gid_t_sz); 5310*ee754c2dSkamil if (sgid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sgid, gid_t_sz); 5311*ee754c2dSkamil } 5312*ee754c2dSkamil return res; 5313*ee754c2dSkamil} 5314*ee754c2dSkamil#define INIT_GETRESID \ 5315*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(getresuid); \ 5316*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(getresgid); 5317*ee754c2dSkamil#else 5318*ee754c2dSkamil#define INIT_GETRESID 5319*ee754c2dSkamil#endif 5320*ee754c2dSkamil 5321*ee754c2dSkamil#if SANITIZER_INTERCEPT_GETIFADDRS 5322*ee754c2dSkamil// As long as getifaddrs()/freeifaddrs() use calloc()/free(), we don't need to 5323*ee754c2dSkamil// intercept freeifaddrs(). If that ceases to be the case, we might need to 5324*ee754c2dSkamil// intercept it to poison the memory again. 5325*ee754c2dSkamilINTERCEPTOR(int, getifaddrs, __sanitizer_ifaddrs **ifap) { 5326*ee754c2dSkamil void *ctx; 5327*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getifaddrs, ifap); 5328*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 5329*ee754c2dSkamil // its metadata. See 5330*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 5331*ee754c2dSkamil int res = REAL(getifaddrs)(ifap); 5332*ee754c2dSkamil if (res == 0 && ifap) { 5333*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifap, sizeof(void *)); 5334*ee754c2dSkamil __sanitizer_ifaddrs *p = *ifap; 5335*ee754c2dSkamil while (p) { 5336*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(__sanitizer_ifaddrs)); 5337*ee754c2dSkamil if (p->ifa_name) 5338*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_name, 5339*ee754c2dSkamil REAL(strlen)(p->ifa_name) + 1); 5340*ee754c2dSkamil if (p->ifa_addr) 5341*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_addr, struct_sockaddr_sz); 5342*ee754c2dSkamil if (p->ifa_netmask) 5343*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_netmask, struct_sockaddr_sz); 5344*ee754c2dSkamil // On Linux this is a union, but the other member also points to a 5345*ee754c2dSkamil // struct sockaddr, so the following is sufficient. 5346*ee754c2dSkamil if (p->ifa_dstaddr) 5347*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_dstaddr, struct_sockaddr_sz); 5348*ee754c2dSkamil // FIXME(smatveev): Unpoison p->ifa_data as well. 5349*ee754c2dSkamil p = p->ifa_next; 5350*ee754c2dSkamil } 5351*ee754c2dSkamil } 5352*ee754c2dSkamil return res; 5353*ee754c2dSkamil} 5354*ee754c2dSkamil#define INIT_GETIFADDRS \ 5355*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(getifaddrs); 5356*ee754c2dSkamil#else 5357*ee754c2dSkamil#define INIT_GETIFADDRS 5358*ee754c2dSkamil#endif 5359*ee754c2dSkamil 5360*ee754c2dSkamil#if SANITIZER_INTERCEPT_IF_INDEXTONAME 5361*ee754c2dSkamilINTERCEPTOR(char *, if_indextoname, unsigned int ifindex, char* ifname) { 5362*ee754c2dSkamil void *ctx; 5363*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, if_indextoname, ifindex, ifname); 5364*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 5365*ee754c2dSkamil // its metadata. See 5366*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 5367*ee754c2dSkamil char *res = REAL(if_indextoname)(ifindex, ifname); 5368*ee754c2dSkamil if (res && ifname) 5369*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifname, REAL(strlen)(ifname) + 1); 5370*ee754c2dSkamil return res; 5371*ee754c2dSkamil} 5372*ee754c2dSkamilINTERCEPTOR(unsigned int, if_nametoindex, const char* ifname) { 5373*ee754c2dSkamil void *ctx; 5374*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, if_nametoindex, ifname); 5375*ee754c2dSkamil if (ifname) 5376*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, ifname, REAL(strlen)(ifname) + 1); 5377*ee754c2dSkamil return REAL(if_nametoindex)(ifname); 5378*ee754c2dSkamil} 5379*ee754c2dSkamil#define INIT_IF_INDEXTONAME \ 5380*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(if_indextoname); \ 5381*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(if_nametoindex); 5382*ee754c2dSkamil#else 5383*ee754c2dSkamil#define INIT_IF_INDEXTONAME 5384*ee754c2dSkamil#endif 5385*ee754c2dSkamil 5386*ee754c2dSkamil#if SANITIZER_INTERCEPT_CAPGET 5387*ee754c2dSkamilINTERCEPTOR(int, capget, void *hdrp, void *datap) { 5388*ee754c2dSkamil void *ctx; 5389*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, capget, hdrp, datap); 5390*ee754c2dSkamil if (hdrp) 5391*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, hdrp, __user_cap_header_struct_sz); 5392*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 5393*ee754c2dSkamil // its metadata. See 5394*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 5395*ee754c2dSkamil int res = REAL(capget)(hdrp, datap); 5396*ee754c2dSkamil if (res == 0 && datap) 5397*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, datap, __user_cap_data_struct_sz); 5398*ee754c2dSkamil // We can also return -1 and write to hdrp->version if the version passed in 5399*ee754c2dSkamil // hdrp->version is unsupported. But that's not a trivial condition to check, 5400*ee754c2dSkamil // and anyway COMMON_INTERCEPTOR_READ_RANGE protects us to some extent. 5401*ee754c2dSkamil return res; 5402*ee754c2dSkamil} 5403*ee754c2dSkamilINTERCEPTOR(int, capset, void *hdrp, const void *datap) { 5404*ee754c2dSkamil void *ctx; 5405*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, capset, hdrp, datap); 5406*ee754c2dSkamil if (hdrp) 5407*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, hdrp, __user_cap_header_struct_sz); 5408*ee754c2dSkamil if (datap) 5409*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, datap, __user_cap_data_struct_sz); 5410*ee754c2dSkamil return REAL(capset)(hdrp, datap); 5411*ee754c2dSkamil} 5412*ee754c2dSkamil#define INIT_CAPGET \ 5413*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(capget); \ 5414*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(capset); 5415*ee754c2dSkamil#else 5416*ee754c2dSkamil#define INIT_CAPGET 5417*ee754c2dSkamil#endif 5418*ee754c2dSkamil 5419*ee754c2dSkamil#if SANITIZER_INTERCEPT_AEABI_MEM 5420*ee754c2dSkamilINTERCEPTOR(void *, __aeabi_memmove, void *to, const void *from, uptr size) { 5421*ee754c2dSkamil void *ctx; 5422*ee754c2dSkamil COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size); 5423*ee754c2dSkamil} 5424*ee754c2dSkamil 5425*ee754c2dSkamilINTERCEPTOR(void *, __aeabi_memmove4, void *to, const void *from, uptr size) { 5426*ee754c2dSkamil void *ctx; 5427*ee754c2dSkamil COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size); 5428*ee754c2dSkamil} 5429*ee754c2dSkamil 5430*ee754c2dSkamilINTERCEPTOR(void *, __aeabi_memmove8, void *to, const void *from, uptr size) { 5431*ee754c2dSkamil void *ctx; 5432*ee754c2dSkamil COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size); 5433*ee754c2dSkamil} 5434*ee754c2dSkamil 5435*ee754c2dSkamilINTERCEPTOR(void *, __aeabi_memcpy, void *to, const void *from, uptr size) { 5436*ee754c2dSkamil void *ctx; 5437*ee754c2dSkamil COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size); 5438*ee754c2dSkamil} 5439*ee754c2dSkamil 5440*ee754c2dSkamilINTERCEPTOR(void *, __aeabi_memcpy4, void *to, const void *from, uptr size) { 5441*ee754c2dSkamil void *ctx; 5442*ee754c2dSkamil COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size); 5443*ee754c2dSkamil} 5444*ee754c2dSkamil 5445*ee754c2dSkamilINTERCEPTOR(void *, __aeabi_memcpy8, void *to, const void *from, uptr size) { 5446*ee754c2dSkamil void *ctx; 5447*ee754c2dSkamil COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size); 5448*ee754c2dSkamil} 5449*ee754c2dSkamil 5450*ee754c2dSkamil// Note the argument order. 5451*ee754c2dSkamilINTERCEPTOR(void *, __aeabi_memset, void *block, uptr size, int c) { 5452*ee754c2dSkamil void *ctx; 5453*ee754c2dSkamil COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size); 5454*ee754c2dSkamil} 5455*ee754c2dSkamil 5456*ee754c2dSkamilINTERCEPTOR(void *, __aeabi_memset4, void *block, uptr size, int c) { 5457*ee754c2dSkamil void *ctx; 5458*ee754c2dSkamil COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size); 5459*ee754c2dSkamil} 5460*ee754c2dSkamil 5461*ee754c2dSkamilINTERCEPTOR(void *, __aeabi_memset8, void *block, uptr size, int c) { 5462*ee754c2dSkamil void *ctx; 5463*ee754c2dSkamil COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size); 5464*ee754c2dSkamil} 5465*ee754c2dSkamil 5466*ee754c2dSkamilINTERCEPTOR(void *, __aeabi_memclr, void *block, uptr size) { 5467*ee754c2dSkamil void *ctx; 5468*ee754c2dSkamil COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size); 5469*ee754c2dSkamil} 5470*ee754c2dSkamil 5471*ee754c2dSkamilINTERCEPTOR(void *, __aeabi_memclr4, void *block, uptr size) { 5472*ee754c2dSkamil void *ctx; 5473*ee754c2dSkamil COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size); 5474*ee754c2dSkamil} 5475*ee754c2dSkamil 5476*ee754c2dSkamilINTERCEPTOR(void *, __aeabi_memclr8, void *block, uptr size) { 5477*ee754c2dSkamil void *ctx; 5478*ee754c2dSkamil COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size); 5479*ee754c2dSkamil} 5480*ee754c2dSkamil 5481*ee754c2dSkamil#define INIT_AEABI_MEM \ 5482*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(__aeabi_memmove); \ 5483*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(__aeabi_memmove4); \ 5484*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(__aeabi_memmove8); \ 5485*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy); \ 5486*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy4); \ 5487*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy8); \ 5488*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(__aeabi_memset); \ 5489*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(__aeabi_memset4); \ 5490*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(__aeabi_memset8); \ 5491*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(__aeabi_memclr); \ 5492*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(__aeabi_memclr4); \ 5493*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(__aeabi_memclr8); 5494*ee754c2dSkamil#else 5495*ee754c2dSkamil#define INIT_AEABI_MEM 5496*ee754c2dSkamil#endif // SANITIZER_INTERCEPT_AEABI_MEM 5497*ee754c2dSkamil 5498*ee754c2dSkamil#if SANITIZER_INTERCEPT___BZERO 5499*ee754c2dSkamilINTERCEPTOR(void *, __bzero, void *block, uptr size) { 5500*ee754c2dSkamil void *ctx; 5501*ee754c2dSkamil COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size); 5502*ee754c2dSkamil} 5503*ee754c2dSkamil 5504*ee754c2dSkamil#define INIT___BZERO COMMON_INTERCEPT_FUNCTION(__bzero); 5505*ee754c2dSkamil#else 5506*ee754c2dSkamil#define INIT___BZERO 5507*ee754c2dSkamil#endif // SANITIZER_INTERCEPT___BZERO 5508*ee754c2dSkamil 5509*ee754c2dSkamil#if SANITIZER_INTERCEPT_FTIME 5510*ee754c2dSkamilINTERCEPTOR(int, ftime, __sanitizer_timeb *tp) { 5511*ee754c2dSkamil void *ctx; 5512*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, ftime, tp); 5513*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 5514*ee754c2dSkamil // its metadata. See 5515*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 5516*ee754c2dSkamil int res = REAL(ftime)(tp); 5517*ee754c2dSkamil if (tp) 5518*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, sizeof(*tp)); 5519*ee754c2dSkamil return res; 5520*ee754c2dSkamil} 5521*ee754c2dSkamil#define INIT_FTIME COMMON_INTERCEPT_FUNCTION(ftime); 5522*ee754c2dSkamil#else 5523*ee754c2dSkamil#define INIT_FTIME 5524*ee754c2dSkamil#endif // SANITIZER_INTERCEPT_FTIME 5525*ee754c2dSkamil 5526*ee754c2dSkamil#if SANITIZER_INTERCEPT_XDR 5527*ee754c2dSkamilINTERCEPTOR(void, xdrmem_create, __sanitizer_XDR *xdrs, uptr addr, 5528*ee754c2dSkamil unsigned size, int op) { 5529*ee754c2dSkamil void *ctx; 5530*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, xdrmem_create, xdrs, addr, size, op); 5531*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 5532*ee754c2dSkamil // its metadata. See 5533*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 5534*ee754c2dSkamil REAL(xdrmem_create)(xdrs, addr, size, op); 5535*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdrs, sizeof(*xdrs)); 5536*ee754c2dSkamil if (op == __sanitizer_XDR_ENCODE) { 5537*ee754c2dSkamil // It's not obvious how much data individual xdr_ routines write. 5538*ee754c2dSkamil // Simply unpoison the entire target buffer in advance. 5539*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (void *)addr, size); 5540*ee754c2dSkamil } 5541*ee754c2dSkamil} 5542*ee754c2dSkamil 5543*ee754c2dSkamilINTERCEPTOR(void, xdrstdio_create, __sanitizer_XDR *xdrs, void *file, int op) { 5544*ee754c2dSkamil void *ctx; 5545*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, xdrstdio_create, xdrs, file, op); 5546*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 5547*ee754c2dSkamil // its metadata. See 5548*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 5549*ee754c2dSkamil REAL(xdrstdio_create)(xdrs, file, op); 5550*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdrs, sizeof(*xdrs)); 5551*ee754c2dSkamil} 5552*ee754c2dSkamil 5553*ee754c2dSkamil// FIXME: under ASan the call below may write to freed memory and corrupt 5554*ee754c2dSkamil// its metadata. See 5555*ee754c2dSkamil// https://github.com/google/sanitizers/issues/321. 5556*ee754c2dSkamil#define XDR_INTERCEPTOR(F, T) \ 5557*ee754c2dSkamil INTERCEPTOR(int, F, __sanitizer_XDR *xdrs, T *p) { \ 5558*ee754c2dSkamil void *ctx; \ 5559*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, F, xdrs, p); \ 5560*ee754c2dSkamil if (p && xdrs->x_op == __sanitizer_XDR_ENCODE) \ 5561*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p)); \ 5562*ee754c2dSkamil int res = REAL(F)(xdrs, p); \ 5563*ee754c2dSkamil if (res && p && xdrs->x_op == __sanitizer_XDR_DECODE) \ 5564*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); \ 5565*ee754c2dSkamil return res; \ 5566*ee754c2dSkamil } 5567*ee754c2dSkamil 5568*ee754c2dSkamilXDR_INTERCEPTOR(xdr_short, short) 5569*ee754c2dSkamilXDR_INTERCEPTOR(xdr_u_short, unsigned short) 5570*ee754c2dSkamilXDR_INTERCEPTOR(xdr_int, int) 5571*ee754c2dSkamilXDR_INTERCEPTOR(xdr_u_int, unsigned) 5572*ee754c2dSkamilXDR_INTERCEPTOR(xdr_long, long) 5573*ee754c2dSkamilXDR_INTERCEPTOR(xdr_u_long, unsigned long) 5574*ee754c2dSkamilXDR_INTERCEPTOR(xdr_hyper, long long) 5575*ee754c2dSkamilXDR_INTERCEPTOR(xdr_u_hyper, unsigned long long) 5576*ee754c2dSkamilXDR_INTERCEPTOR(xdr_longlong_t, long long) 5577*ee754c2dSkamilXDR_INTERCEPTOR(xdr_u_longlong_t, unsigned long long) 5578*ee754c2dSkamilXDR_INTERCEPTOR(xdr_int8_t, u8) 5579*ee754c2dSkamilXDR_INTERCEPTOR(xdr_uint8_t, u8) 5580*ee754c2dSkamilXDR_INTERCEPTOR(xdr_int16_t, u16) 5581*ee754c2dSkamilXDR_INTERCEPTOR(xdr_uint16_t, u16) 5582*ee754c2dSkamilXDR_INTERCEPTOR(xdr_int32_t, u32) 5583*ee754c2dSkamilXDR_INTERCEPTOR(xdr_uint32_t, u32) 5584*ee754c2dSkamilXDR_INTERCEPTOR(xdr_int64_t, u64) 5585*ee754c2dSkamilXDR_INTERCEPTOR(xdr_uint64_t, u64) 5586*ee754c2dSkamilXDR_INTERCEPTOR(xdr_quad_t, long long) 5587*ee754c2dSkamilXDR_INTERCEPTOR(xdr_u_quad_t, unsigned long long) 5588*ee754c2dSkamilXDR_INTERCEPTOR(xdr_bool, bool) 5589*ee754c2dSkamilXDR_INTERCEPTOR(xdr_enum, int) 5590*ee754c2dSkamilXDR_INTERCEPTOR(xdr_char, char) 5591*ee754c2dSkamilXDR_INTERCEPTOR(xdr_u_char, unsigned char) 5592*ee754c2dSkamilXDR_INTERCEPTOR(xdr_float, float) 5593*ee754c2dSkamilXDR_INTERCEPTOR(xdr_double, double) 5594*ee754c2dSkamil 5595*ee754c2dSkamil// FIXME: intercept xdr_array, opaque, union, vector, reference, pointer, 5596*ee754c2dSkamil// wrapstring, sizeof 5597*ee754c2dSkamil 5598*ee754c2dSkamilINTERCEPTOR(int, xdr_bytes, __sanitizer_XDR *xdrs, char **p, unsigned *sizep, 5599*ee754c2dSkamil unsigned maxsize) { 5600*ee754c2dSkamil void *ctx; 5601*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, xdr_bytes, xdrs, p, sizep, maxsize); 5602*ee754c2dSkamil if (p && sizep && xdrs->x_op == __sanitizer_XDR_ENCODE) { 5603*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p)); 5604*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, sizep, sizeof(*sizep)); 5605*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, *p, *sizep); 5606*ee754c2dSkamil } 5607*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 5608*ee754c2dSkamil // its metadata. See 5609*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 5610*ee754c2dSkamil int res = REAL(xdr_bytes)(xdrs, p, sizep, maxsize); 5611*ee754c2dSkamil if (p && sizep && xdrs->x_op == __sanitizer_XDR_DECODE) { 5612*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); 5613*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizep, sizeof(*sizep)); 5614*ee754c2dSkamil if (res && *p && *sizep) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, *sizep); 5615*ee754c2dSkamil } 5616*ee754c2dSkamil return res; 5617*ee754c2dSkamil} 5618*ee754c2dSkamil 5619*ee754c2dSkamilINTERCEPTOR(int, xdr_string, __sanitizer_XDR *xdrs, char **p, 5620*ee754c2dSkamil unsigned maxsize) { 5621*ee754c2dSkamil void *ctx; 5622*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, xdr_string, xdrs, p, maxsize); 5623*ee754c2dSkamil if (p && xdrs->x_op == __sanitizer_XDR_ENCODE) { 5624*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p)); 5625*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, *p, REAL(strlen)(*p) + 1); 5626*ee754c2dSkamil } 5627*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 5628*ee754c2dSkamil // its metadata. See 5629*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 5630*ee754c2dSkamil int res = REAL(xdr_string)(xdrs, p, maxsize); 5631*ee754c2dSkamil if (p && xdrs->x_op == __sanitizer_XDR_DECODE) { 5632*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); 5633*ee754c2dSkamil if (res && *p) 5634*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1); 5635*ee754c2dSkamil } 5636*ee754c2dSkamil return res; 5637*ee754c2dSkamil} 5638*ee754c2dSkamil 5639*ee754c2dSkamil#define INIT_XDR \ 5640*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(xdrmem_create); \ 5641*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(xdrstdio_create); \ 5642*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(xdr_short); \ 5643*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(xdr_u_short); \ 5644*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(xdr_int); \ 5645*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(xdr_u_int); \ 5646*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(xdr_long); \ 5647*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(xdr_u_long); \ 5648*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(xdr_hyper); \ 5649*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(xdr_u_hyper); \ 5650*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(xdr_longlong_t); \ 5651*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(xdr_u_longlong_t); \ 5652*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(xdr_int8_t); \ 5653*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(xdr_uint8_t); \ 5654*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(xdr_int16_t); \ 5655*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(xdr_uint16_t); \ 5656*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(xdr_int32_t); \ 5657*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(xdr_uint32_t); \ 5658*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(xdr_int64_t); \ 5659*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(xdr_uint64_t); \ 5660*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(xdr_quad_t); \ 5661*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(xdr_u_quad_t); \ 5662*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(xdr_bool); \ 5663*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(xdr_enum); \ 5664*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(xdr_char); \ 5665*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(xdr_u_char); \ 5666*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(xdr_float); \ 5667*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(xdr_double); \ 5668*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(xdr_bytes); \ 5669*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(xdr_string); 5670*ee754c2dSkamil#else 5671*ee754c2dSkamil#define INIT_XDR 5672*ee754c2dSkamil#endif // SANITIZER_INTERCEPT_XDR 5673*ee754c2dSkamil 5674*ee754c2dSkamil#if SANITIZER_INTERCEPT_TSEARCH 5675*ee754c2dSkamilINTERCEPTOR(void *, tsearch, void *key, void **rootp, 5676*ee754c2dSkamil int (*compar)(const void *, const void *)) { 5677*ee754c2dSkamil void *ctx; 5678*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, tsearch, key, rootp, compar); 5679*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 5680*ee754c2dSkamil // its metadata. See 5681*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 5682*ee754c2dSkamil void *res = REAL(tsearch)(key, rootp, compar); 5683*ee754c2dSkamil if (res && *(void **)res == key) 5684*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(void *)); 5685*ee754c2dSkamil return res; 5686*ee754c2dSkamil} 5687*ee754c2dSkamil#define INIT_TSEARCH COMMON_INTERCEPT_FUNCTION(tsearch); 5688*ee754c2dSkamil#else 5689*ee754c2dSkamil#define INIT_TSEARCH 5690*ee754c2dSkamil#endif 5691*ee754c2dSkamil 5692*ee754c2dSkamil#if SANITIZER_INTERCEPT_LIBIO_INTERNALS || SANITIZER_INTERCEPT_FOPEN || \ 5693*ee754c2dSkamil SANITIZER_INTERCEPT_OPEN_MEMSTREAM 5694*ee754c2dSkamilvoid unpoison_file(__sanitizer_FILE *fp) { 5695*ee754c2dSkamil#if SANITIZER_HAS_STRUCT_FILE 5696*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp, sizeof(*fp)); 5697*ee754c2dSkamil if (fp->_IO_read_base && fp->_IO_read_base < fp->_IO_read_end) 5698*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp->_IO_read_base, 5699*ee754c2dSkamil fp->_IO_read_end - fp->_IO_read_base); 5700*ee754c2dSkamil#endif // SANITIZER_HAS_STRUCT_FILE 5701*ee754c2dSkamil} 5702*ee754c2dSkamil#endif 5703*ee754c2dSkamil 5704*ee754c2dSkamil#if SANITIZER_INTERCEPT_LIBIO_INTERNALS 5705*ee754c2dSkamil// These guys are called when a .c source is built with -O2. 5706*ee754c2dSkamilINTERCEPTOR(int, __uflow, __sanitizer_FILE *fp) { 5707*ee754c2dSkamil void *ctx; 5708*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, __uflow, fp); 5709*ee754c2dSkamil int res = REAL(__uflow)(fp); 5710*ee754c2dSkamil unpoison_file(fp); 5711*ee754c2dSkamil return res; 5712*ee754c2dSkamil} 5713*ee754c2dSkamilINTERCEPTOR(int, __underflow, __sanitizer_FILE *fp) { 5714*ee754c2dSkamil void *ctx; 5715*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, __underflow, fp); 5716*ee754c2dSkamil int res = REAL(__underflow)(fp); 5717*ee754c2dSkamil unpoison_file(fp); 5718*ee754c2dSkamil return res; 5719*ee754c2dSkamil} 5720*ee754c2dSkamilINTERCEPTOR(int, __overflow, __sanitizer_FILE *fp, int ch) { 5721*ee754c2dSkamil void *ctx; 5722*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, __overflow, fp, ch); 5723*ee754c2dSkamil int res = REAL(__overflow)(fp, ch); 5724*ee754c2dSkamil unpoison_file(fp); 5725*ee754c2dSkamil return res; 5726*ee754c2dSkamil} 5727*ee754c2dSkamilINTERCEPTOR(int, __wuflow, __sanitizer_FILE *fp) { 5728*ee754c2dSkamil void *ctx; 5729*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, __wuflow, fp); 5730*ee754c2dSkamil int res = REAL(__wuflow)(fp); 5731*ee754c2dSkamil unpoison_file(fp); 5732*ee754c2dSkamil return res; 5733*ee754c2dSkamil} 5734*ee754c2dSkamilINTERCEPTOR(int, __wunderflow, __sanitizer_FILE *fp) { 5735*ee754c2dSkamil void *ctx; 5736*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, __wunderflow, fp); 5737*ee754c2dSkamil int res = REAL(__wunderflow)(fp); 5738*ee754c2dSkamil unpoison_file(fp); 5739*ee754c2dSkamil return res; 5740*ee754c2dSkamil} 5741*ee754c2dSkamilINTERCEPTOR(int, __woverflow, __sanitizer_FILE *fp, int ch) { 5742*ee754c2dSkamil void *ctx; 5743*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, __woverflow, fp, ch); 5744*ee754c2dSkamil int res = REAL(__woverflow)(fp, ch); 5745*ee754c2dSkamil unpoison_file(fp); 5746*ee754c2dSkamil return res; 5747*ee754c2dSkamil} 5748*ee754c2dSkamil#define INIT_LIBIO_INTERNALS \ 5749*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(__uflow); \ 5750*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(__underflow); \ 5751*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(__overflow); \ 5752*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(__wuflow); \ 5753*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(__wunderflow); \ 5754*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(__woverflow); 5755*ee754c2dSkamil#else 5756*ee754c2dSkamil#define INIT_LIBIO_INTERNALS 5757*ee754c2dSkamil#endif 5758*ee754c2dSkamil 5759*ee754c2dSkamil#if SANITIZER_INTERCEPT_FOPEN 5760*ee754c2dSkamilINTERCEPTOR(__sanitizer_FILE *, fopen, const char *path, const char *mode) { 5761*ee754c2dSkamil void *ctx; 5762*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, fopen, path, mode); 5763*ee754c2dSkamil if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 5764*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1); 5765*ee754c2dSkamil __sanitizer_FILE *res = REAL(fopen)(path, mode); 5766*ee754c2dSkamil COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path); 5767*ee754c2dSkamil if (res) unpoison_file(res); 5768*ee754c2dSkamil return res; 5769*ee754c2dSkamil} 5770*ee754c2dSkamilINTERCEPTOR(__sanitizer_FILE *, fdopen, int fd, const char *mode) { 5771*ee754c2dSkamil void *ctx; 5772*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, fdopen, fd, mode); 5773*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1); 5774*ee754c2dSkamil __sanitizer_FILE *res = REAL(fdopen)(fd, mode); 5775*ee754c2dSkamil if (res) unpoison_file(res); 5776*ee754c2dSkamil return res; 5777*ee754c2dSkamil} 5778*ee754c2dSkamilINTERCEPTOR(__sanitizer_FILE *, freopen, const char *path, const char *mode, 5779*ee754c2dSkamil __sanitizer_FILE *fp) { 5780*ee754c2dSkamil void *ctx; 5781*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, freopen, path, mode, fp); 5782*ee754c2dSkamil if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 5783*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1); 5784*ee754c2dSkamil COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp); 5785*ee754c2dSkamil __sanitizer_FILE *res = REAL(freopen)(path, mode, fp); 5786*ee754c2dSkamil COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path); 5787*ee754c2dSkamil if (res) unpoison_file(res); 5788*ee754c2dSkamil return res; 5789*ee754c2dSkamil} 5790*ee754c2dSkamil#define INIT_FOPEN \ 5791*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(fopen); \ 5792*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(fdopen); \ 5793*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(freopen); 5794*ee754c2dSkamil#else 5795*ee754c2dSkamil#define INIT_FOPEN 5796*ee754c2dSkamil#endif 5797*ee754c2dSkamil 5798*ee754c2dSkamil#if SANITIZER_INTERCEPT_FOPEN64 5799*ee754c2dSkamilINTERCEPTOR(__sanitizer_FILE *, fopen64, const char *path, const char *mode) { 5800*ee754c2dSkamil void *ctx; 5801*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, fopen64, path, mode); 5802*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 5803*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1); 5804*ee754c2dSkamil __sanitizer_FILE *res = REAL(fopen64)(path, mode); 5805*ee754c2dSkamil COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path); 5806*ee754c2dSkamil if (res) unpoison_file(res); 5807*ee754c2dSkamil return res; 5808*ee754c2dSkamil} 5809*ee754c2dSkamilINTERCEPTOR(__sanitizer_FILE *, freopen64, const char *path, const char *mode, 5810*ee754c2dSkamil __sanitizer_FILE *fp) { 5811*ee754c2dSkamil void *ctx; 5812*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, freopen64, path, mode, fp); 5813*ee754c2dSkamil if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 5814*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1); 5815*ee754c2dSkamil COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp); 5816*ee754c2dSkamil __sanitizer_FILE *res = REAL(freopen64)(path, mode, fp); 5817*ee754c2dSkamil COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path); 5818*ee754c2dSkamil if (res) unpoison_file(res); 5819*ee754c2dSkamil return res; 5820*ee754c2dSkamil} 5821*ee754c2dSkamil#define INIT_FOPEN64 \ 5822*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(fopen64); \ 5823*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(freopen64); 5824*ee754c2dSkamil#else 5825*ee754c2dSkamil#define INIT_FOPEN64 5826*ee754c2dSkamil#endif 5827*ee754c2dSkamil 5828*ee754c2dSkamil#if SANITIZER_INTERCEPT_OPEN_MEMSTREAM 5829*ee754c2dSkamilINTERCEPTOR(__sanitizer_FILE *, open_memstream, char **ptr, SIZE_T *sizeloc) { 5830*ee754c2dSkamil void *ctx; 5831*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, open_memstream, ptr, sizeloc); 5832*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 5833*ee754c2dSkamil // its metadata. See 5834*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 5835*ee754c2dSkamil __sanitizer_FILE *res = REAL(open_memstream)(ptr, sizeloc); 5836*ee754c2dSkamil if (res) { 5837*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, sizeof(*ptr)); 5838*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizeloc, sizeof(*sizeloc)); 5839*ee754c2dSkamil unpoison_file(res); 5840*ee754c2dSkamil FileMetadata file = {ptr, sizeloc}; 5841*ee754c2dSkamil SetInterceptorMetadata(res, file); 5842*ee754c2dSkamil } 5843*ee754c2dSkamil return res; 5844*ee754c2dSkamil} 5845*ee754c2dSkamilINTERCEPTOR(__sanitizer_FILE *, open_wmemstream, wchar_t **ptr, 5846*ee754c2dSkamil SIZE_T *sizeloc) { 5847*ee754c2dSkamil void *ctx; 5848*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, open_wmemstream, ptr, sizeloc); 5849*ee754c2dSkamil __sanitizer_FILE *res = REAL(open_wmemstream)(ptr, sizeloc); 5850*ee754c2dSkamil if (res) { 5851*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, sizeof(*ptr)); 5852*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizeloc, sizeof(*sizeloc)); 5853*ee754c2dSkamil unpoison_file(res); 5854*ee754c2dSkamil FileMetadata file = {(char **)ptr, sizeloc}; 5855*ee754c2dSkamil SetInterceptorMetadata(res, file); 5856*ee754c2dSkamil } 5857*ee754c2dSkamil return res; 5858*ee754c2dSkamil} 5859*ee754c2dSkamilINTERCEPTOR(__sanitizer_FILE *, fmemopen, void *buf, SIZE_T size, 5860*ee754c2dSkamil const char *mode) { 5861*ee754c2dSkamil void *ctx; 5862*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, fmemopen, buf, size, mode); 5863*ee754c2dSkamil // FIXME: under ASan the call below may write to freed memory and corrupt 5864*ee754c2dSkamil // its metadata. See 5865*ee754c2dSkamil // https://github.com/google/sanitizers/issues/321. 5866*ee754c2dSkamil __sanitizer_FILE *res = REAL(fmemopen)(buf, size, mode); 5867*ee754c2dSkamil if (res) unpoison_file(res); 5868*ee754c2dSkamil return res; 5869*ee754c2dSkamil} 5870*ee754c2dSkamil#define INIT_OPEN_MEMSTREAM \ 5871*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(open_memstream); \ 5872*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(open_wmemstream); \ 5873*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(fmemopen); 5874*ee754c2dSkamil#else 5875*ee754c2dSkamil#define INIT_OPEN_MEMSTREAM 5876*ee754c2dSkamil#endif 5877*ee754c2dSkamil 5878*ee754c2dSkamil#if SANITIZER_INTERCEPT_OBSTACK 5879*ee754c2dSkamilstatic void initialize_obstack(__sanitizer_obstack *obstack) { 5880*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(obstack, sizeof(*obstack)); 5881*ee754c2dSkamil if (obstack->chunk) 5882*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(obstack->chunk, 5883*ee754c2dSkamil sizeof(*obstack->chunk)); 5884*ee754c2dSkamil} 5885*ee754c2dSkamil 5886*ee754c2dSkamilINTERCEPTOR(int, _obstack_begin_1, __sanitizer_obstack *obstack, int sz, 5887*ee754c2dSkamil int align, void *(*alloc_fn)(uptr arg, uptr sz), 5888*ee754c2dSkamil void (*free_fn)(uptr arg, void *p)) { 5889*ee754c2dSkamil void *ctx; 5890*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, _obstack_begin_1, obstack, sz, align, alloc_fn, 5891*ee754c2dSkamil free_fn); 5892*ee754c2dSkamil int res = REAL(_obstack_begin_1)(obstack, sz, align, alloc_fn, free_fn); 5893*ee754c2dSkamil if (res) initialize_obstack(obstack); 5894*ee754c2dSkamil return res; 5895*ee754c2dSkamil} 5896*ee754c2dSkamilINTERCEPTOR(int, _obstack_begin, __sanitizer_obstack *obstack, int sz, 5897*ee754c2dSkamil int align, void *(*alloc_fn)(uptr sz), void (*free_fn)(void *p)) { 5898*ee754c2dSkamil void *ctx; 5899*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, _obstack_begin, obstack, sz, align, alloc_fn, 5900*ee754c2dSkamil free_fn); 5901*ee754c2dSkamil int res = REAL(_obstack_begin)(obstack, sz, align, alloc_fn, free_fn); 5902*ee754c2dSkamil if (res) initialize_obstack(obstack); 5903*ee754c2dSkamil return res; 5904*ee754c2dSkamil} 5905*ee754c2dSkamilINTERCEPTOR(void, _obstack_newchunk, __sanitizer_obstack *obstack, int length) { 5906*ee754c2dSkamil void *ctx; 5907*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, _obstack_newchunk, obstack, length); 5908*ee754c2dSkamil REAL(_obstack_newchunk)(obstack, length); 5909*ee754c2dSkamil if (obstack->chunk) 5910*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE( 5911*ee754c2dSkamil obstack->chunk, obstack->next_free - (char *)obstack->chunk); 5912*ee754c2dSkamil} 5913*ee754c2dSkamil#define INIT_OBSTACK \ 5914*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(_obstack_begin_1); \ 5915*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(_obstack_begin); \ 5916*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(_obstack_newchunk); 5917*ee754c2dSkamil#else 5918*ee754c2dSkamil#define INIT_OBSTACK 5919*ee754c2dSkamil#endif 5920*ee754c2dSkamil 5921*ee754c2dSkamil#if SANITIZER_INTERCEPT_FFLUSH 5922*ee754c2dSkamilINTERCEPTOR(int, fflush, __sanitizer_FILE *fp) { 5923*ee754c2dSkamil void *ctx; 5924*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, fflush, fp); 5925*ee754c2dSkamil int res = REAL(fflush)(fp); 5926*ee754c2dSkamil // FIXME: handle fp == NULL 5927*ee754c2dSkamil if (fp) { 5928*ee754c2dSkamil const FileMetadata *m = GetInterceptorMetadata(fp); 5929*ee754c2dSkamil if (m) COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size); 5930*ee754c2dSkamil } 5931*ee754c2dSkamil return res; 5932*ee754c2dSkamil} 5933*ee754c2dSkamil#define INIT_FFLUSH COMMON_INTERCEPT_FUNCTION(fflush); 5934*ee754c2dSkamil#else 5935*ee754c2dSkamil#define INIT_FFLUSH 5936*ee754c2dSkamil#endif 5937*ee754c2dSkamil 5938*ee754c2dSkamil#if SANITIZER_INTERCEPT_FCLOSE 5939*ee754c2dSkamilINTERCEPTOR(int, fclose, __sanitizer_FILE *fp) { 5940*ee754c2dSkamil void *ctx; 5941*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, fclose, fp); 5942*ee754c2dSkamil COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp); 5943*ee754c2dSkamil const FileMetadata *m = GetInterceptorMetadata(fp); 5944*ee754c2dSkamil int res = REAL(fclose)(fp); 5945*ee754c2dSkamil if (m) { 5946*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size); 5947*ee754c2dSkamil DeleteInterceptorMetadata(fp); 5948*ee754c2dSkamil } 5949*ee754c2dSkamil return res; 5950*ee754c2dSkamil} 5951*ee754c2dSkamil#define INIT_FCLOSE COMMON_INTERCEPT_FUNCTION(fclose); 5952*ee754c2dSkamil#else 5953*ee754c2dSkamil#define INIT_FCLOSE 5954*ee754c2dSkamil#endif 5955*ee754c2dSkamil 5956*ee754c2dSkamil#if SANITIZER_INTERCEPT_DLOPEN_DLCLOSE 5957*ee754c2dSkamilINTERCEPTOR(void*, dlopen, const char *filename, int flag) { 5958*ee754c2dSkamil void *ctx; 5959*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlopen, filename, flag); 5960*ee754c2dSkamil if (filename) COMMON_INTERCEPTOR_READ_STRING(ctx, filename, 0); 5961*ee754c2dSkamil COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag); 5962*ee754c2dSkamil void *res = REAL(dlopen)(filename, flag); 5963*ee754c2dSkamil Symbolizer::GetOrInit()->InvalidateModuleList(); 5964*ee754c2dSkamil COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, res); 5965*ee754c2dSkamil return res; 5966*ee754c2dSkamil} 5967*ee754c2dSkamil 5968*ee754c2dSkamilINTERCEPTOR(int, dlclose, void *handle) { 5969*ee754c2dSkamil void *ctx; 5970*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlclose, handle); 5971*ee754c2dSkamil int res = REAL(dlclose)(handle); 5972*ee754c2dSkamil Symbolizer::GetOrInit()->InvalidateModuleList(); 5973*ee754c2dSkamil COMMON_INTERCEPTOR_LIBRARY_UNLOADED(); 5974*ee754c2dSkamil return res; 5975*ee754c2dSkamil} 5976*ee754c2dSkamil#define INIT_DLOPEN_DLCLOSE \ 5977*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(dlopen); \ 5978*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(dlclose); 5979*ee754c2dSkamil#else 5980*ee754c2dSkamil#define INIT_DLOPEN_DLCLOSE 5981*ee754c2dSkamil#endif 5982*ee754c2dSkamil 5983*ee754c2dSkamil#if SANITIZER_INTERCEPT_GETPASS 5984*ee754c2dSkamilINTERCEPTOR(char *, getpass, const char *prompt) { 5985*ee754c2dSkamil void *ctx; 5986*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getpass, prompt); 5987*ee754c2dSkamil if (prompt) 5988*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, prompt, REAL(strlen)(prompt)+1); 5989*ee754c2dSkamil char *res = REAL(getpass)(prompt); 5990*ee754c2dSkamil if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res)+1); 5991*ee754c2dSkamil return res; 5992*ee754c2dSkamil} 5993*ee754c2dSkamil 5994*ee754c2dSkamil#define INIT_GETPASS COMMON_INTERCEPT_FUNCTION(getpass); 5995*ee754c2dSkamil#else 5996*ee754c2dSkamil#define INIT_GETPASS 5997*ee754c2dSkamil#endif 5998*ee754c2dSkamil 5999*ee754c2dSkamil#if SANITIZER_INTERCEPT_TIMERFD 6000*ee754c2dSkamilINTERCEPTOR(int, timerfd_settime, int fd, int flags, void *new_value, 6001*ee754c2dSkamil void *old_value) { 6002*ee754c2dSkamil void *ctx; 6003*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, timerfd_settime, fd, flags, new_value, 6004*ee754c2dSkamil old_value); 6005*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerspec_sz); 6006*ee754c2dSkamil int res = REAL(timerfd_settime)(fd, flags, new_value, old_value); 6007*ee754c2dSkamil if (res != -1 && old_value) 6008*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerspec_sz); 6009*ee754c2dSkamil return res; 6010*ee754c2dSkamil} 6011*ee754c2dSkamil 6012*ee754c2dSkamilINTERCEPTOR(int, timerfd_gettime, int fd, void *curr_value) { 6013*ee754c2dSkamil void *ctx; 6014*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, timerfd_gettime, fd, curr_value); 6015*ee754c2dSkamil int res = REAL(timerfd_gettime)(fd, curr_value); 6016*ee754c2dSkamil if (res != -1 && curr_value) 6017*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerspec_sz); 6018*ee754c2dSkamil return res; 6019*ee754c2dSkamil} 6020*ee754c2dSkamil#define INIT_TIMERFD \ 6021*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(timerfd_settime); \ 6022*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(timerfd_gettime); 6023*ee754c2dSkamil#else 6024*ee754c2dSkamil#define INIT_TIMERFD 6025*ee754c2dSkamil#endif 6026*ee754c2dSkamil 6027*ee754c2dSkamil#if SANITIZER_INTERCEPT_MLOCKX 6028*ee754c2dSkamil// Linux kernel has a bug that leads to kernel deadlock if a process 6029*ee754c2dSkamil// maps TBs of memory and then calls mlock(). 6030*ee754c2dSkamilstatic void MlockIsUnsupported() { 6031*ee754c2dSkamil static atomic_uint8_t printed; 6032*ee754c2dSkamil if (atomic_exchange(&printed, 1, memory_order_relaxed)) 6033*ee754c2dSkamil return; 6034*ee754c2dSkamil VPrintf(1, "%s ignores mlock/mlockall/munlock/munlockall\n", 6035*ee754c2dSkamil SanitizerToolName); 6036*ee754c2dSkamil} 6037*ee754c2dSkamil 6038*ee754c2dSkamilINTERCEPTOR(int, mlock, const void *addr, uptr len) { 6039*ee754c2dSkamil MlockIsUnsupported(); 6040*ee754c2dSkamil return 0; 6041*ee754c2dSkamil} 6042*ee754c2dSkamil 6043*ee754c2dSkamilINTERCEPTOR(int, munlock, const void *addr, uptr len) { 6044*ee754c2dSkamil MlockIsUnsupported(); 6045*ee754c2dSkamil return 0; 6046*ee754c2dSkamil} 6047*ee754c2dSkamil 6048*ee754c2dSkamilINTERCEPTOR(int, mlockall, int flags) { 6049*ee754c2dSkamil MlockIsUnsupported(); 6050*ee754c2dSkamil return 0; 6051*ee754c2dSkamil} 6052*ee754c2dSkamil 6053*ee754c2dSkamilINTERCEPTOR(int, munlockall, void) { 6054*ee754c2dSkamil MlockIsUnsupported(); 6055*ee754c2dSkamil return 0; 6056*ee754c2dSkamil} 6057*ee754c2dSkamil 6058*ee754c2dSkamil#define INIT_MLOCKX \ 6059*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(mlock); \ 6060*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(munlock); \ 6061*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(mlockall); \ 6062*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(munlockall); 6063*ee754c2dSkamil 6064*ee754c2dSkamil#else 6065*ee754c2dSkamil#define INIT_MLOCKX 6066*ee754c2dSkamil#endif // SANITIZER_INTERCEPT_MLOCKX 6067*ee754c2dSkamil 6068*ee754c2dSkamil#if SANITIZER_INTERCEPT_FOPENCOOKIE 6069*ee754c2dSkamilstruct WrappedCookie { 6070*ee754c2dSkamil void *real_cookie; 6071*ee754c2dSkamil __sanitizer_cookie_io_functions_t real_io_funcs; 6072*ee754c2dSkamil}; 6073*ee754c2dSkamil 6074*ee754c2dSkamilstatic uptr wrapped_read(void *cookie, char *buf, uptr size) { 6075*ee754c2dSkamil COMMON_INTERCEPTOR_UNPOISON_PARAM(3); 6076*ee754c2dSkamil WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie; 6077*ee754c2dSkamil __sanitizer_cookie_io_read real_read = wrapped_cookie->real_io_funcs.read; 6078*ee754c2dSkamil return real_read ? real_read(wrapped_cookie->real_cookie, buf, size) : 0; 6079*ee754c2dSkamil} 6080*ee754c2dSkamil 6081*ee754c2dSkamilstatic uptr wrapped_write(void *cookie, const char *buf, uptr size) { 6082*ee754c2dSkamil COMMON_INTERCEPTOR_UNPOISON_PARAM(3); 6083*ee754c2dSkamil WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie; 6084*ee754c2dSkamil __sanitizer_cookie_io_write real_write = wrapped_cookie->real_io_funcs.write; 6085*ee754c2dSkamil return real_write ? real_write(wrapped_cookie->real_cookie, buf, size) : size; 6086*ee754c2dSkamil} 6087*ee754c2dSkamil 6088*ee754c2dSkamilstatic int wrapped_seek(void *cookie, u64 *offset, int whence) { 6089*ee754c2dSkamil COMMON_INTERCEPTOR_UNPOISON_PARAM(3); 6090*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(offset, sizeof(*offset)); 6091*ee754c2dSkamil WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie; 6092*ee754c2dSkamil __sanitizer_cookie_io_seek real_seek = wrapped_cookie->real_io_funcs.seek; 6093*ee754c2dSkamil return real_seek ? real_seek(wrapped_cookie->real_cookie, offset, whence) 6094*ee754c2dSkamil : -1; 6095*ee754c2dSkamil} 6096*ee754c2dSkamil 6097*ee754c2dSkamilstatic int wrapped_close(void *cookie) { 6098*ee754c2dSkamil COMMON_INTERCEPTOR_UNPOISON_PARAM(1); 6099*ee754c2dSkamil WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie; 6100*ee754c2dSkamil __sanitizer_cookie_io_close real_close = wrapped_cookie->real_io_funcs.close; 6101*ee754c2dSkamil int res = real_close ? real_close(wrapped_cookie->real_cookie) : 0; 6102*ee754c2dSkamil InternalFree(wrapped_cookie); 6103*ee754c2dSkamil return res; 6104*ee754c2dSkamil} 6105*ee754c2dSkamil 6106*ee754c2dSkamilINTERCEPTOR(__sanitizer_FILE *, fopencookie, void *cookie, const char *mode, 6107*ee754c2dSkamil __sanitizer_cookie_io_functions_t io_funcs) { 6108*ee754c2dSkamil void *ctx; 6109*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, fopencookie, cookie, mode, io_funcs); 6110*ee754c2dSkamil WrappedCookie *wrapped_cookie = 6111*ee754c2dSkamil (WrappedCookie *)InternalAlloc(sizeof(WrappedCookie)); 6112*ee754c2dSkamil wrapped_cookie->real_cookie = cookie; 6113*ee754c2dSkamil wrapped_cookie->real_io_funcs = io_funcs; 6114*ee754c2dSkamil __sanitizer_FILE *res = 6115*ee754c2dSkamil REAL(fopencookie)(wrapped_cookie, mode, {wrapped_read, wrapped_write, 6116*ee754c2dSkamil wrapped_seek, wrapped_close}); 6117*ee754c2dSkamil return res; 6118*ee754c2dSkamil} 6119*ee754c2dSkamil 6120*ee754c2dSkamil#define INIT_FOPENCOOKIE COMMON_INTERCEPT_FUNCTION(fopencookie); 6121*ee754c2dSkamil#else 6122*ee754c2dSkamil#define INIT_FOPENCOOKIE 6123*ee754c2dSkamil#endif // SANITIZER_INTERCEPT_FOPENCOOKIE 6124*ee754c2dSkamil 6125*ee754c2dSkamil#if SANITIZER_INTERCEPT_SEM 6126*ee754c2dSkamilINTERCEPTOR(int, sem_init, __sanitizer_sem_t *s, int pshared, unsigned value) { 6127*ee754c2dSkamil void *ctx; 6128*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, sem_init, s, pshared, value); 6129*ee754c2dSkamil // Workaround a bug in glibc's "old" semaphore implementation by 6130*ee754c2dSkamil // zero-initializing the sem_t contents. This has to be done here because 6131*ee754c2dSkamil // interceptors bind to the lowest symbols version by default, hitting the 6132*ee754c2dSkamil // buggy code path while the non-sanitized build of the same code works fine. 6133*ee754c2dSkamil REAL(memset)(s, 0, sizeof(*s)); 6134*ee754c2dSkamil int res = REAL(sem_init)(s, pshared, value); 6135*ee754c2dSkamil return res; 6136*ee754c2dSkamil} 6137*ee754c2dSkamil 6138*ee754c2dSkamilINTERCEPTOR(int, sem_destroy, __sanitizer_sem_t *s) { 6139*ee754c2dSkamil void *ctx; 6140*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, sem_destroy, s); 6141*ee754c2dSkamil int res = REAL(sem_destroy)(s); 6142*ee754c2dSkamil return res; 6143*ee754c2dSkamil} 6144*ee754c2dSkamil 6145*ee754c2dSkamilINTERCEPTOR(int, sem_wait, __sanitizer_sem_t *s) { 6146*ee754c2dSkamil void *ctx; 6147*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, sem_wait, s); 6148*ee754c2dSkamil int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_wait)(s); 6149*ee754c2dSkamil if (res == 0) { 6150*ee754c2dSkamil COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s); 6151*ee754c2dSkamil } 6152*ee754c2dSkamil return res; 6153*ee754c2dSkamil} 6154*ee754c2dSkamil 6155*ee754c2dSkamilINTERCEPTOR(int, sem_trywait, __sanitizer_sem_t *s) { 6156*ee754c2dSkamil void *ctx; 6157*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, sem_trywait, s); 6158*ee754c2dSkamil int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_trywait)(s); 6159*ee754c2dSkamil if (res == 0) { 6160*ee754c2dSkamil COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s); 6161*ee754c2dSkamil } 6162*ee754c2dSkamil return res; 6163*ee754c2dSkamil} 6164*ee754c2dSkamil 6165*ee754c2dSkamilINTERCEPTOR(int, sem_timedwait, __sanitizer_sem_t *s, void *abstime) { 6166*ee754c2dSkamil void *ctx; 6167*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, sem_timedwait, s, abstime); 6168*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, abstime, struct_timespec_sz); 6169*ee754c2dSkamil int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_timedwait)(s, abstime); 6170*ee754c2dSkamil if (res == 0) { 6171*ee754c2dSkamil COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s); 6172*ee754c2dSkamil } 6173*ee754c2dSkamil return res; 6174*ee754c2dSkamil} 6175*ee754c2dSkamil 6176*ee754c2dSkamilINTERCEPTOR(int, sem_post, __sanitizer_sem_t *s) { 6177*ee754c2dSkamil void *ctx; 6178*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, sem_post, s); 6179*ee754c2dSkamil COMMON_INTERCEPTOR_RELEASE(ctx, (uptr)s); 6180*ee754c2dSkamil int res = REAL(sem_post)(s); 6181*ee754c2dSkamil return res; 6182*ee754c2dSkamil} 6183*ee754c2dSkamil 6184*ee754c2dSkamilINTERCEPTOR(int, sem_getvalue, __sanitizer_sem_t *s, int *sval) { 6185*ee754c2dSkamil void *ctx; 6186*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, sem_getvalue, s, sval); 6187*ee754c2dSkamil int res = REAL(sem_getvalue)(s, sval); 6188*ee754c2dSkamil if (res == 0) { 6189*ee754c2dSkamil COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s); 6190*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sval, sizeof(*sval)); 6191*ee754c2dSkamil } 6192*ee754c2dSkamil return res; 6193*ee754c2dSkamil} 6194*ee754c2dSkamil#define INIT_SEM \ 6195*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(sem_init); \ 6196*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(sem_destroy); \ 6197*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(sem_wait); \ 6198*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(sem_trywait); \ 6199*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(sem_timedwait); \ 6200*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(sem_post); \ 6201*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(sem_getvalue); 6202*ee754c2dSkamil#else 6203*ee754c2dSkamil#define INIT_SEM 6204*ee754c2dSkamil#endif // SANITIZER_INTERCEPT_SEM 6205*ee754c2dSkamil 6206*ee754c2dSkamil#if SANITIZER_INTERCEPT_PTHREAD_SETCANCEL 6207*ee754c2dSkamilINTERCEPTOR(int, pthread_setcancelstate, int state, int *oldstate) { 6208*ee754c2dSkamil void *ctx; 6209*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, pthread_setcancelstate, state, oldstate); 6210*ee754c2dSkamil int res = REAL(pthread_setcancelstate)(state, oldstate); 6211*ee754c2dSkamil if (res == 0 && oldstate != nullptr) 6212*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldstate, sizeof(*oldstate)); 6213*ee754c2dSkamil return res; 6214*ee754c2dSkamil} 6215*ee754c2dSkamil 6216*ee754c2dSkamilINTERCEPTOR(int, pthread_setcanceltype, int type, int *oldtype) { 6217*ee754c2dSkamil void *ctx; 6218*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, pthread_setcanceltype, type, oldtype); 6219*ee754c2dSkamil int res = REAL(pthread_setcanceltype)(type, oldtype); 6220*ee754c2dSkamil if (res == 0 && oldtype != nullptr) 6221*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldtype, sizeof(*oldtype)); 6222*ee754c2dSkamil return res; 6223*ee754c2dSkamil} 6224*ee754c2dSkamil#define INIT_PTHREAD_SETCANCEL \ 6225*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(pthread_setcancelstate); \ 6226*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(pthread_setcanceltype); 6227*ee754c2dSkamil#else 6228*ee754c2dSkamil#define INIT_PTHREAD_SETCANCEL 6229*ee754c2dSkamil#endif 6230*ee754c2dSkamil 6231*ee754c2dSkamil#if SANITIZER_INTERCEPT_MINCORE 6232*ee754c2dSkamilINTERCEPTOR(int, mincore, void *addr, uptr length, unsigned char *vec) { 6233*ee754c2dSkamil void *ctx; 6234*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, mincore, addr, length, vec); 6235*ee754c2dSkamil int res = REAL(mincore)(addr, length, vec); 6236*ee754c2dSkamil if (res == 0) { 6237*ee754c2dSkamil uptr page_size = GetPageSizeCached(); 6238*ee754c2dSkamil uptr vec_size = ((length + page_size - 1) & (~(page_size - 1))) / page_size; 6239*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, vec, vec_size); 6240*ee754c2dSkamil } 6241*ee754c2dSkamil return res; 6242*ee754c2dSkamil} 6243*ee754c2dSkamil#define INIT_MINCORE COMMON_INTERCEPT_FUNCTION(mincore); 6244*ee754c2dSkamil#else 6245*ee754c2dSkamil#define INIT_MINCORE 6246*ee754c2dSkamil#endif 6247*ee754c2dSkamil 6248*ee754c2dSkamil#if SANITIZER_INTERCEPT_PROCESS_VM_READV 6249*ee754c2dSkamilINTERCEPTOR(SSIZE_T, process_vm_readv, int pid, __sanitizer_iovec *local_iov, 6250*ee754c2dSkamil uptr liovcnt, __sanitizer_iovec *remote_iov, uptr riovcnt, 6251*ee754c2dSkamil uptr flags) { 6252*ee754c2dSkamil void *ctx; 6253*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, process_vm_readv, pid, local_iov, liovcnt, 6254*ee754c2dSkamil remote_iov, riovcnt, flags); 6255*ee754c2dSkamil SSIZE_T res = REAL(process_vm_readv)(pid, local_iov, liovcnt, remote_iov, 6256*ee754c2dSkamil riovcnt, flags); 6257*ee754c2dSkamil if (res > 0) 6258*ee754c2dSkamil write_iovec(ctx, local_iov, liovcnt, res); 6259*ee754c2dSkamil return res; 6260*ee754c2dSkamil} 6261*ee754c2dSkamil 6262*ee754c2dSkamilINTERCEPTOR(SSIZE_T, process_vm_writev, int pid, __sanitizer_iovec *local_iov, 6263*ee754c2dSkamil uptr liovcnt, __sanitizer_iovec *remote_iov, uptr riovcnt, 6264*ee754c2dSkamil uptr flags) { 6265*ee754c2dSkamil void *ctx; 6266*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, process_vm_writev, pid, local_iov, liovcnt, 6267*ee754c2dSkamil remote_iov, riovcnt, flags); 6268*ee754c2dSkamil SSIZE_T res = REAL(process_vm_writev)(pid, local_iov, liovcnt, remote_iov, 6269*ee754c2dSkamil riovcnt, flags); 6270*ee754c2dSkamil if (res > 0) 6271*ee754c2dSkamil read_iovec(ctx, local_iov, liovcnt, res); 6272*ee754c2dSkamil return res; 6273*ee754c2dSkamil} 6274*ee754c2dSkamil#define INIT_PROCESS_VM_READV \ 6275*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(process_vm_readv); \ 6276*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(process_vm_writev); 6277*ee754c2dSkamil#else 6278*ee754c2dSkamil#define INIT_PROCESS_VM_READV 6279*ee754c2dSkamil#endif 6280*ee754c2dSkamil 6281*ee754c2dSkamil#if SANITIZER_INTERCEPT_CTERMID 6282*ee754c2dSkamilINTERCEPTOR(char *, ctermid, char *s) { 6283*ee754c2dSkamil void *ctx; 6284*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, ctermid, s); 6285*ee754c2dSkamil char *res = REAL(ctermid)(s); 6286*ee754c2dSkamil if (res) { 6287*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1); 6288*ee754c2dSkamil } 6289*ee754c2dSkamil return res; 6290*ee754c2dSkamil} 6291*ee754c2dSkamil#define INIT_CTERMID COMMON_INTERCEPT_FUNCTION(ctermid); 6292*ee754c2dSkamil#else 6293*ee754c2dSkamil#define INIT_CTERMID 6294*ee754c2dSkamil#endif 6295*ee754c2dSkamil 6296*ee754c2dSkamil#if SANITIZER_INTERCEPT_CTERMID_R 6297*ee754c2dSkamilINTERCEPTOR(char *, ctermid_r, char *s) { 6298*ee754c2dSkamil void *ctx; 6299*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, ctermid_r, s); 6300*ee754c2dSkamil char *res = REAL(ctermid_r)(s); 6301*ee754c2dSkamil if (res) { 6302*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1); 6303*ee754c2dSkamil } 6304*ee754c2dSkamil return res; 6305*ee754c2dSkamil} 6306*ee754c2dSkamil#define INIT_CTERMID_R COMMON_INTERCEPT_FUNCTION(ctermid_r); 6307*ee754c2dSkamil#else 6308*ee754c2dSkamil#define INIT_CTERMID_R 6309*ee754c2dSkamil#endif 6310*ee754c2dSkamil 6311*ee754c2dSkamil#if SANITIZER_INTERCEPT_RECV_RECVFROM 6312*ee754c2dSkamilINTERCEPTOR(SSIZE_T, recv, int fd, void *buf, SIZE_T len, int flags) { 6313*ee754c2dSkamil void *ctx; 6314*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, recv, fd, buf, len, flags); 6315*ee754c2dSkamil COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 6316*ee754c2dSkamil SSIZE_T res = REAL(recv)(fd, buf, len, flags); 6317*ee754c2dSkamil if (res > 0) { 6318*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, Min((SIZE_T)res, len)); 6319*ee754c2dSkamil } 6320*ee754c2dSkamil if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 6321*ee754c2dSkamil return res; 6322*ee754c2dSkamil} 6323*ee754c2dSkamil 6324*ee754c2dSkamilINTERCEPTOR(SSIZE_T, recvfrom, int fd, void *buf, SIZE_T len, int flags, 6325*ee754c2dSkamil void *srcaddr, int *addrlen) { 6326*ee754c2dSkamil void *ctx; 6327*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, recvfrom, fd, buf, len, flags, srcaddr, 6328*ee754c2dSkamil addrlen); 6329*ee754c2dSkamil COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 6330*ee754c2dSkamil SIZE_T srcaddr_sz; 6331*ee754c2dSkamil if (srcaddr) srcaddr_sz = *addrlen; 6332*ee754c2dSkamil (void)srcaddr_sz; // prevent "set but not used" warning 6333*ee754c2dSkamil SSIZE_T res = REAL(recvfrom)(fd, buf, len, flags, srcaddr, addrlen); 6334*ee754c2dSkamil if (res > 0) { 6335*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, Min((SIZE_T)res, len)); 6336*ee754c2dSkamil if (srcaddr) 6337*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(srcaddr, 6338*ee754c2dSkamil Min((SIZE_T)*addrlen, srcaddr_sz)); 6339*ee754c2dSkamil } 6340*ee754c2dSkamil return res; 6341*ee754c2dSkamil} 6342*ee754c2dSkamil#define INIT_RECV_RECVFROM \ 6343*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(recv); \ 6344*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(recvfrom); 6345*ee754c2dSkamil#else 6346*ee754c2dSkamil#define INIT_RECV_RECVFROM 6347*ee754c2dSkamil#endif 6348*ee754c2dSkamil 6349*ee754c2dSkamil#if SANITIZER_INTERCEPT_SEND_SENDTO 6350*ee754c2dSkamilINTERCEPTOR(SSIZE_T, send, int fd, void *buf, SIZE_T len, int flags) { 6351*ee754c2dSkamil void *ctx; 6352*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, send, fd, buf, len, flags); 6353*ee754c2dSkamil if (fd >= 0) { 6354*ee754c2dSkamil COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 6355*ee754c2dSkamil COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 6356*ee754c2dSkamil } 6357*ee754c2dSkamil SSIZE_T res = REAL(send)(fd, buf, len, flags); 6358*ee754c2dSkamil if (common_flags()->intercept_send && res > 0) 6359*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, Min((SIZE_T)res, len)); 6360*ee754c2dSkamil return res; 6361*ee754c2dSkamil} 6362*ee754c2dSkamil 6363*ee754c2dSkamilINTERCEPTOR(SSIZE_T, sendto, int fd, void *buf, SIZE_T len, int flags, 6364*ee754c2dSkamil void *dstaddr, int addrlen) { 6365*ee754c2dSkamil void *ctx; 6366*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, sendto, fd, buf, len, flags, dstaddr, addrlen); 6367*ee754c2dSkamil if (fd >= 0) { 6368*ee754c2dSkamil COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 6369*ee754c2dSkamil COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 6370*ee754c2dSkamil } 6371*ee754c2dSkamil // Can't check dstaddr as it may have uninitialized padding at the end. 6372*ee754c2dSkamil SSIZE_T res = REAL(sendto)(fd, buf, len, flags, dstaddr, addrlen); 6373*ee754c2dSkamil if (common_flags()->intercept_send && res > 0) 6374*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, Min((SIZE_T)res, len)); 6375*ee754c2dSkamil return res; 6376*ee754c2dSkamil} 6377*ee754c2dSkamil#define INIT_SEND_SENDTO \ 6378*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(send); \ 6379*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(sendto); 6380*ee754c2dSkamil#else 6381*ee754c2dSkamil#define INIT_SEND_SENDTO 6382*ee754c2dSkamil#endif 6383*ee754c2dSkamil 6384*ee754c2dSkamil#if SANITIZER_INTERCEPT_EVENTFD_READ_WRITE 6385*ee754c2dSkamilINTERCEPTOR(int, eventfd_read, int fd, u64 *value) { 6386*ee754c2dSkamil void *ctx; 6387*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, eventfd_read, fd, value); 6388*ee754c2dSkamil COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 6389*ee754c2dSkamil int res = REAL(eventfd_read)(fd, value); 6390*ee754c2dSkamil if (res == 0) { 6391*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, sizeof(*value)); 6392*ee754c2dSkamil if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 6393*ee754c2dSkamil } 6394*ee754c2dSkamil return res; 6395*ee754c2dSkamil} 6396*ee754c2dSkamilINTERCEPTOR(int, eventfd_write, int fd, u64 value) { 6397*ee754c2dSkamil void *ctx; 6398*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, eventfd_write, fd, value); 6399*ee754c2dSkamil if (fd >= 0) { 6400*ee754c2dSkamil COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 6401*ee754c2dSkamil COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 6402*ee754c2dSkamil } 6403*ee754c2dSkamil int res = REAL(eventfd_write)(fd, value); 6404*ee754c2dSkamil return res; 6405*ee754c2dSkamil} 6406*ee754c2dSkamil#define INIT_EVENTFD_READ_WRITE \ 6407*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(eventfd_read); \ 6408*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(eventfd_write) 6409*ee754c2dSkamil#else 6410*ee754c2dSkamil#define INIT_EVENTFD_READ_WRITE 6411*ee754c2dSkamil#endif 6412*ee754c2dSkamil 6413*ee754c2dSkamil#if SANITIZER_INTERCEPT_STAT 6414*ee754c2dSkamilINTERCEPTOR(int, stat, const char *path, void *buf) { 6415*ee754c2dSkamil void *ctx; 6416*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, stat, path, buf); 6417*ee754c2dSkamil if (common_flags()->intercept_stat) 6418*ee754c2dSkamil COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0); 6419*ee754c2dSkamil int res = REAL(stat)(path, buf); 6420*ee754c2dSkamil if (!res) 6421*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz); 6422*ee754c2dSkamil return res; 6423*ee754c2dSkamil} 6424*ee754c2dSkamil#define INIT_STAT COMMON_INTERCEPT_FUNCTION(stat) 6425*ee754c2dSkamil#else 6426*ee754c2dSkamil#define INIT_STAT 6427*ee754c2dSkamil#endif 6428*ee754c2dSkamil 6429*ee754c2dSkamil#if SANITIZER_INTERCEPT_LSTAT 6430*ee754c2dSkamilINTERCEPTOR(int, lstat, const char *path, void *buf) { 6431*ee754c2dSkamil void *ctx; 6432*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, lstat, path, buf); 6433*ee754c2dSkamil if (common_flags()->intercept_stat) 6434*ee754c2dSkamil COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0); 6435*ee754c2dSkamil int res = REAL(lstat)(path, buf); 6436*ee754c2dSkamil if (!res) 6437*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz); 6438*ee754c2dSkamil return res; 6439*ee754c2dSkamil} 6440*ee754c2dSkamil#define INIT_LSTAT COMMON_INTERCEPT_FUNCTION(lstat) 6441*ee754c2dSkamil#else 6442*ee754c2dSkamil#define INIT_LSTAT 6443*ee754c2dSkamil#endif 6444*ee754c2dSkamil 6445*ee754c2dSkamil#if SANITIZER_INTERCEPT___XSTAT 6446*ee754c2dSkamilINTERCEPTOR(int, __xstat, int version, const char *path, void *buf) { 6447*ee754c2dSkamil void *ctx; 6448*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, __xstat, version, path, buf); 6449*ee754c2dSkamil if (common_flags()->intercept_stat) 6450*ee754c2dSkamil COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0); 6451*ee754c2dSkamil int res = REAL(__xstat)(version, path, buf); 6452*ee754c2dSkamil if (!res) 6453*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz); 6454*ee754c2dSkamil return res; 6455*ee754c2dSkamil} 6456*ee754c2dSkamil#define INIT___XSTAT COMMON_INTERCEPT_FUNCTION(__xstat) 6457*ee754c2dSkamil#else 6458*ee754c2dSkamil#define INIT___XSTAT 6459*ee754c2dSkamil#endif 6460*ee754c2dSkamil 6461*ee754c2dSkamil#if SANITIZER_INTERCEPT___XSTAT64 6462*ee754c2dSkamilINTERCEPTOR(int, __xstat64, int version, const char *path, void *buf) { 6463*ee754c2dSkamil void *ctx; 6464*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, __xstat64, version, path, buf); 6465*ee754c2dSkamil if (common_flags()->intercept_stat) 6466*ee754c2dSkamil COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0); 6467*ee754c2dSkamil int res = REAL(__xstat64)(version, path, buf); 6468*ee754c2dSkamil if (!res) 6469*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat64_sz); 6470*ee754c2dSkamil return res; 6471*ee754c2dSkamil} 6472*ee754c2dSkamil#define INIT___XSTAT64 COMMON_INTERCEPT_FUNCTION(__xstat64) 6473*ee754c2dSkamil#else 6474*ee754c2dSkamil#define INIT___XSTAT64 6475*ee754c2dSkamil#endif 6476*ee754c2dSkamil 6477*ee754c2dSkamil#if SANITIZER_INTERCEPT___LXSTAT 6478*ee754c2dSkamilINTERCEPTOR(int, __lxstat, int version, const char *path, void *buf) { 6479*ee754c2dSkamil void *ctx; 6480*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, __lxstat, version, path, buf); 6481*ee754c2dSkamil if (common_flags()->intercept_stat) 6482*ee754c2dSkamil COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0); 6483*ee754c2dSkamil int res = REAL(__lxstat)(version, path, buf); 6484*ee754c2dSkamil if (!res) 6485*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz); 6486*ee754c2dSkamil return res; 6487*ee754c2dSkamil} 6488*ee754c2dSkamil#define INIT___LXSTAT COMMON_INTERCEPT_FUNCTION(__lxstat) 6489*ee754c2dSkamil#else 6490*ee754c2dSkamil#define INIT___LXSTAT 6491*ee754c2dSkamil#endif 6492*ee754c2dSkamil 6493*ee754c2dSkamil#if SANITIZER_INTERCEPT___LXSTAT64 6494*ee754c2dSkamilINTERCEPTOR(int, __lxstat64, int version, const char *path, void *buf) { 6495*ee754c2dSkamil void *ctx; 6496*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, __lxstat64, version, path, buf); 6497*ee754c2dSkamil if (common_flags()->intercept_stat) 6498*ee754c2dSkamil COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0); 6499*ee754c2dSkamil int res = REAL(__lxstat64)(version, path, buf); 6500*ee754c2dSkamil if (!res) 6501*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat64_sz); 6502*ee754c2dSkamil return res; 6503*ee754c2dSkamil} 6504*ee754c2dSkamil#define INIT___LXSTAT64 COMMON_INTERCEPT_FUNCTION(__lxstat64) 6505*ee754c2dSkamil#else 6506*ee754c2dSkamil#define INIT___LXSTAT64 6507*ee754c2dSkamil#endif 6508*ee754c2dSkamil 6509*ee754c2dSkamil// FIXME: add other *stat interceptor 6510*ee754c2dSkamil 6511*ee754c2dSkamil#if SANITIZER_INTERCEPT_UTMP 6512*ee754c2dSkamilINTERCEPTOR(void *, getutent, int dummy) { 6513*ee754c2dSkamil void *ctx; 6514*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getutent, dummy); 6515*ee754c2dSkamil void *res = REAL(getutent)(dummy); 6516*ee754c2dSkamil if (res) 6517*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmp_sz); 6518*ee754c2dSkamil return res; 6519*ee754c2dSkamil} 6520*ee754c2dSkamilINTERCEPTOR(void *, getutid, void *ut) { 6521*ee754c2dSkamil void *ctx; 6522*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getutid, ut); 6523*ee754c2dSkamil void *res = REAL(getutid)(ut); 6524*ee754c2dSkamil if (res) 6525*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmp_sz); 6526*ee754c2dSkamil return res; 6527*ee754c2dSkamil} 6528*ee754c2dSkamilINTERCEPTOR(void *, getutline, void *ut) { 6529*ee754c2dSkamil void *ctx; 6530*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getutline, ut); 6531*ee754c2dSkamil void *res = REAL(getutline)(ut); 6532*ee754c2dSkamil if (res) 6533*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmp_sz); 6534*ee754c2dSkamil return res; 6535*ee754c2dSkamil} 6536*ee754c2dSkamil#define INIT_UTMP \ 6537*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(getutent); \ 6538*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(getutid); \ 6539*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(getutline); 6540*ee754c2dSkamil#else 6541*ee754c2dSkamil#define INIT_UTMP 6542*ee754c2dSkamil#endif 6543*ee754c2dSkamil 6544*ee754c2dSkamil#if SANITIZER_INTERCEPT_UTMPX 6545*ee754c2dSkamilINTERCEPTOR(void *, getutxent, int dummy) { 6546*ee754c2dSkamil void *ctx; 6547*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getutxent, dummy); 6548*ee754c2dSkamil void *res = REAL(getutxent)(dummy); 6549*ee754c2dSkamil if (res) 6550*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmpx_sz); 6551*ee754c2dSkamil return res; 6552*ee754c2dSkamil} 6553*ee754c2dSkamilINTERCEPTOR(void *, getutxid, void *ut) { 6554*ee754c2dSkamil void *ctx; 6555*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getutxid, ut); 6556*ee754c2dSkamil void *res = REAL(getutxid)(ut); 6557*ee754c2dSkamil if (res) 6558*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmpx_sz); 6559*ee754c2dSkamil return res; 6560*ee754c2dSkamil} 6561*ee754c2dSkamilINTERCEPTOR(void *, getutxline, void *ut) { 6562*ee754c2dSkamil void *ctx; 6563*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getutxline, ut); 6564*ee754c2dSkamil void *res = REAL(getutxline)(ut); 6565*ee754c2dSkamil if (res) 6566*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmpx_sz); 6567*ee754c2dSkamil return res; 6568*ee754c2dSkamil} 6569*ee754c2dSkamil#define INIT_UTMPX \ 6570*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(getutxent); \ 6571*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(getutxid); \ 6572*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(getutxline); 6573*ee754c2dSkamil#else 6574*ee754c2dSkamil#define INIT_UTMPX 6575*ee754c2dSkamil#endif 6576*ee754c2dSkamil 6577*ee754c2dSkamil#if SANITIZER_INTERCEPT_GETLOADAVG 6578*ee754c2dSkamilINTERCEPTOR(int, getloadavg, double *loadavg, int nelem) { 6579*ee754c2dSkamil void *ctx; 6580*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getloadavg, loadavg, nelem); 6581*ee754c2dSkamil int res = REAL(getloadavg)(loadavg, nelem); 6582*ee754c2dSkamil if (res > 0) 6583*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, loadavg, res * sizeof(*loadavg)); 6584*ee754c2dSkamil return res; 6585*ee754c2dSkamil} 6586*ee754c2dSkamil#define INIT_GETLOADAVG \ 6587*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(getloadavg); 6588*ee754c2dSkamil#else 6589*ee754c2dSkamil#define INIT_GETLOADAVG 6590*ee754c2dSkamil#endif 6591*ee754c2dSkamil 6592*ee754c2dSkamil#if SANITIZER_INTERCEPT_MCHECK_MPROBE 6593*ee754c2dSkamilINTERCEPTOR(int, mcheck, void (*abortfunc)(int mstatus)) { 6594*ee754c2dSkamil return 0; 6595*ee754c2dSkamil} 6596*ee754c2dSkamil 6597*ee754c2dSkamilINTERCEPTOR(int, mcheck_pedantic, void (*abortfunc)(int mstatus)) { 6598*ee754c2dSkamil return 0; 6599*ee754c2dSkamil} 6600*ee754c2dSkamil 6601*ee754c2dSkamilINTERCEPTOR(int, mprobe, void *ptr) { 6602*ee754c2dSkamil return 0; 6603*ee754c2dSkamil} 6604*ee754c2dSkamil#endif 6605*ee754c2dSkamil 6606*ee754c2dSkamilINTERCEPTOR(SIZE_T, wcslen, const wchar_t *s) { 6607*ee754c2dSkamil void *ctx; 6608*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, wcslen, s); 6609*ee754c2dSkamil SIZE_T res = REAL(wcslen)(s); 6610*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, s, sizeof(wchar_t) * (res + 1)); 6611*ee754c2dSkamil return res; 6612*ee754c2dSkamil} 6613*ee754c2dSkamil 6614*ee754c2dSkamilINTERCEPTOR(SIZE_T, wcsnlen, const wchar_t *s, SIZE_T n) { 6615*ee754c2dSkamil void *ctx; 6616*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, wcsnlen, s, n); 6617*ee754c2dSkamil SIZE_T res = REAL(wcsnlen)(s, n); 6618*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, s, sizeof(wchar_t) * Min(res + 1, n)); 6619*ee754c2dSkamil return res; 6620*ee754c2dSkamil} 6621*ee754c2dSkamil#define INIT_WCSLEN \ 6622*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(wcslen); \ 6623*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(wcsnlen); 6624*ee754c2dSkamil 6625*ee754c2dSkamil#if SANITIZER_INTERCEPT_WCSCAT 6626*ee754c2dSkamilINTERCEPTOR(wchar_t *, wcscat, wchar_t *dst, const wchar_t *src) { 6627*ee754c2dSkamil void *ctx; 6628*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, wcscat, dst, src); 6629*ee754c2dSkamil SIZE_T src_size = REAL(wcslen)(src); 6630*ee754c2dSkamil SIZE_T dst_size = REAL(wcslen)(dst); 6631*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, src, (src_size + 1) * sizeof(wchar_t)); 6632*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, dst, (dst_size + 1) * sizeof(wchar_t)); 6633*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst + dst_size, 6634*ee754c2dSkamil (src_size + 1) * sizeof(wchar_t)); 6635*ee754c2dSkamil return REAL(wcscat)(dst, src); // NOLINT 6636*ee754c2dSkamil} 6637*ee754c2dSkamil 6638*ee754c2dSkamilINTERCEPTOR(wchar_t *, wcsncat, wchar_t *dst, const wchar_t *src, SIZE_T n) { 6639*ee754c2dSkamil void *ctx; 6640*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, wcsncat, dst, src, n); 6641*ee754c2dSkamil SIZE_T src_size = REAL(wcsnlen)(src, n); 6642*ee754c2dSkamil SIZE_T dst_size = REAL(wcslen)(dst); 6643*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, src, 6644*ee754c2dSkamil Min(src_size + 1, n) * sizeof(wchar_t)); 6645*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, dst, (dst_size + 1) * sizeof(wchar_t)); 6646*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst + dst_size, 6647*ee754c2dSkamil (src_size + 1) * sizeof(wchar_t)); 6648*ee754c2dSkamil return REAL(wcsncat)(dst, src, n); // NOLINT 6649*ee754c2dSkamil} 6650*ee754c2dSkamil#define INIT_WCSCAT \ 6651*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(wcscat); \ 6652*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(wcsncat); 6653*ee754c2dSkamil#else 6654*ee754c2dSkamil#define INIT_WCSCAT 6655*ee754c2dSkamil#endif 6656*ee754c2dSkamil 6657*ee754c2dSkamil#if SANITIZER_INTERCEPT_STRXFRM 6658*ee754c2dSkamilstatic SIZE_T RealStrLen(const char *str) { return REAL(strlen)(str); } 6659*ee754c2dSkamil 6660*ee754c2dSkamilstatic SIZE_T RealStrLen(const wchar_t *str) { return REAL(wcslen)(str); } 6661*ee754c2dSkamil 6662*ee754c2dSkamil#define STRXFRM_INTERCEPTOR_IMPL(strxfrm, dest, src, len, ...) \ 6663*ee754c2dSkamil { \ 6664*ee754c2dSkamil void *ctx; \ 6665*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strxfrm, dest, src, len, ##__VA_ARGS__); \ 6666*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, src, \ 6667*ee754c2dSkamil sizeof(*src) * (RealStrLen(src) + 1)); \ 6668*ee754c2dSkamil SIZE_T res = REAL(strxfrm)(dest, src, len, ##__VA_ARGS__); \ 6669*ee754c2dSkamil if (res < len) \ 6670*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, sizeof(*src) * (res + 1)); \ 6671*ee754c2dSkamil return res; \ 6672*ee754c2dSkamil } 6673*ee754c2dSkamil 6674*ee754c2dSkamilINTERCEPTOR(SIZE_T, strxfrm, char *dest, const char *src, SIZE_T len) { 6675*ee754c2dSkamil STRXFRM_INTERCEPTOR_IMPL(strxfrm, dest, src, len); 6676*ee754c2dSkamil} 6677*ee754c2dSkamil 6678*ee754c2dSkamilINTERCEPTOR(SIZE_T, strxfrm_l, char *dest, const char *src, SIZE_T len, 6679*ee754c2dSkamil void *locale) { 6680*ee754c2dSkamil STRXFRM_INTERCEPTOR_IMPL(strxfrm_l, dest, src, len, locale); 6681*ee754c2dSkamil} 6682*ee754c2dSkamil 6683*ee754c2dSkamil#define INIT_STRXFRM \ 6684*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(strxfrm); \ 6685*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(strxfrm_l); 6686*ee754c2dSkamil#else 6687*ee754c2dSkamil#define INIT_STRXFRM 6688*ee754c2dSkamil#endif 6689*ee754c2dSkamil 6690*ee754c2dSkamil#if SANITIZER_INTERCEPT___STRXFRM_L 6691*ee754c2dSkamilINTERCEPTOR(SIZE_T, __strxfrm_l, char *dest, const char *src, SIZE_T len, 6692*ee754c2dSkamil void *locale) { 6693*ee754c2dSkamil STRXFRM_INTERCEPTOR_IMPL(__strxfrm_l, dest, src, len, locale); 6694*ee754c2dSkamil} 6695*ee754c2dSkamil 6696*ee754c2dSkamil#define INIT___STRXFRM_L COMMON_INTERCEPT_FUNCTION(__strxfrm_l); 6697*ee754c2dSkamil#else 6698*ee754c2dSkamil#define INIT___STRXFRM_L 6699*ee754c2dSkamil#endif 6700*ee754c2dSkamil 6701*ee754c2dSkamil#if SANITIZER_INTERCEPT_WCSXFRM 6702*ee754c2dSkamilINTERCEPTOR(SIZE_T, wcsxfrm, wchar_t *dest, const wchar_t *src, SIZE_T len) { 6703*ee754c2dSkamil STRXFRM_INTERCEPTOR_IMPL(wcsxfrm, dest, src, len); 6704*ee754c2dSkamil} 6705*ee754c2dSkamil 6706*ee754c2dSkamilINTERCEPTOR(SIZE_T, wcsxfrm_l, wchar_t *dest, const wchar_t *src, SIZE_T len, 6707*ee754c2dSkamil void *locale) { 6708*ee754c2dSkamil STRXFRM_INTERCEPTOR_IMPL(wcsxfrm_l, dest, src, len, locale); 6709*ee754c2dSkamil} 6710*ee754c2dSkamil 6711*ee754c2dSkamil#define INIT_WCSXFRM \ 6712*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(wcsxfrm); \ 6713*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(wcsxfrm_l); 6714*ee754c2dSkamil#else 6715*ee754c2dSkamil#define INIT_WCSXFRM 6716*ee754c2dSkamil#endif 6717*ee754c2dSkamil 6718*ee754c2dSkamil#if SANITIZER_INTERCEPT___WCSXFRM_L 6719*ee754c2dSkamilINTERCEPTOR(SIZE_T, __wcsxfrm_l, wchar_t *dest, const wchar_t *src, SIZE_T len, 6720*ee754c2dSkamil void *locale) { 6721*ee754c2dSkamil STRXFRM_INTERCEPTOR_IMPL(__wcsxfrm_l, dest, src, len, locale); 6722*ee754c2dSkamil} 6723*ee754c2dSkamil 6724*ee754c2dSkamil#define INIT___WCSXFRM_L COMMON_INTERCEPT_FUNCTION(__wcsxfrm_l); 6725*ee754c2dSkamil#else 6726*ee754c2dSkamil#define INIT___WCSXFRM_L 6727*ee754c2dSkamil#endif 6728*ee754c2dSkamil 6729*ee754c2dSkamil#if SANITIZER_INTERCEPT_ACCT 6730*ee754c2dSkamilINTERCEPTOR(int, acct, const char *file) { 6731*ee754c2dSkamil void *ctx; 6732*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, acct, file); 6733*ee754c2dSkamil if (file) 6734*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, file, REAL(strlen)(file) + 1); 6735*ee754c2dSkamil return REAL(acct)(file); 6736*ee754c2dSkamil} 6737*ee754c2dSkamil#define INIT_ACCT COMMON_INTERCEPT_FUNCTION(acct) 6738*ee754c2dSkamil#else 6739*ee754c2dSkamil#define INIT_ACCT 6740*ee754c2dSkamil#endif 6741*ee754c2dSkamil 6742*ee754c2dSkamil#if SANITIZER_INTERCEPT_USER_FROM_UID 6743*ee754c2dSkamilINTERCEPTOR(const char *, user_from_uid, u32 uid, int nouser) { 6744*ee754c2dSkamil void *ctx; 6745*ee754c2dSkamil const char *user; 6746*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, user_from_uid, uid, nouser); 6747*ee754c2dSkamil user = REAL(user_from_uid)(uid, nouser); 6748*ee754c2dSkamil if (user) 6749*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, user, REAL(strlen)(user) + 1); 6750*ee754c2dSkamil return user; 6751*ee754c2dSkamil} 6752*ee754c2dSkamil#define INIT_USER_FROM_UID COMMON_INTERCEPT_FUNCTION(user_from_uid) 6753*ee754c2dSkamil#else 6754*ee754c2dSkamil#define INIT_USER_FROM_UID 6755*ee754c2dSkamil#endif 6756*ee754c2dSkamil 6757*ee754c2dSkamil#if SANITIZER_INTERCEPT_UID_FROM_USER 6758*ee754c2dSkamilINTERCEPTOR(int, uid_from_user, const char *name, u32 *uid) { 6759*ee754c2dSkamil void *ctx; 6760*ee754c2dSkamil int res; 6761*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, uid_from_user, name, uid); 6762*ee754c2dSkamil if (name) 6763*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 6764*ee754c2dSkamil res = REAL(uid_from_user)(name, uid); 6765*ee754c2dSkamil if (uid) 6766*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, uid, sizeof(*uid)); 6767*ee754c2dSkamil return res; 6768*ee754c2dSkamil} 6769*ee754c2dSkamil#define INIT_UID_FROM_USER COMMON_INTERCEPT_FUNCTION(uid_from_user) 6770*ee754c2dSkamil#else 6771*ee754c2dSkamil#define INIT_UID_FROM_USER 6772*ee754c2dSkamil#endif 6773*ee754c2dSkamil 6774*ee754c2dSkamil#if SANITIZER_INTERCEPT_GROUP_FROM_GID 6775*ee754c2dSkamilINTERCEPTOR(const char *, group_from_gid, u32 gid, int nogroup) { 6776*ee754c2dSkamil void *ctx; 6777*ee754c2dSkamil const char *group; 6778*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, group_from_gid, gid, nogroup); 6779*ee754c2dSkamil group = REAL(group_from_gid)(gid, nogroup); 6780*ee754c2dSkamil if (group) 6781*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, group, REAL(strlen)(group) + 1); 6782*ee754c2dSkamil return group; 6783*ee754c2dSkamil} 6784*ee754c2dSkamil#define INIT_GROUP_FROM_GID COMMON_INTERCEPT_FUNCTION(group_from_gid) 6785*ee754c2dSkamil#else 6786*ee754c2dSkamil#define INIT_GROUP_FROM_GID 6787*ee754c2dSkamil#endif 6788*ee754c2dSkamil 6789*ee754c2dSkamil#if SANITIZER_INTERCEPT_GID_FROM_GROUP 6790*ee754c2dSkamilINTERCEPTOR(int, gid_from_group, const char *group, u32 *gid) { 6791*ee754c2dSkamil void *ctx; 6792*ee754c2dSkamil int res; 6793*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, gid_from_group, group, gid); 6794*ee754c2dSkamil if (group) 6795*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, group, REAL(strlen)(group) + 1); 6796*ee754c2dSkamil res = REAL(gid_from_group)(group, gid); 6797*ee754c2dSkamil if (gid) 6798*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, gid, sizeof(*gid)); 6799*ee754c2dSkamil return res; 6800*ee754c2dSkamil} 6801*ee754c2dSkamil#define INIT_GID_FROM_GROUP COMMON_INTERCEPT_FUNCTION(gid_from_group) 6802*ee754c2dSkamil#else 6803*ee754c2dSkamil#define INIT_GID_FROM_GROUP 6804*ee754c2dSkamil#endif 6805*ee754c2dSkamil 6806*ee754c2dSkamil#if SANITIZER_INTERCEPT_ACCESS 6807*ee754c2dSkamilINTERCEPTOR(int, access, const char *path, int mode) { 6808*ee754c2dSkamil void *ctx; 6809*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, access, path, mode); 6810*ee754c2dSkamil if (path) 6811*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 6812*ee754c2dSkamil return REAL(access)(path, mode); 6813*ee754c2dSkamil} 6814*ee754c2dSkamil#define INIT_ACCESS COMMON_INTERCEPT_FUNCTION(access) 6815*ee754c2dSkamil#else 6816*ee754c2dSkamil#define INIT_ACCESS 6817*ee754c2dSkamil#endif 6818*ee754c2dSkamil 6819*ee754c2dSkamil#if SANITIZER_INTERCEPT_FACCESSAT 6820*ee754c2dSkamilINTERCEPTOR(int, faccessat, int fd, const char *path, int mode, int flags) { 6821*ee754c2dSkamil void *ctx; 6822*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, faccessat, fd, path, mode, flags); 6823*ee754c2dSkamil if (path) 6824*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 6825*ee754c2dSkamil return REAL(faccessat)(fd, path, mode, flags); 6826*ee754c2dSkamil} 6827*ee754c2dSkamil#define INIT_FACCESSAT COMMON_INTERCEPT_FUNCTION(faccessat) 6828*ee754c2dSkamil#else 6829*ee754c2dSkamil#define INIT_FACCESSAT 6830*ee754c2dSkamil#endif 6831*ee754c2dSkamil 6832*ee754c2dSkamil#if SANITIZER_INTERCEPT_GETGROUPLIST 6833*ee754c2dSkamilINTERCEPTOR(int, getgrouplist, const char *name, u32 basegid, u32 *groups, 6834*ee754c2dSkamil int *ngroups) { 6835*ee754c2dSkamil void *ctx; 6836*ee754c2dSkamil int res; 6837*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getgrouplist, name, basegid, groups, ngroups); 6838*ee754c2dSkamil if (name) 6839*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 6840*ee754c2dSkamil if (ngroups) 6841*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, ngroups, sizeof(*ngroups)); 6842*ee754c2dSkamil res = REAL(getgrouplist)(name, basegid, groups, ngroups); 6843*ee754c2dSkamil if (!res && groups && ngroups) { 6844*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, groups, sizeof(*groups) * (*ngroups)); 6845*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ngroups, sizeof(*ngroups)); 6846*ee754c2dSkamil } 6847*ee754c2dSkamil return res; 6848*ee754c2dSkamil} 6849*ee754c2dSkamil 6850*ee754c2dSkamil#define INIT_GETGROUPLIST COMMON_INTERCEPT_FUNCTION(getgrouplist); 6851*ee754c2dSkamil#else 6852*ee754c2dSkamil#define INIT_GETGROUPLIST 6853*ee754c2dSkamil#endif 6854*ee754c2dSkamil 6855*ee754c2dSkamil#if SANITIZER_INTERCEPT_GETGROUPMEMBERSHIP 6856*ee754c2dSkamilINTERCEPTOR(int, getgroupmembership, const char *name, u32 basegid, u32 *groups, 6857*ee754c2dSkamil int maxgrp, int *ngroups) { 6858*ee754c2dSkamil void *ctx; 6859*ee754c2dSkamil int res; 6860*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getgroupmembership, name, basegid, groups, 6861*ee754c2dSkamil maxgrp, ngroups); 6862*ee754c2dSkamil if (name) 6863*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 6864*ee754c2dSkamil res = REAL(getgroupmembership)(name, basegid, groups, maxgrp, ngroups); 6865*ee754c2dSkamil if (!res && groups && ngroups) { 6866*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, groups, sizeof(*groups) * (*ngroups)); 6867*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ngroups, sizeof(*ngroups)); 6868*ee754c2dSkamil } 6869*ee754c2dSkamil return res; 6870*ee754c2dSkamil} 6871*ee754c2dSkamil 6872*ee754c2dSkamil#define INIT_GETGROUPMEMBERSHIP COMMON_INTERCEPT_FUNCTION(getgroupmembership); 6873*ee754c2dSkamil#else 6874*ee754c2dSkamil#define INIT_GETGROUPMEMBERSHIP 6875*ee754c2dSkamil#endif 6876*ee754c2dSkamil 6877*ee754c2dSkamil#if SANITIZER_INTERCEPT_READLINK 6878*ee754c2dSkamilINTERCEPTOR(SSIZE_T, readlink, const char *path, char *buf, SIZE_T bufsiz) { 6879*ee754c2dSkamil void* ctx; 6880*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, readlink, path, buf, bufsiz); 6881*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 6882*ee754c2dSkamil SSIZE_T res = REAL(readlink)(path, buf, bufsiz); 6883*ee754c2dSkamil if (res > 0) 6884*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res); 6885*ee754c2dSkamil return res; 6886*ee754c2dSkamil} 6887*ee754c2dSkamil 6888*ee754c2dSkamil#define INIT_READLINK COMMON_INTERCEPT_FUNCTION(readlink) 6889*ee754c2dSkamil#else 6890*ee754c2dSkamil#define INIT_READLINK 6891*ee754c2dSkamil#endif 6892*ee754c2dSkamil 6893*ee754c2dSkamil#if SANITIZER_INTERCEPT_READLINKAT 6894*ee754c2dSkamilINTERCEPTOR(SSIZE_T, readlinkat, int dirfd, const char *path, char *buf, 6895*ee754c2dSkamil SIZE_T bufsiz) { 6896*ee754c2dSkamil void* ctx; 6897*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, readlinkat, dirfd, path, buf, bufsiz); 6898*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 6899*ee754c2dSkamil SSIZE_T res = REAL(readlinkat)(dirfd, path, buf, bufsiz); 6900*ee754c2dSkamil if (res > 0) 6901*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res); 6902*ee754c2dSkamil return res; 6903*ee754c2dSkamil} 6904*ee754c2dSkamil 6905*ee754c2dSkamil#define INIT_READLINKAT COMMON_INTERCEPT_FUNCTION(readlinkat) 6906*ee754c2dSkamil#else 6907*ee754c2dSkamil#define INIT_READLINKAT 6908*ee754c2dSkamil#endif 6909*ee754c2dSkamil 6910*ee754c2dSkamil#if SANITIZER_INTERCEPT_NAME_TO_HANDLE_AT 6911*ee754c2dSkamilINTERCEPTOR(int, name_to_handle_at, int dirfd, const char *pathname, 6912*ee754c2dSkamil struct file_handle *handle, int *mount_id, int flags) { 6913*ee754c2dSkamil void* ctx; 6914*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, name_to_handle_at, dirfd, pathname, handle, 6915*ee754c2dSkamil mount_id, flags); 6916*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, pathname, REAL(strlen)(pathname) + 1); 6917*ee754c2dSkamil 6918*ee754c2dSkamil __sanitizer_file_handle *sanitizer_handle = 6919*ee754c2dSkamil reinterpret_cast<__sanitizer_file_handle*>(handle); 6920*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE( 6921*ee754c2dSkamil ctx, &sanitizer_handle->handle_bytes, 6922*ee754c2dSkamil sizeof(sanitizer_handle->handle_bytes)); 6923*ee754c2dSkamil 6924*ee754c2dSkamil int res = REAL(name_to_handle_at)(dirfd, pathname, handle, mount_id, flags); 6925*ee754c2dSkamil if (!res) { 6926*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE( 6927*ee754c2dSkamil ctx, &sanitizer_handle->handle_bytes, 6928*ee754c2dSkamil sizeof(sanitizer_handle->handle_bytes)); 6929*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE( 6930*ee754c2dSkamil ctx, &sanitizer_handle->handle_type, 6931*ee754c2dSkamil sizeof(sanitizer_handle->handle_type)); 6932*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE( 6933*ee754c2dSkamil ctx, &sanitizer_handle->f_handle, sanitizer_handle->handle_bytes); 6934*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mount_id, sizeof(*mount_id)); 6935*ee754c2dSkamil } 6936*ee754c2dSkamil return res; 6937*ee754c2dSkamil} 6938*ee754c2dSkamil 6939*ee754c2dSkamil#define INIT_NAME_TO_HANDLE_AT COMMON_INTERCEPT_FUNCTION(name_to_handle_at) 6940*ee754c2dSkamil#else 6941*ee754c2dSkamil#define INIT_NAME_TO_HANDLE_AT 6942*ee754c2dSkamil#endif 6943*ee754c2dSkamil 6944*ee754c2dSkamil#if SANITIZER_INTERCEPT_OPEN_BY_HANDLE_AT 6945*ee754c2dSkamilINTERCEPTOR(int, open_by_handle_at, int mount_fd, struct file_handle* handle, 6946*ee754c2dSkamil int flags) { 6947*ee754c2dSkamil void* ctx; 6948*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, open_by_handle_at, mount_fd, handle, flags); 6949*ee754c2dSkamil 6950*ee754c2dSkamil __sanitizer_file_handle *sanitizer_handle = 6951*ee754c2dSkamil reinterpret_cast<__sanitizer_file_handle*>(handle); 6952*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE( 6953*ee754c2dSkamil ctx, &sanitizer_handle->handle_bytes, 6954*ee754c2dSkamil sizeof(sanitizer_handle->handle_bytes)); 6955*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE( 6956*ee754c2dSkamil ctx, &sanitizer_handle->handle_type, 6957*ee754c2dSkamil sizeof(sanitizer_handle->handle_type)); 6958*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE( 6959*ee754c2dSkamil ctx, &sanitizer_handle->f_handle, sanitizer_handle->handle_bytes); 6960*ee754c2dSkamil 6961*ee754c2dSkamil return REAL(open_by_handle_at)(mount_fd, handle, flags); 6962*ee754c2dSkamil} 6963*ee754c2dSkamil 6964*ee754c2dSkamil#define INIT_OPEN_BY_HANDLE_AT COMMON_INTERCEPT_FUNCTION(open_by_handle_at) 6965*ee754c2dSkamil#else 6966*ee754c2dSkamil#define INIT_OPEN_BY_HANDLE_AT 6967*ee754c2dSkamil#endif 6968*ee754c2dSkamil 6969*ee754c2dSkamil#if SANITIZER_INTERCEPT_STRLCPY 6970*ee754c2dSkamilINTERCEPTOR(SIZE_T, strlcpy, char *dst, char *src, SIZE_T size) { 6971*ee754c2dSkamil void *ctx; 6972*ee754c2dSkamil SIZE_T res; 6973*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strlcpy, dst, src, size); 6974*ee754c2dSkamil if (src) { 6975*ee754c2dSkamil // Keep strnlen as macro argument, as macro may ignore it. 6976*ee754c2dSkamil COMMON_INTERCEPTOR_READ_STRING( 6977*ee754c2dSkamil ctx, src, Min(internal_strnlen(src, size), size - 1) + 1); 6978*ee754c2dSkamil } 6979*ee754c2dSkamil res = REAL(strlcpy)(dst, src, size); 6980*ee754c2dSkamil COMMON_INTERCEPTOR_COPY_STRING(ctx, dst, src, REAL(strlen)(dst) + 1); 6981*ee754c2dSkamil return res; 6982*ee754c2dSkamil} 6983*ee754c2dSkamil 6984*ee754c2dSkamilINTERCEPTOR(SIZE_T, strlcat, char *dst, char *src, SIZE_T size) { 6985*ee754c2dSkamil void *ctx; 6986*ee754c2dSkamil SIZE_T len = 0; 6987*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strlcat, dst, src, size); 6988*ee754c2dSkamil // src is checked in the strlcpy() interceptor 6989*ee754c2dSkamil if (dst) { 6990*ee754c2dSkamil len = internal_strnlen(dst, size); 6991*ee754c2dSkamil COMMON_INTERCEPTOR_READ_STRING(ctx, dst, Min(len, size - 1) + 1); 6992*ee754c2dSkamil } 6993*ee754c2dSkamil // Reuse the rest of the code in the strlcpy() interceptor 6994*ee754c2dSkamil return WRAP(strlcpy)(dst + len, src, size - len) + len; 6995*ee754c2dSkamil} 6996*ee754c2dSkamil#define INIT_STRLCPY \ 6997*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(strlcpy); \ 6998*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(strlcat); 6999*ee754c2dSkamil#else 7000*ee754c2dSkamil#define INIT_STRLCPY 7001*ee754c2dSkamil#endif 7002*ee754c2dSkamil 7003*ee754c2dSkamil#if SANITIZER_INTERCEPT_MMAP 7004*ee754c2dSkamilINTERCEPTOR(void *, mmap, void *addr, SIZE_T sz, int prot, int flags, int fd, 7005*ee754c2dSkamil OFF_T off) { 7006*ee754c2dSkamil void *ctx; 7007*ee754c2dSkamil if (common_flags()->detect_write_exec) 7008*ee754c2dSkamil ReportMmapWriteExec(prot); 7009*ee754c2dSkamil if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) 7010*ee754c2dSkamil return (void *)internal_mmap(addr, sz, prot, flags, fd, off); 7011*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, mmap, addr, sz, prot, flags, fd, off); 7012*ee754c2dSkamil COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, sz, prot, flags, fd, off); 7013*ee754c2dSkamil} 7014*ee754c2dSkamil 7015*ee754c2dSkamilINTERCEPTOR(int, mprotect, void *addr, SIZE_T sz, int prot) { 7016*ee754c2dSkamil void *ctx; 7017*ee754c2dSkamil if (common_flags()->detect_write_exec) 7018*ee754c2dSkamil ReportMmapWriteExec(prot); 7019*ee754c2dSkamil if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) 7020*ee754c2dSkamil return (int)internal_mprotect(addr, sz, prot); 7021*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, mprotect, addr, sz, prot); 7022*ee754c2dSkamil MprotectMallocZones(addr, prot); 7023*ee754c2dSkamil return REAL(mprotect)(addr, sz, prot); 7024*ee754c2dSkamil} 7025*ee754c2dSkamil#define INIT_MMAP \ 7026*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(mmap); \ 7027*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(mprotect); 7028*ee754c2dSkamil#else 7029*ee754c2dSkamil#define INIT_MMAP 7030*ee754c2dSkamil#endif 7031*ee754c2dSkamil 7032*ee754c2dSkamil#if SANITIZER_INTERCEPT_MMAP64 7033*ee754c2dSkamilINTERCEPTOR(void *, mmap64, void *addr, SIZE_T sz, int prot, int flags, int fd, 7034*ee754c2dSkamil OFF64_T off) { 7035*ee754c2dSkamil void *ctx; 7036*ee754c2dSkamil if (common_flags()->detect_write_exec) 7037*ee754c2dSkamil ReportMmapWriteExec(prot); 7038*ee754c2dSkamil if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) 7039*ee754c2dSkamil return (void *)internal_mmap(addr, sz, prot, flags, fd, off); 7040*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, mmap64, addr, sz, prot, flags, fd, off); 7041*ee754c2dSkamil COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap64, addr, sz, prot, flags, fd, off); 7042*ee754c2dSkamil} 7043*ee754c2dSkamil#define INIT_MMAP64 COMMON_INTERCEPT_FUNCTION(mmap64); 7044*ee754c2dSkamil#else 7045*ee754c2dSkamil#define INIT_MMAP64 7046*ee754c2dSkamil#endif 7047*ee754c2dSkamil 7048*ee754c2dSkamil#if SANITIZER_INTERCEPT_DEVNAME 7049*ee754c2dSkamilINTERCEPTOR(char *, devname, u64 dev, u32 type) { 7050*ee754c2dSkamil void *ctx; 7051*ee754c2dSkamil char *name; 7052*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, devname, dev, type); 7053*ee754c2dSkamil name = REAL(devname)(dev, type); 7054*ee754c2dSkamil if (name) 7055*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, REAL(strlen)(name) + 1); 7056*ee754c2dSkamil return name; 7057*ee754c2dSkamil} 7058*ee754c2dSkamil#define INIT_DEVNAME COMMON_INTERCEPT_FUNCTION(devname); 7059*ee754c2dSkamil#else 7060*ee754c2dSkamil#define INIT_DEVNAME 7061*ee754c2dSkamil#endif 7062*ee754c2dSkamil 7063*ee754c2dSkamil#if SANITIZER_INTERCEPT_DEVNAME_R 7064*ee754c2dSkamil#if SANITIZER_NETBSD 7065*ee754c2dSkamil#define DEVNAME_R_RETTYPE int 7066*ee754c2dSkamil#define DEVNAME_R_SUCCESS(x) (!(x)) 7067*ee754c2dSkamil#else 7068*ee754c2dSkamil#define DEVNAME_R_RETTYPE char* 7069*ee754c2dSkamil#define DEVNAME_R_SUCCESS(x) (x) 7070*ee754c2dSkamil#endif 7071*ee754c2dSkamilINTERCEPTOR(DEVNAME_R_RETTYPE, devname_r, u64 dev, u32 type, char *path, 7072*ee754c2dSkamil uptr len) { 7073*ee754c2dSkamil void *ctx; 7074*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, devname_r, dev, type, path, len); 7075*ee754c2dSkamil DEVNAME_R_RETTYPE res = REAL(devname_r)(dev, type, path, len); 7076*ee754c2dSkamil if (DEVNAME_R_SUCCESS(res)) 7077*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, path, REAL(strlen)(path) + 1); 7078*ee754c2dSkamil return res; 7079*ee754c2dSkamil} 7080*ee754c2dSkamil#define INIT_DEVNAME_R COMMON_INTERCEPT_FUNCTION(devname_r); 7081*ee754c2dSkamil#else 7082*ee754c2dSkamil#define INIT_DEVNAME_R 7083*ee754c2dSkamil#endif 7084*ee754c2dSkamil 7085*ee754c2dSkamil#if SANITIZER_INTERCEPT_FGETLN 7086*ee754c2dSkamilINTERCEPTOR(char *, fgetln, __sanitizer_FILE *stream, SIZE_T *len) { 7087*ee754c2dSkamil void *ctx; 7088*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, fgetln, stream, len); 7089*ee754c2dSkamil char *str = REAL(fgetln)(stream, len); 7090*ee754c2dSkamil if (str && len) { 7091*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len)); 7092*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, *len); 7093*ee754c2dSkamil } 7094*ee754c2dSkamil return str; 7095*ee754c2dSkamil} 7096*ee754c2dSkamil#define INIT_FGETLN COMMON_INTERCEPT_FUNCTION(fgetln) 7097*ee754c2dSkamil#else 7098*ee754c2dSkamil#define INIT_FGETLN 7099*ee754c2dSkamil#endif 7100*ee754c2dSkamil 7101*ee754c2dSkamil#if SANITIZER_INTERCEPT_STRMODE 7102*ee754c2dSkamilINTERCEPTOR(void, strmode, u32 mode, char *bp) { 7103*ee754c2dSkamil void *ctx; 7104*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strmode, mode, bp); 7105*ee754c2dSkamil REAL(strmode)(mode, bp); 7106*ee754c2dSkamil if (bp) 7107*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, bp, REAL(strlen)(bp) + 1); 7108*ee754c2dSkamil} 7109*ee754c2dSkamil#define INIT_STRMODE COMMON_INTERCEPT_FUNCTION(strmode) 7110*ee754c2dSkamil#else 7111*ee754c2dSkamil#define INIT_STRMODE 7112*ee754c2dSkamil#endif 7113*ee754c2dSkamil 7114*ee754c2dSkamil#if SANITIZER_INTERCEPT_TTYENT 7115*ee754c2dSkamilINTERCEPTOR(struct __sanitizer_ttyent *, getttyent, void) { 7116*ee754c2dSkamil void *ctx; 7117*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getttyent); 7118*ee754c2dSkamil struct __sanitizer_ttyent *ttyent = REAL(getttyent)(); 7119*ee754c2dSkamil if (ttyent) 7120*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ttyent, struct_ttyent_sz); 7121*ee754c2dSkamil return ttyent; 7122*ee754c2dSkamil} 7123*ee754c2dSkamilINTERCEPTOR(struct __sanitizer_ttyent *, getttynam, char *name) { 7124*ee754c2dSkamil void *ctx; 7125*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getttynam, name); 7126*ee754c2dSkamil if (name) 7127*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 7128*ee754c2dSkamil struct __sanitizer_ttyent *ttyent = REAL(getttynam)(name); 7129*ee754c2dSkamil if (ttyent) 7130*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ttyent, struct_ttyent_sz); 7131*ee754c2dSkamil return ttyent; 7132*ee754c2dSkamil} 7133*ee754c2dSkamilINTERCEPTOR(int, setttyentpath, char *path) { 7134*ee754c2dSkamil void *ctx; 7135*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, setttyentpath, path); 7136*ee754c2dSkamil if (path) 7137*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 7138*ee754c2dSkamil return REAL(setttyentpath)(path); 7139*ee754c2dSkamil} 7140*ee754c2dSkamil#define INIT_TTYENT \ 7141*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(getttyent); \ 7142*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(getttynam); \ 7143*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(setttyentpath) 7144*ee754c2dSkamil#else 7145*ee754c2dSkamil#define INIT_TTYENT 7146*ee754c2dSkamil#endif 7147*ee754c2dSkamil 7148*ee754c2dSkamil#if SANITIZER_INTERCEPT_PROTOENT 7149*ee754c2dSkamilINTERCEPTOR(struct __sanitizer_protoent *, getprotoent) { 7150*ee754c2dSkamil void *ctx; 7151*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getprotoent); 7152*ee754c2dSkamil struct __sanitizer_protoent *p = REAL(getprotoent)(); 7153*ee754c2dSkamil if (p) { 7154*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); 7155*ee754c2dSkamil 7156*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_name, REAL(strlen)(p->p_name) + 1); 7157*ee754c2dSkamil 7158*ee754c2dSkamil SIZE_T pp_size = 1; // One handles the trailing \0 7159*ee754c2dSkamil 7160*ee754c2dSkamil for (char **pp = p->p_aliases; *pp; ++pp, ++pp_size) 7161*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *pp, REAL(strlen)(*pp) + 1); 7162*ee754c2dSkamil 7163*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_aliases, 7164*ee754c2dSkamil pp_size * sizeof(char **)); 7165*ee754c2dSkamil } 7166*ee754c2dSkamil return p; 7167*ee754c2dSkamil} 7168*ee754c2dSkamil 7169*ee754c2dSkamilINTERCEPTOR(struct __sanitizer_protoent *, getprotobyname, const char *name) { 7170*ee754c2dSkamil void *ctx; 7171*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getprotobyname, name); 7172*ee754c2dSkamil if (name) 7173*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 7174*ee754c2dSkamil struct __sanitizer_protoent *p = REAL(getprotobyname)(name); 7175*ee754c2dSkamil if (p) { 7176*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); 7177*ee754c2dSkamil 7178*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_name, REAL(strlen)(p->p_name) + 1); 7179*ee754c2dSkamil 7180*ee754c2dSkamil SIZE_T pp_size = 1; // One handles the trailing \0 7181*ee754c2dSkamil 7182*ee754c2dSkamil for (char **pp = p->p_aliases; *pp; ++pp, ++pp_size) 7183*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *pp, REAL(strlen)(*pp) + 1); 7184*ee754c2dSkamil 7185*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_aliases, 7186*ee754c2dSkamil pp_size * sizeof(char **)); 7187*ee754c2dSkamil } 7188*ee754c2dSkamil return p; 7189*ee754c2dSkamil} 7190*ee754c2dSkamil 7191*ee754c2dSkamilINTERCEPTOR(struct __sanitizer_protoent *, getprotobynumber, int proto) { 7192*ee754c2dSkamil void *ctx; 7193*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getprotobynumber, proto); 7194*ee754c2dSkamil struct __sanitizer_protoent *p = REAL(getprotobynumber)(proto); 7195*ee754c2dSkamil if (p) { 7196*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); 7197*ee754c2dSkamil 7198*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_name, REAL(strlen)(p->p_name) + 1); 7199*ee754c2dSkamil 7200*ee754c2dSkamil SIZE_T pp_size = 1; // One handles the trailing \0 7201*ee754c2dSkamil 7202*ee754c2dSkamil for (char **pp = p->p_aliases; *pp; ++pp, ++pp_size) 7203*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *pp, REAL(strlen)(*pp) + 1); 7204*ee754c2dSkamil 7205*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_aliases, 7206*ee754c2dSkamil pp_size * sizeof(char **)); 7207*ee754c2dSkamil } 7208*ee754c2dSkamil return p; 7209*ee754c2dSkamil} 7210*ee754c2dSkamil#define INIT_PROTOENT \ 7211*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(getprotoent); \ 7212*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(getprotobyname); \ 7213*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(getprotobynumber) 7214*ee754c2dSkamil#else 7215*ee754c2dSkamil#define INIT_PROTOENT 7216*ee754c2dSkamil#endif 7217*ee754c2dSkamil 7218*ee754c2dSkamil#if SANITIZER_INTERCEPT_NETENT 7219*ee754c2dSkamilINTERCEPTOR(struct __sanitizer_netent *, getnetent) { 7220*ee754c2dSkamil void *ctx; 7221*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getnetent); 7222*ee754c2dSkamil struct __sanitizer_netent *n = REAL(getnetent)(); 7223*ee754c2dSkamil if (n) { 7224*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n)); 7225*ee754c2dSkamil 7226*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_name, REAL(strlen)(n->n_name) + 1); 7227*ee754c2dSkamil 7228*ee754c2dSkamil SIZE_T nn_size = 1; // One handles the trailing \0 7229*ee754c2dSkamil 7230*ee754c2dSkamil for (char **nn = n->n_aliases; *nn; ++nn, ++nn_size) 7231*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, REAL(strlen)(*nn) + 1); 7232*ee754c2dSkamil 7233*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases, 7234*ee754c2dSkamil nn_size * sizeof(char **)); 7235*ee754c2dSkamil } 7236*ee754c2dSkamil return n; 7237*ee754c2dSkamil} 7238*ee754c2dSkamil 7239*ee754c2dSkamilINTERCEPTOR(struct __sanitizer_netent *, getnetbyname, const char *name) { 7240*ee754c2dSkamil void *ctx; 7241*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getnetbyname, name); 7242*ee754c2dSkamil if (name) 7243*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 7244*ee754c2dSkamil struct __sanitizer_netent *n = REAL(getnetbyname)(name); 7245*ee754c2dSkamil if (n) { 7246*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n)); 7247*ee754c2dSkamil 7248*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_name, REAL(strlen)(n->n_name) + 1); 7249*ee754c2dSkamil 7250*ee754c2dSkamil SIZE_T nn_size = 1; // One handles the trailing \0 7251*ee754c2dSkamil 7252*ee754c2dSkamil for (char **nn = n->n_aliases; *nn; ++nn, ++nn_size) 7253*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, REAL(strlen)(*nn) + 1); 7254*ee754c2dSkamil 7255*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases, 7256*ee754c2dSkamil nn_size * sizeof(char **)); 7257*ee754c2dSkamil } 7258*ee754c2dSkamil return n; 7259*ee754c2dSkamil} 7260*ee754c2dSkamil 7261*ee754c2dSkamilINTERCEPTOR(struct __sanitizer_netent *, getnetbyaddr, u32 net, int type) { 7262*ee754c2dSkamil void *ctx; 7263*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getnetbyaddr, net, type); 7264*ee754c2dSkamil struct __sanitizer_netent *n = REAL(getnetbyaddr)(net, type); 7265*ee754c2dSkamil if (n) { 7266*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n)); 7267*ee754c2dSkamil 7268*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_name, REAL(strlen)(n->n_name) + 1); 7269*ee754c2dSkamil 7270*ee754c2dSkamil SIZE_T nn_size = 1; // One handles the trailing \0 7271*ee754c2dSkamil 7272*ee754c2dSkamil for (char **nn = n->n_aliases; *nn; ++nn, ++nn_size) 7273*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, REAL(strlen)(*nn) + 1); 7274*ee754c2dSkamil 7275*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases, 7276*ee754c2dSkamil nn_size * sizeof(char **)); 7277*ee754c2dSkamil } 7278*ee754c2dSkamil return n; 7279*ee754c2dSkamil} 7280*ee754c2dSkamil#define INIT_NETENT \ 7281*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(getnetent); \ 7282*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(getnetbyname); \ 7283*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(getnetbyaddr) 7284*ee754c2dSkamil#else 7285*ee754c2dSkamil#define INIT_NETENT 7286*ee754c2dSkamil#endif 7287*ee754c2dSkamil 7288*ee754c2dSkamil#if SANITIZER_INTERCEPT_GETMNTINFO 7289*ee754c2dSkamilINTERCEPTOR(int, getmntinfo, void **mntbufp, int flags) { 7290*ee754c2dSkamil void *ctx; 7291*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getmntinfo, mntbufp, flags); 7292*ee754c2dSkamil int cnt = REAL(getmntinfo)(mntbufp, flags); 7293*ee754c2dSkamil if (cnt > 0 && mntbufp) { 7294*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mntbufp, sizeof(void *)); 7295*ee754c2dSkamil if (*mntbufp) 7296*ee754c2dSkamil#if SANITIZER_NETBSD 7297*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *mntbufp, cnt * struct_statvfs_sz); 7298*ee754c2dSkamil#else 7299*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *mntbufp, cnt * struct_statfs_sz); 7300*ee754c2dSkamil#endif 7301*ee754c2dSkamil } 7302*ee754c2dSkamil return cnt; 7303*ee754c2dSkamil} 7304*ee754c2dSkamil#define INIT_GETMNTINFO COMMON_INTERCEPT_FUNCTION(getmntinfo) 7305*ee754c2dSkamil#else 7306*ee754c2dSkamil#define INIT_GETMNTINFO 7307*ee754c2dSkamil#endif 7308*ee754c2dSkamil 7309*ee754c2dSkamil#if SANITIZER_INTERCEPT_MI_VECTOR_HASH 7310*ee754c2dSkamilINTERCEPTOR(void, mi_vector_hash, const void *key, SIZE_T len, u32 seed, 7311*ee754c2dSkamil u32 hashes[3]) { 7312*ee754c2dSkamil void *ctx; 7313*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, mi_vector_hash, key, len, seed, hashes); 7314*ee754c2dSkamil if (key) 7315*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, key, len); 7316*ee754c2dSkamil REAL(mi_vector_hash)(key, len, seed, hashes); 7317*ee754c2dSkamil if (hashes) 7318*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hashes, sizeof(hashes[0]) * 3); 7319*ee754c2dSkamil} 7320*ee754c2dSkamil#define INIT_MI_VECTOR_HASH COMMON_INTERCEPT_FUNCTION(mi_vector_hash) 7321*ee754c2dSkamil#else 7322*ee754c2dSkamil#define INIT_MI_VECTOR_HASH 7323*ee754c2dSkamil#endif 7324*ee754c2dSkamil 7325*ee754c2dSkamil#if SANITIZER_INTERCEPT_SETVBUF 7326*ee754c2dSkamilINTERCEPTOR(int, setvbuf, __sanitizer_FILE *stream, char *buf, int mode, 7327*ee754c2dSkamil SIZE_T size) { 7328*ee754c2dSkamil void *ctx; 7329*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, setvbuf, stream, buf, mode, size); 7330*ee754c2dSkamil int ret = REAL(setvbuf)(stream, buf, mode, size); 7331*ee754c2dSkamil if (buf) 7332*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, size); 7333*ee754c2dSkamil if (stream) 7334*ee754c2dSkamil unpoison_file(stream); 7335*ee754c2dSkamil return ret; 7336*ee754c2dSkamil} 7337*ee754c2dSkamil 7338*ee754c2dSkamilINTERCEPTOR(void, setbuf, __sanitizer_FILE *stream, char *buf) { 7339*ee754c2dSkamil void *ctx; 7340*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, setbuf, stream, buf); 7341*ee754c2dSkamil REAL(setbuf)(stream, buf); 7342*ee754c2dSkamil if (buf) { 7343*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer_bufsiz); 7344*ee754c2dSkamil } 7345*ee754c2dSkamil if (stream) 7346*ee754c2dSkamil unpoison_file(stream); 7347*ee754c2dSkamil} 7348*ee754c2dSkamil 7349*ee754c2dSkamilINTERCEPTOR(void, setbuffer, __sanitizer_FILE *stream, char *buf, int mode) { 7350*ee754c2dSkamil void *ctx; 7351*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, setbuffer, stream, buf, mode); 7352*ee754c2dSkamil REAL(setbuffer)(stream, buf, mode); 7353*ee754c2dSkamil if (buf) { 7354*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer_bufsiz); 7355*ee754c2dSkamil } 7356*ee754c2dSkamil if (stream) 7357*ee754c2dSkamil unpoison_file(stream); 7358*ee754c2dSkamil} 7359*ee754c2dSkamil 7360*ee754c2dSkamilINTERCEPTOR(void, setlinebuf, __sanitizer_FILE *stream) { 7361*ee754c2dSkamil void *ctx; 7362*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, setlinebuf, stream); 7363*ee754c2dSkamil REAL(setlinebuf)(stream); 7364*ee754c2dSkamil if (stream) 7365*ee754c2dSkamil unpoison_file(stream); 7366*ee754c2dSkamil} 7367*ee754c2dSkamil#define INIT_SETVBUF COMMON_INTERCEPT_FUNCTION(setvbuf); \ 7368*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(setbuf); \ 7369*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(setbuffer); \ 7370*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(setlinebuf) 7371*ee754c2dSkamil#else 7372*ee754c2dSkamil#define INIT_SETVBUF 7373*ee754c2dSkamil#endif 7374*ee754c2dSkamil 7375*ee754c2dSkamil#if SANITIZER_INTERCEPT_GETVFSSTAT 7376*ee754c2dSkamilINTERCEPTOR(int, getvfsstat, void *buf, SIZE_T bufsize, int flags) { 7377*ee754c2dSkamil void *ctx; 7378*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getvfsstat, buf, bufsize, flags); 7379*ee754c2dSkamil int ret = REAL(getvfsstat)(buf, bufsize, flags); 7380*ee754c2dSkamil if (buf && ret > 0) 7381*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, ret * struct_statvfs_sz); 7382*ee754c2dSkamil return ret; 7383*ee754c2dSkamil} 7384*ee754c2dSkamil#define INIT_GETVFSSTAT COMMON_INTERCEPT_FUNCTION(getvfsstat) 7385*ee754c2dSkamil#else 7386*ee754c2dSkamil#define INIT_GETVFSSTAT 7387*ee754c2dSkamil#endif 7388*ee754c2dSkamil 7389*ee754c2dSkamil#if SANITIZER_INTERCEPT_REGEX 7390*ee754c2dSkamilINTERCEPTOR(int, regcomp, void *preg, const char *pattern, int cflags) { 7391*ee754c2dSkamil void *ctx; 7392*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, regcomp, preg, pattern, cflags); 7393*ee754c2dSkamil if (pattern) 7394*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, pattern, REAL(strlen)(pattern) + 1); 7395*ee754c2dSkamil int res = REAL(regcomp)(preg, pattern, cflags); 7396*ee754c2dSkamil if (!res) 7397*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, preg, struct_regex_sz); 7398*ee754c2dSkamil return res; 7399*ee754c2dSkamil} 7400*ee754c2dSkamilINTERCEPTOR(int, regexec, const void *preg, const char *string, SIZE_T nmatch, 7401*ee754c2dSkamil struct __sanitizer_regmatch *pmatch[], int eflags) { 7402*ee754c2dSkamil void *ctx; 7403*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, regexec, preg, string, nmatch, pmatch, eflags); 7404*ee754c2dSkamil if (preg) 7405*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, preg, struct_regex_sz); 7406*ee754c2dSkamil if (string) 7407*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, string, REAL(strlen)(string) + 1); 7408*ee754c2dSkamil int res = REAL(regexec)(preg, string, nmatch, pmatch, eflags); 7409*ee754c2dSkamil if (!res && pmatch) 7410*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pmatch, nmatch * struct_regmatch_sz); 7411*ee754c2dSkamil return res; 7412*ee754c2dSkamil} 7413*ee754c2dSkamilINTERCEPTOR(SIZE_T, regerror, int errcode, const void *preg, char *errbuf, 7414*ee754c2dSkamil SIZE_T errbuf_size) { 7415*ee754c2dSkamil void *ctx; 7416*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, regerror, errcode, preg, errbuf, errbuf_size); 7417*ee754c2dSkamil if (preg) 7418*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, preg, struct_regex_sz); 7419*ee754c2dSkamil SIZE_T res = REAL(regerror)(errcode, preg, errbuf, errbuf_size); 7420*ee754c2dSkamil if (errbuf) 7421*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, errbuf, REAL(strlen)(errbuf) + 1); 7422*ee754c2dSkamil return res; 7423*ee754c2dSkamil} 7424*ee754c2dSkamilINTERCEPTOR(void, regfree, const void *preg) { 7425*ee754c2dSkamil void *ctx; 7426*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, regfree, preg); 7427*ee754c2dSkamil if (preg) 7428*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, preg, struct_regex_sz); 7429*ee754c2dSkamil REAL(regfree)(preg); 7430*ee754c2dSkamil} 7431*ee754c2dSkamil#define INIT_REGEX \ 7432*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(regcomp); \ 7433*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(regexec); \ 7434*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(regerror); \ 7435*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(regfree); 7436*ee754c2dSkamil#else 7437*ee754c2dSkamil#define INIT_REGEX 7438*ee754c2dSkamil#endif 7439*ee754c2dSkamil 7440*ee754c2dSkamil#if SANITIZER_INTERCEPT_REGEXSUB 7441*ee754c2dSkamilINTERCEPTOR(SSIZE_T, regnsub, char *buf, SIZE_T bufsiz, const char *sub, 7442*ee754c2dSkamil const struct __sanitizer_regmatch *rm, const char *str) { 7443*ee754c2dSkamil void *ctx; 7444*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, regnsub, buf, bufsiz, sub, rm, str); 7445*ee754c2dSkamil if (sub) 7446*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, sub, REAL(strlen)(sub) + 1); 7447*ee754c2dSkamil // The implementation demands and hardcodes 10 elements 7448*ee754c2dSkamil if (rm) 7449*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, rm, 10 * struct_regmatch_sz); 7450*ee754c2dSkamil if (str) 7451*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, str, REAL(strlen)(str) + 1); 7452*ee754c2dSkamil SSIZE_T res = REAL(regnsub)(buf, bufsiz, sub, rm, str); 7453*ee754c2dSkamil if (res > 0 && buf) 7454*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, REAL(strlen)(buf) + 1); 7455*ee754c2dSkamil return res; 7456*ee754c2dSkamil} 7457*ee754c2dSkamilINTERCEPTOR(SSIZE_T, regasub, char **buf, const char *sub, 7458*ee754c2dSkamil const struct __sanitizer_regmatch *rm, const char *sstr) { 7459*ee754c2dSkamil void *ctx; 7460*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, regasub, buf, sub, rm, sstr); 7461*ee754c2dSkamil if (sub) 7462*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, sub, REAL(strlen)(sub) + 1); 7463*ee754c2dSkamil // Hardcode 10 elements as this is hardcoded size 7464*ee754c2dSkamil if (rm) 7465*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, rm, 10 * struct_regmatch_sz); 7466*ee754c2dSkamil if (sstr) 7467*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, sstr, REAL(strlen)(sstr) + 1); 7468*ee754c2dSkamil SSIZE_T res = REAL(regasub)(buf, sub, rm, sstr); 7469*ee754c2dSkamil if (res > 0 && buf) { 7470*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sizeof(char *)); 7471*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *buf, REAL(strlen)(*buf) + 1); 7472*ee754c2dSkamil } 7473*ee754c2dSkamil return res; 7474*ee754c2dSkamil} 7475*ee754c2dSkamil 7476*ee754c2dSkamil#define INIT_REGEXSUB \ 7477*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(regnsub); \ 7478*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(regasub); 7479*ee754c2dSkamil#else 7480*ee754c2dSkamil#define INIT_REGEXSUB 7481*ee754c2dSkamil#endif 7482*ee754c2dSkamil 7483*ee754c2dSkamil#if SANITIZER_INTERCEPT_FTS 7484*ee754c2dSkamilINTERCEPTOR(void *, fts_open, char *const *path_argv, int options, 7485*ee754c2dSkamil int (*compar)(void **, void **)) { 7486*ee754c2dSkamil void *ctx; 7487*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, fts_open, path_argv, options, compar); 7488*ee754c2dSkamil if (path_argv) { 7489*ee754c2dSkamil for (char *const *pa = path_argv; ; ++pa) { 7490*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, pa, sizeof(char **)); 7491*ee754c2dSkamil if (!*pa) 7492*ee754c2dSkamil break; 7493*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, REAL(strlen)(*pa) + 1); 7494*ee754c2dSkamil } 7495*ee754c2dSkamil } 7496*ee754c2dSkamil // TODO(kamil): handle compar callback 7497*ee754c2dSkamil void *fts = REAL(fts_open)(path_argv, options, compar); 7498*ee754c2dSkamil if (fts) 7499*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, fts, struct_FTS_sz); 7500*ee754c2dSkamil return fts; 7501*ee754c2dSkamil} 7502*ee754c2dSkamil 7503*ee754c2dSkamilINTERCEPTOR(void *, fts_read, void *ftsp) { 7504*ee754c2dSkamil void *ctx; 7505*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, fts_read, ftsp); 7506*ee754c2dSkamil if (ftsp) 7507*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz); 7508*ee754c2dSkamil void *ftsent = REAL(fts_read)(ftsp); 7509*ee754c2dSkamil if (ftsent) 7510*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ftsent, struct_FTSENT_sz); 7511*ee754c2dSkamil return ftsent; 7512*ee754c2dSkamil} 7513*ee754c2dSkamil 7514*ee754c2dSkamilINTERCEPTOR(void *, fts_children, void *ftsp, int options) { 7515*ee754c2dSkamil void *ctx; 7516*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, fts_children, ftsp, options); 7517*ee754c2dSkamil if (ftsp) 7518*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz); 7519*ee754c2dSkamil void *ftsent = REAL(fts_children)(ftsp, options); 7520*ee754c2dSkamil if (ftsent) 7521*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ftsent, struct_FTSENT_sz); 7522*ee754c2dSkamil return ftsent; 7523*ee754c2dSkamil} 7524*ee754c2dSkamil 7525*ee754c2dSkamilINTERCEPTOR(int, fts_set, void *ftsp, void *f, int options) { 7526*ee754c2dSkamil void *ctx; 7527*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, fts_set, ftsp, f, options); 7528*ee754c2dSkamil if (ftsp) 7529*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz); 7530*ee754c2dSkamil if (f) 7531*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, f, struct_FTSENT_sz); 7532*ee754c2dSkamil return REAL(fts_set)(ftsp, f, options); 7533*ee754c2dSkamil} 7534*ee754c2dSkamil 7535*ee754c2dSkamilINTERCEPTOR(int, fts_close, void *ftsp) { 7536*ee754c2dSkamil void *ctx; 7537*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, fts_close, ftsp); 7538*ee754c2dSkamil if (ftsp) 7539*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz); 7540*ee754c2dSkamil return REAL(fts_close)(ftsp); 7541*ee754c2dSkamil} 7542*ee754c2dSkamil#define INIT_FTS \ 7543*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(fts_open); \ 7544*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(fts_read); \ 7545*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(fts_children); \ 7546*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(fts_set); \ 7547*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(fts_close); 7548*ee754c2dSkamil#else 7549*ee754c2dSkamil#define INIT_FTS 7550*ee754c2dSkamil#endif 7551*ee754c2dSkamil 7552*ee754c2dSkamil#if SANITIZER_INTERCEPT_SYSCTL 7553*ee754c2dSkamilINTERCEPTOR(int, sysctl, int *name, unsigned int namelen, void *oldp, 7554*ee754c2dSkamil SIZE_T *oldlenp, void *newp, SIZE_T newlen) { 7555*ee754c2dSkamil void *ctx; 7556*ee754c2dSkamil if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) 7557*ee754c2dSkamil return internal_sysctl(name, namelen, oldp, oldlenp, newp, newlen); 7558*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, sysctl, name, namelen, oldp, oldlenp, newp, 7559*ee754c2dSkamil newlen); 7560*ee754c2dSkamil if (name) 7561*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, name, namelen * sizeof(*name)); 7562*ee754c2dSkamil if (oldlenp) 7563*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, oldlenp, sizeof(*oldlenp)); 7564*ee754c2dSkamil if (newp && newlen) 7565*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, newp, newlen); 7566*ee754c2dSkamil int res = REAL(sysctl)(name, namelen, oldp, oldlenp, newp, newlen); 7567*ee754c2dSkamil if (!res) { 7568*ee754c2dSkamil if (oldlenp) { 7569*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldlenp, sizeof(*oldlenp)); 7570*ee754c2dSkamil if (oldp) 7571*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldp, *oldlenp); 7572*ee754c2dSkamil } 7573*ee754c2dSkamil } 7574*ee754c2dSkamil return res; 7575*ee754c2dSkamil} 7576*ee754c2dSkamil 7577*ee754c2dSkamilINTERCEPTOR(int, sysctlbyname, char *sname, void *oldp, SIZE_T *oldlenp, 7578*ee754c2dSkamil void *newp, SIZE_T newlen) { 7579*ee754c2dSkamil void *ctx; 7580*ee754c2dSkamil if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) 7581*ee754c2dSkamil return internal_sysctlbyname(sname, oldp, oldlenp, newp, newlen); 7582*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, sysctlbyname, sname, oldp, oldlenp, newp, 7583*ee754c2dSkamil newlen); 7584*ee754c2dSkamil if (sname) 7585*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, REAL(strlen)(sname) + 1); 7586*ee754c2dSkamil if (oldlenp) 7587*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, oldlenp, sizeof(*oldlenp)); 7588*ee754c2dSkamil if (newp && newlen) 7589*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, newp, newlen); 7590*ee754c2dSkamil int res = REAL(sysctlbyname)(sname, oldp, oldlenp, newp, newlen); 7591*ee754c2dSkamil if (!res) { 7592*ee754c2dSkamil if (oldlenp) { 7593*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldlenp, sizeof(*oldlenp)); 7594*ee754c2dSkamil if (oldp) 7595*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldp, *oldlenp); 7596*ee754c2dSkamil } 7597*ee754c2dSkamil } 7598*ee754c2dSkamil return res; 7599*ee754c2dSkamil} 7600*ee754c2dSkamil 7601*ee754c2dSkamilINTERCEPTOR(int, sysctlnametomib, const char *sname, int *name, 7602*ee754c2dSkamil SIZE_T *namelenp) { 7603*ee754c2dSkamil void *ctx; 7604*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, sysctlnametomib, sname, name, namelenp); 7605*ee754c2dSkamil if (sname) 7606*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, REAL(strlen)(sname) + 1); 7607*ee754c2dSkamil if (namelenp) 7608*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, namelenp, sizeof(*namelenp)); 7609*ee754c2dSkamil int res = REAL(sysctlnametomib)(sname, name, namelenp); 7610*ee754c2dSkamil if (!res) { 7611*ee754c2dSkamil if (namelenp) { 7612*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelenp, sizeof(*namelenp)); 7613*ee754c2dSkamil if (name) 7614*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, *namelenp * sizeof(*name)); 7615*ee754c2dSkamil } 7616*ee754c2dSkamil } 7617*ee754c2dSkamil return res; 7618*ee754c2dSkamil} 7619*ee754c2dSkamil 7620*ee754c2dSkamil#define INIT_SYSCTL \ 7621*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(sysctl); \ 7622*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(sysctlbyname); \ 7623*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(sysctlnametomib); 7624*ee754c2dSkamil#else 7625*ee754c2dSkamil#define INIT_SYSCTL 7626*ee754c2dSkamil#endif 7627*ee754c2dSkamil 7628*ee754c2dSkamil#if SANITIZER_INTERCEPT_ASYSCTL 7629*ee754c2dSkamilINTERCEPTOR(void *, asysctl, const int *name, SIZE_T namelen, SIZE_T *len) { 7630*ee754c2dSkamil void *ctx; 7631*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, asysctl, name, namelen, len); 7632*ee754c2dSkamil if (name) 7633*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, name, sizeof(*name) * namelen); 7634*ee754c2dSkamil void *res = REAL(asysctl)(name, namelen, len); 7635*ee754c2dSkamil if (res && len) { 7636*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len)); 7637*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, *len); 7638*ee754c2dSkamil } 7639*ee754c2dSkamil return res; 7640*ee754c2dSkamil} 7641*ee754c2dSkamil 7642*ee754c2dSkamilINTERCEPTOR(void *, asysctlbyname, const char *sname, SIZE_T *len) { 7643*ee754c2dSkamil void *ctx; 7644*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, asysctlbyname, sname, len); 7645*ee754c2dSkamil if (sname) 7646*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, REAL(strlen)(sname) + 1); 7647*ee754c2dSkamil void *res = REAL(asysctlbyname)(sname, len); 7648*ee754c2dSkamil if (res && len) { 7649*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len)); 7650*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, *len); 7651*ee754c2dSkamil } 7652*ee754c2dSkamil return res; 7653*ee754c2dSkamil} 7654*ee754c2dSkamil#define INIT_ASYSCTL \ 7655*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(asysctl); \ 7656*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(asysctlbyname); 7657*ee754c2dSkamil#else 7658*ee754c2dSkamil#define INIT_ASYSCTL 7659*ee754c2dSkamil#endif 7660*ee754c2dSkamil 7661*ee754c2dSkamil#if SANITIZER_INTERCEPT_SYSCTLGETMIBINFO 7662*ee754c2dSkamilINTERCEPTOR(int, sysctlgetmibinfo, char *sname, int *name, 7663*ee754c2dSkamil unsigned int *namelenp, char *cname, SIZE_T *csz, void **rnode, 7664*ee754c2dSkamil int v) { 7665*ee754c2dSkamil void *ctx; 7666*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, sysctlgetmibinfo, sname, name, namelenp, cname, 7667*ee754c2dSkamil csz, rnode, v); 7668*ee754c2dSkamil if (sname) 7669*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, REAL(strlen)(sname) + 1); 7670*ee754c2dSkamil if (namelenp) 7671*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, namelenp, sizeof(*namelenp)); 7672*ee754c2dSkamil if (csz) 7673*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, csz, sizeof(*csz)); 7674*ee754c2dSkamil // Skip rnode, it's rarely used and not trivial to sanitize 7675*ee754c2dSkamil // It's also used mostly internally 7676*ee754c2dSkamil int res = REAL(sysctlgetmibinfo)(sname, name, namelenp, cname, csz, rnode, v); 7677*ee754c2dSkamil if (!res) { 7678*ee754c2dSkamil if (namelenp) { 7679*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelenp, sizeof(*namelenp)); 7680*ee754c2dSkamil if (name) 7681*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, *namelenp * sizeof(*name)); 7682*ee754c2dSkamil } 7683*ee754c2dSkamil if (csz) { 7684*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, csz, sizeof(*csz)); 7685*ee754c2dSkamil if (cname) 7686*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cname, *csz); 7687*ee754c2dSkamil } 7688*ee754c2dSkamil } 7689*ee754c2dSkamil return res; 7690*ee754c2dSkamil} 7691*ee754c2dSkamil#define INIT_SYSCTLGETMIBINFO \ 7692*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(sysctlgetmibinfo); 7693*ee754c2dSkamil#else 7694*ee754c2dSkamil#define INIT_SYSCTLGETMIBINFO 7695*ee754c2dSkamil#endif 7696*ee754c2dSkamil 7697*ee754c2dSkamil#if SANITIZER_INTERCEPT_NL_LANGINFO 7698*ee754c2dSkamilINTERCEPTOR(char *, nl_langinfo, long item) { 7699*ee754c2dSkamil void *ctx; 7700*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, nl_langinfo, item); 7701*ee754c2dSkamil char *ret = REAL(nl_langinfo)(item); 7702*ee754c2dSkamil if (ret) 7703*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, REAL(strlen)(ret) + 1); 7704*ee754c2dSkamil return ret; 7705*ee754c2dSkamil} 7706*ee754c2dSkamil#define INIT_NL_LANGINFO COMMON_INTERCEPT_FUNCTION(nl_langinfo) 7707*ee754c2dSkamil#else 7708*ee754c2dSkamil#define INIT_NL_LANGINFO 7709*ee754c2dSkamil#endif 7710*ee754c2dSkamil 7711*ee754c2dSkamil#if SANITIZER_INTERCEPT_MODCTL 7712*ee754c2dSkamilINTERCEPTOR(int, modctl, int operation, void *argp) { 7713*ee754c2dSkamil void *ctx; 7714*ee754c2dSkamil int ret; 7715*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, modctl, operation, argp); 7716*ee754c2dSkamil 7717*ee754c2dSkamil if (operation == modctl_load) { 7718*ee754c2dSkamil if (argp) { 7719*ee754c2dSkamil __sanitizer_modctl_load_t *ml = (__sanitizer_modctl_load_t *)argp; 7720*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, ml, sizeof(*ml)); 7721*ee754c2dSkamil if (ml->ml_filename) 7722*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, ml->ml_filename, 7723*ee754c2dSkamil REAL(strlen)(ml->ml_filename) + 1); 7724*ee754c2dSkamil if (ml->ml_props) 7725*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, ml->ml_props, ml->ml_propslen); 7726*ee754c2dSkamil } 7727*ee754c2dSkamil ret = REAL(modctl)(operation, argp); 7728*ee754c2dSkamil } else if (operation == modctl_unload) { 7729*ee754c2dSkamil if (argp) { 7730*ee754c2dSkamil const char *name = (const char *)argp; 7731*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 7732*ee754c2dSkamil } 7733*ee754c2dSkamil ret = REAL(modctl)(operation, argp); 7734*ee754c2dSkamil } else if (operation == modctl_stat) { 7735*ee754c2dSkamil uptr iov_len; 7736*ee754c2dSkamil struct __sanitizer_iovec *iov = (struct __sanitizer_iovec *)argp; 7737*ee754c2dSkamil if (iov) { 7738*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, iov, sizeof(*iov)); 7739*ee754c2dSkamil iov_len = iov->iov_len; 7740*ee754c2dSkamil } 7741*ee754c2dSkamil ret = REAL(modctl)(operation, argp); 7742*ee754c2dSkamil if (iov) 7743*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE( 7744*ee754c2dSkamil ctx, iov->iov_base, Min(iov_len, iov->iov_len)); 7745*ee754c2dSkamil } else if (operation == modctl_exists) 7746*ee754c2dSkamil ret = REAL(modctl)(operation, argp); 7747*ee754c2dSkamil else 7748*ee754c2dSkamil ret = REAL(modctl)(operation, argp); 7749*ee754c2dSkamil 7750*ee754c2dSkamil return ret; 7751*ee754c2dSkamil} 7752*ee754c2dSkamil#define INIT_MODCTL COMMON_INTERCEPT_FUNCTION(modctl) 7753*ee754c2dSkamil#else 7754*ee754c2dSkamil#define INIT_MODCTL 7755*ee754c2dSkamil#endif 7756*ee754c2dSkamil 7757*ee754c2dSkamil#if SANITIZER_INTERCEPT_STRTONUM 7758*ee754c2dSkamilINTERCEPTOR(long long, strtonum, const char *nptr, long long minval, 7759*ee754c2dSkamil long long maxval, const char **errstr) { 7760*ee754c2dSkamil void *ctx; 7761*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strtonum, nptr, minval, maxval, errstr); 7762*ee754c2dSkamil 7763*ee754c2dSkamil // TODO(kamil): Implement strtoll as a common inteceptor 7764*ee754c2dSkamil char *real_endptr; 7765*ee754c2dSkamil long long ret = (long long)REAL(strtoimax)(nptr, &real_endptr, 10); 7766*ee754c2dSkamil StrtolFixAndCheck(ctx, nptr, nullptr, real_endptr, 10); 7767*ee754c2dSkamil 7768*ee754c2dSkamil ret = REAL(strtonum)(nptr, minval, maxval, errstr); 7769*ee754c2dSkamil if (errstr) { 7770*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, errstr, sizeof(const char *)); 7771*ee754c2dSkamil if (*errstr) 7772*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *errstr, REAL(strlen)(*errstr) + 1); 7773*ee754c2dSkamil } 7774*ee754c2dSkamil return ret; 7775*ee754c2dSkamil} 7776*ee754c2dSkamil#define INIT_STRTONUM COMMON_INTERCEPT_FUNCTION(strtonum) 7777*ee754c2dSkamil#else 7778*ee754c2dSkamil#define INIT_STRTONUM 7779*ee754c2dSkamil#endif 7780*ee754c2dSkamil 7781*ee754c2dSkamil#if SANITIZER_INTERCEPT_FPARSELN 7782*ee754c2dSkamilINTERCEPTOR(char *, fparseln, __sanitizer_FILE *stream, SIZE_T *len, 7783*ee754c2dSkamil SIZE_T *lineno, const char delim[3], int flags) { 7784*ee754c2dSkamil void *ctx; 7785*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, fparseln, stream, len, lineno, delim, flags); 7786*ee754c2dSkamil if (lineno) 7787*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, lineno, sizeof(*lineno)); 7788*ee754c2dSkamil if (delim) 7789*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, delim, sizeof(delim[0]) * 3); 7790*ee754c2dSkamil char *ret = REAL(fparseln)(stream, len, lineno, delim, flags); 7791*ee754c2dSkamil if (ret) { 7792*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, REAL(strlen)(ret) + 1); 7793*ee754c2dSkamil if (len) 7794*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len)); 7795*ee754c2dSkamil if (lineno) 7796*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineno, sizeof(*lineno)); 7797*ee754c2dSkamil } 7798*ee754c2dSkamil return ret; 7799*ee754c2dSkamil} 7800*ee754c2dSkamil#define INIT_FPARSELN COMMON_INTERCEPT_FUNCTION(fparseln) 7801*ee754c2dSkamil#else 7802*ee754c2dSkamil#define INIT_FPARSELN 7803*ee754c2dSkamil#endif 7804*ee754c2dSkamil 7805*ee754c2dSkamil#if SANITIZER_INTERCEPT_STATVFS1 7806*ee754c2dSkamilINTERCEPTOR(int, statvfs1, const char *path, void *buf, int flags) { 7807*ee754c2dSkamil void *ctx; 7808*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, statvfs1, path, buf, flags); 7809*ee754c2dSkamil if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 7810*ee754c2dSkamil int res = REAL(statvfs1)(path, buf, flags); 7811*ee754c2dSkamil if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz); 7812*ee754c2dSkamil return res; 7813*ee754c2dSkamil} 7814*ee754c2dSkamilINTERCEPTOR(int, fstatvfs1, int fd, void *buf, int flags) { 7815*ee754c2dSkamil void *ctx; 7816*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs1, fd, buf, flags); 7817*ee754c2dSkamil COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 7818*ee754c2dSkamil int res = REAL(fstatvfs1)(fd, buf, flags); 7819*ee754c2dSkamil if (!res) { 7820*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz); 7821*ee754c2dSkamil if (fd >= 0) 7822*ee754c2dSkamil COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 7823*ee754c2dSkamil } 7824*ee754c2dSkamil return res; 7825*ee754c2dSkamil} 7826*ee754c2dSkamil#define INIT_STATVFS1 \ 7827*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(statvfs1); \ 7828*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(fstatvfs1); 7829*ee754c2dSkamil#else 7830*ee754c2dSkamil#define INIT_STATVFS1 7831*ee754c2dSkamil#endif 7832*ee754c2dSkamil 7833*ee754c2dSkamil#if SANITIZER_INTERCEPT_STRTOI 7834*ee754c2dSkamilINTERCEPTOR(INTMAX_T, strtoi, const char *nptr, char **endptr, int base, 7835*ee754c2dSkamil INTMAX_T low, INTMAX_T high, int *rstatus) { 7836*ee754c2dSkamil void *ctx; 7837*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strtoi, nptr, endptr, base, low, high, rstatus); 7838*ee754c2dSkamil char *real_endptr; 7839*ee754c2dSkamil INTMAX_T ret = REAL(strtoi)(nptr, &real_endptr, base, low, high, rstatus); 7840*ee754c2dSkamil StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base); 7841*ee754c2dSkamil if (rstatus) 7842*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rstatus, sizeof(*rstatus)); 7843*ee754c2dSkamil return ret; 7844*ee754c2dSkamil} 7845*ee754c2dSkamil 7846*ee754c2dSkamilINTERCEPTOR(UINTMAX_T, strtou, const char *nptr, char **endptr, int base, 7847*ee754c2dSkamil UINTMAX_T low, UINTMAX_T high, int *rstatus) { 7848*ee754c2dSkamil void *ctx; 7849*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strtou, nptr, endptr, base, low, high, rstatus); 7850*ee754c2dSkamil char *real_endptr; 7851*ee754c2dSkamil UINTMAX_T ret = REAL(strtou)(nptr, &real_endptr, base, low, high, rstatus); 7852*ee754c2dSkamil StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base); 7853*ee754c2dSkamil if (rstatus) 7854*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rstatus, sizeof(*rstatus)); 7855*ee754c2dSkamil return ret; 7856*ee754c2dSkamil} 7857*ee754c2dSkamil#define INIT_STRTOI \ 7858*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(strtoi); \ 7859*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(strtou) 7860*ee754c2dSkamil#else 7861*ee754c2dSkamil#define INIT_STRTOI 7862*ee754c2dSkamil#endif 7863*ee754c2dSkamil 7864*ee754c2dSkamil#if SANITIZER_INTERCEPT_CAPSICUM 7865*ee754c2dSkamil#define CAP_RIGHTS_INIT_INTERCEPTOR(cap_rights_init, rights, ...) \ 7866*ee754c2dSkamil { \ 7867*ee754c2dSkamil void *ctx; \ 7868*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_init, rights, ##__VA_ARGS__); \ 7869*ee754c2dSkamil if (rights) \ 7870*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights)); \ 7871*ee754c2dSkamil __sanitizer_cap_rights_t *ret = \ 7872*ee754c2dSkamil REAL(cap_rights_init)(rights, ##__VA_ARGS__); \ 7873*ee754c2dSkamil if (ret) \ 7874*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret)); \ 7875*ee754c2dSkamil return ret; \ 7876*ee754c2dSkamil } 7877*ee754c2dSkamil 7878*ee754c2dSkamil#define CAP_RIGHTS_SET_INTERCEPTOR(cap_rights_set, rights, ...) \ 7879*ee754c2dSkamil { \ 7880*ee754c2dSkamil void *ctx; \ 7881*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_set, rights, ##__VA_ARGS__); \ 7882*ee754c2dSkamil if (rights) \ 7883*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights)); \ 7884*ee754c2dSkamil __sanitizer_cap_rights_t *ret = \ 7885*ee754c2dSkamil REAL(cap_rights_set)(rights, ##__VA_ARGS__); \ 7886*ee754c2dSkamil if (ret) \ 7887*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret)); \ 7888*ee754c2dSkamil return ret; \ 7889*ee754c2dSkamil } 7890*ee754c2dSkamil 7891*ee754c2dSkamil#define CAP_RIGHTS_CLEAR_INTERCEPTOR(cap_rights_clear, rights, ...) \ 7892*ee754c2dSkamil { \ 7893*ee754c2dSkamil void *ctx; \ 7894*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_clear, rights, ##__VA_ARGS__); \ 7895*ee754c2dSkamil if (rights) \ 7896*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights)); \ 7897*ee754c2dSkamil __sanitizer_cap_rights_t *ret = \ 7898*ee754c2dSkamil REAL(cap_rights_clear)(rights, ##__VA_ARGS__); \ 7899*ee754c2dSkamil if (ret) \ 7900*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret)); \ 7901*ee754c2dSkamil return ret; \ 7902*ee754c2dSkamil } 7903*ee754c2dSkamil 7904*ee754c2dSkamil#define CAP_RIGHTS_IS_SET_INTERCEPTOR(cap_rights_is_set, rights, ...) \ 7905*ee754c2dSkamil { \ 7906*ee754c2dSkamil void *ctx; \ 7907*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_is_set, rights, ##__VA_ARGS__); \ 7908*ee754c2dSkamil if (rights) \ 7909*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights)); \ 7910*ee754c2dSkamil return REAL(cap_rights_is_set)(rights, ##__VA_ARGS__); \ 7911*ee754c2dSkamil } 7912*ee754c2dSkamil 7913*ee754c2dSkamilINTERCEPTOR(__sanitizer_cap_rights_t *, cap_rights_init, 7914*ee754c2dSkamil __sanitizer_cap_rights_t *rights) { 7915*ee754c2dSkamil CAP_RIGHTS_INIT_INTERCEPTOR(cap_rights_init, rights); 7916*ee754c2dSkamil} 7917*ee754c2dSkamil 7918*ee754c2dSkamilINTERCEPTOR(__sanitizer_cap_rights_t *, cap_rights_set, 7919*ee754c2dSkamil __sanitizer_cap_rights_t *rights) { 7920*ee754c2dSkamil CAP_RIGHTS_SET_INTERCEPTOR(cap_rights_set, rights); 7921*ee754c2dSkamil} 7922*ee754c2dSkamil 7923*ee754c2dSkamilINTERCEPTOR(__sanitizer_cap_rights_t *, cap_rights_clear, 7924*ee754c2dSkamil __sanitizer_cap_rights_t *rights) { 7925*ee754c2dSkamil CAP_RIGHTS_CLEAR_INTERCEPTOR(cap_rights_clear, rights); 7926*ee754c2dSkamil} 7927*ee754c2dSkamil 7928*ee754c2dSkamilINTERCEPTOR(bool, cap_rights_is_set, 7929*ee754c2dSkamil __sanitizer_cap_rights_t *rights) { 7930*ee754c2dSkamil CAP_RIGHTS_IS_SET_INTERCEPTOR(cap_rights_is_set, rights); 7931*ee754c2dSkamil} 7932*ee754c2dSkamil 7933*ee754c2dSkamilINTERCEPTOR(int, cap_rights_limit, int fd, 7934*ee754c2dSkamil const __sanitizer_cap_rights_t *rights) { 7935*ee754c2dSkamil void *ctx; 7936*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_limit, fd, rights); 7937*ee754c2dSkamil if (rights) 7938*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights)); 7939*ee754c2dSkamil 7940*ee754c2dSkamil return REAL(cap_rights_limit)(fd, rights); 7941*ee754c2dSkamil} 7942*ee754c2dSkamil 7943*ee754c2dSkamilINTERCEPTOR(int, cap_rights_get, int fd, __sanitizer_cap_rights_t *rights) { 7944*ee754c2dSkamil void *ctx; 7945*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_get, fd, rights); 7946*ee754c2dSkamil int ret = REAL(cap_rights_get)(fd, rights); 7947*ee754c2dSkamil if (!ret && rights) 7948*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rights, sizeof(*rights)); 7949*ee754c2dSkamil 7950*ee754c2dSkamil return ret; 7951*ee754c2dSkamil} 7952*ee754c2dSkamil 7953*ee754c2dSkamilINTERCEPTOR(bool, cap_rights_is_valid, const __sanitizer_cap_rights_t *rights) { 7954*ee754c2dSkamil void *ctx; 7955*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_is_valid, rights); 7956*ee754c2dSkamil if (rights) 7957*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights)); 7958*ee754c2dSkamil 7959*ee754c2dSkamil return REAL(cap_rights_is_valid(rights)); 7960*ee754c2dSkamil} 7961*ee754c2dSkamil 7962*ee754c2dSkamilINTERCEPTOR(__sanitizer_cap_rights *, cap_rights_merge, 7963*ee754c2dSkamil __sanitizer_cap_rights *dst, const __sanitizer_cap_rights *src) { 7964*ee754c2dSkamil void *ctx; 7965*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_merge, dst, src); 7966*ee754c2dSkamil if (src) 7967*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 7968*ee754c2dSkamil 7969*ee754c2dSkamil __sanitizer_cap_rights *ret = REAL(cap_rights_merge)(dst, src); 7970*ee754c2dSkamil if (dst) 7971*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(*dst)); 7972*ee754c2dSkamil 7973*ee754c2dSkamil return ret; 7974*ee754c2dSkamil} 7975*ee754c2dSkamil 7976*ee754c2dSkamilINTERCEPTOR(__sanitizer_cap_rights *, cap_rights_remove, 7977*ee754c2dSkamil __sanitizer_cap_rights *dst, const __sanitizer_cap_rights *src) { 7978*ee754c2dSkamil void *ctx; 7979*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_remove, dst, src); 7980*ee754c2dSkamil if (src) 7981*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 7982*ee754c2dSkamil 7983*ee754c2dSkamil __sanitizer_cap_rights *ret = REAL(cap_rights_remove)(dst, src); 7984*ee754c2dSkamil if (dst) 7985*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(*dst)); 7986*ee754c2dSkamil 7987*ee754c2dSkamil return ret; 7988*ee754c2dSkamil} 7989*ee754c2dSkamil 7990*ee754c2dSkamilINTERCEPTOR(bool, cap_rights_contains, const __sanitizer_cap_rights *big, 7991*ee754c2dSkamil const __sanitizer_cap_rights *little) { 7992*ee754c2dSkamil void *ctx; 7993*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_contains, big, little); 7994*ee754c2dSkamil if (little) 7995*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, little, sizeof(*little)); 7996*ee754c2dSkamil if (big) 7997*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, big, sizeof(*big)); 7998*ee754c2dSkamil 7999*ee754c2dSkamil return REAL(cap_rights_contains)(big, little); 8000*ee754c2dSkamil} 8001*ee754c2dSkamil 8002*ee754c2dSkamilINTERCEPTOR(int, cap_ioctls_limit, int fd, const uptr *cmds, SIZE_T ncmds) { 8003*ee754c2dSkamil void *ctx; 8004*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, cap_ioctls_limit, fd, cmds, ncmds); 8005*ee754c2dSkamil if (cmds) 8006*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, cmds, sizeof(*cmds) * ncmds); 8007*ee754c2dSkamil 8008*ee754c2dSkamil return REAL(cap_ioctls_limit)(fd, cmds, ncmds); 8009*ee754c2dSkamil} 8010*ee754c2dSkamil 8011*ee754c2dSkamilINTERCEPTOR(int, cap_ioctls_get, int fd, uptr *cmds, SIZE_T maxcmds) { 8012*ee754c2dSkamil void *ctx; 8013*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, cap_ioctls_get, fd, cmds, maxcmds); 8014*ee754c2dSkamil int ret = REAL(cap_ioctls_get)(fd, cmds, maxcmds); 8015*ee754c2dSkamil if (!ret && cmds) 8016*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cmds, sizeof(*cmds) * maxcmds); 8017*ee754c2dSkamil 8018*ee754c2dSkamil return ret; 8019*ee754c2dSkamil} 8020*ee754c2dSkamil#define INIT_CAPSICUM \ 8021*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(cap_rights_init); \ 8022*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(cap_rights_set); \ 8023*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(cap_rights_clear); \ 8024*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(cap_rights_is_set); \ 8025*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(cap_rights_get); \ 8026*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(cap_rights_limit); \ 8027*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(cap_rights_contains); \ 8028*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(cap_rights_remove); \ 8029*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(cap_rights_merge); \ 8030*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(cap_rights_is_valid); \ 8031*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(cap_ioctls_get); \ 8032*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(cap_ioctls_limit) 8033*ee754c2dSkamil#else 8034*ee754c2dSkamil#define INIT_CAPSICUM 8035*ee754c2dSkamil#endif 8036*ee754c2dSkamil 8037*ee754c2dSkamil#if SANITIZER_INTERCEPT_SHA1 8038*ee754c2dSkamilINTERCEPTOR(void, SHA1Init, void *context) { 8039*ee754c2dSkamil void *ctx; 8040*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, SHA1Init, context); 8041*ee754c2dSkamil REAL(SHA1Init)(context); 8042*ee754c2dSkamil if (context) 8043*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, SHA1_CTX_sz); 8044*ee754c2dSkamil} 8045*ee754c2dSkamilINTERCEPTOR(void, SHA1Update, void *context, const u8 *data, unsigned len) { 8046*ee754c2dSkamil void *ctx; 8047*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, SHA1Update, context, data, len); 8048*ee754c2dSkamil if (data && len > 0) 8049*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); 8050*ee754c2dSkamil if (context) 8051*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA1_CTX_sz); 8052*ee754c2dSkamil REAL(SHA1Update)(context, data, len); 8053*ee754c2dSkamil if (context) 8054*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, SHA1_CTX_sz); 8055*ee754c2dSkamil} 8056*ee754c2dSkamilINTERCEPTOR(void, SHA1Final, u8 digest[20], void *context) { 8057*ee754c2dSkamil void *ctx; 8058*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, SHA1Final, digest, context); 8059*ee754c2dSkamil if (context) 8060*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA1_CTX_sz); 8061*ee754c2dSkamil REAL(SHA1Final)(digest, context); 8062*ee754c2dSkamil if (digest) 8063*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(u8) * 20); 8064*ee754c2dSkamil} 8065*ee754c2dSkamilINTERCEPTOR(void, SHA1Transform, u32 state[5], u8 buffer[64]) { 8066*ee754c2dSkamil void *ctx; 8067*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, SHA1Transform, state, buffer); 8068*ee754c2dSkamil if (state) 8069*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, state, sizeof(u32) * 5); 8070*ee754c2dSkamil if (buffer) 8071*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, sizeof(u8) * 64); 8072*ee754c2dSkamil REAL(SHA1Transform)(state, buffer); 8073*ee754c2dSkamil if (state) 8074*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, state, sizeof(u32) * 5); 8075*ee754c2dSkamil} 8076*ee754c2dSkamilINTERCEPTOR(char *, SHA1End, void *context, char *buf) { 8077*ee754c2dSkamil void *ctx; 8078*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, SHA1End, context, buf); 8079*ee754c2dSkamil if (context) 8080*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA1_CTX_sz); 8081*ee754c2dSkamil char *ret = REAL(SHA1End)(context, buf); 8082*ee754c2dSkamil if (ret) 8083*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length); 8084*ee754c2dSkamil return ret; 8085*ee754c2dSkamil} 8086*ee754c2dSkamilINTERCEPTOR(char *, SHA1File, char *filename, char *buf) { 8087*ee754c2dSkamil void *ctx; 8088*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, SHA1File, filename, buf); 8089*ee754c2dSkamil if (filename) 8090*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1); 8091*ee754c2dSkamil char *ret = REAL(SHA1File)(filename, buf); 8092*ee754c2dSkamil if (ret) 8093*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length); 8094*ee754c2dSkamil return ret; 8095*ee754c2dSkamil} 8096*ee754c2dSkamilINTERCEPTOR(char *, SHA1FileChunk, char *filename, char *buf, OFF_T offset, 8097*ee754c2dSkamil OFF_T length) { 8098*ee754c2dSkamil void *ctx; 8099*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, SHA1FileChunk, filename, buf, offset, length); 8100*ee754c2dSkamil if (filename) 8101*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1); 8102*ee754c2dSkamil char *ret = REAL(SHA1FileChunk)(filename, buf, offset, length); 8103*ee754c2dSkamil if (ret) 8104*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length); 8105*ee754c2dSkamil return ret; 8106*ee754c2dSkamil} 8107*ee754c2dSkamilINTERCEPTOR(char *, SHA1Data, u8 *data, SIZE_T len, char *buf) { 8108*ee754c2dSkamil void *ctx; 8109*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, SHA1Data, data, len, buf); 8110*ee754c2dSkamil if (data) 8111*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); 8112*ee754c2dSkamil char *ret = REAL(SHA1Data)(data, len, buf); 8113*ee754c2dSkamil if (ret) 8114*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length); 8115*ee754c2dSkamil return ret; 8116*ee754c2dSkamil} 8117*ee754c2dSkamil#define INIT_SHA1 \ 8118*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(SHA1Init); \ 8119*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(SHA1Update); \ 8120*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(SHA1Final); \ 8121*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(SHA1Transform); \ 8122*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(SHA1End); \ 8123*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(SHA1File); \ 8124*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(SHA1FileChunk); \ 8125*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(SHA1Data) 8126*ee754c2dSkamil#else 8127*ee754c2dSkamil#define INIT_SHA1 8128*ee754c2dSkamil#endif 8129*ee754c2dSkamil 8130*ee754c2dSkamil#if SANITIZER_INTERCEPT_MD4 8131*ee754c2dSkamilINTERCEPTOR(void, MD4Init, void *context) { 8132*ee754c2dSkamil void *ctx; 8133*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, MD4Init, context); 8134*ee754c2dSkamil REAL(MD4Init)(context); 8135*ee754c2dSkamil if (context) 8136*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD4_CTX_sz); 8137*ee754c2dSkamil} 8138*ee754c2dSkamil 8139*ee754c2dSkamilINTERCEPTOR(void, MD4Update, void *context, const unsigned char *data, 8140*ee754c2dSkamil unsigned int len) { 8141*ee754c2dSkamil void *ctx; 8142*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, MD4Update, context, data, len); 8143*ee754c2dSkamil if (data && len > 0) 8144*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); 8145*ee754c2dSkamil if (context) 8146*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD4_CTX_sz); 8147*ee754c2dSkamil REAL(MD4Update)(context, data, len); 8148*ee754c2dSkamil if (context) 8149*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD4_CTX_sz); 8150*ee754c2dSkamil} 8151*ee754c2dSkamil 8152*ee754c2dSkamilINTERCEPTOR(void, MD4Final, unsigned char digest[16], void *context) { 8153*ee754c2dSkamil void *ctx; 8154*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, MD4Final, digest, context); 8155*ee754c2dSkamil if (context) 8156*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD4_CTX_sz); 8157*ee754c2dSkamil REAL(MD4Final)(digest, context); 8158*ee754c2dSkamil if (digest) 8159*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(unsigned char) * 16); 8160*ee754c2dSkamil} 8161*ee754c2dSkamil 8162*ee754c2dSkamilINTERCEPTOR(char *, MD4End, void *context, char *buf) { 8163*ee754c2dSkamil void *ctx; 8164*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, MD4End, context, buf); 8165*ee754c2dSkamil if (context) 8166*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD4_CTX_sz); 8167*ee754c2dSkamil char *ret = REAL(MD4End)(context, buf); 8168*ee754c2dSkamil if (ret) 8169*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD4_return_length); 8170*ee754c2dSkamil return ret; 8171*ee754c2dSkamil} 8172*ee754c2dSkamil 8173*ee754c2dSkamilINTERCEPTOR(char *, MD4File, const char *filename, char *buf) { 8174*ee754c2dSkamil void *ctx; 8175*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, MD4File, filename, buf); 8176*ee754c2dSkamil if (filename) 8177*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1); 8178*ee754c2dSkamil char *ret = REAL(MD4File)(filename, buf); 8179*ee754c2dSkamil if (ret) 8180*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD4_return_length); 8181*ee754c2dSkamil return ret; 8182*ee754c2dSkamil} 8183*ee754c2dSkamil 8184*ee754c2dSkamilINTERCEPTOR(char *, MD4Data, const unsigned char *data, unsigned int len, 8185*ee754c2dSkamil char *buf) { 8186*ee754c2dSkamil void *ctx; 8187*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, MD4Data, data, len, buf); 8188*ee754c2dSkamil if (data && len > 0) 8189*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); 8190*ee754c2dSkamil char *ret = REAL(MD4Data)(data, len, buf); 8191*ee754c2dSkamil if (ret) 8192*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD4_return_length); 8193*ee754c2dSkamil return ret; 8194*ee754c2dSkamil} 8195*ee754c2dSkamil 8196*ee754c2dSkamil#define INIT_MD4 \ 8197*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(MD4Init); \ 8198*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(MD4Update); \ 8199*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(MD4Final); \ 8200*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(MD4End); \ 8201*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(MD4File); \ 8202*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(MD4Data) 8203*ee754c2dSkamil#else 8204*ee754c2dSkamil#define INIT_MD4 8205*ee754c2dSkamil#endif 8206*ee754c2dSkamil 8207*ee754c2dSkamil#if SANITIZER_INTERCEPT_RMD160 8208*ee754c2dSkamilINTERCEPTOR(void, RMD160Init, void *context) { 8209*ee754c2dSkamil void *ctx; 8210*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, RMD160Init, context); 8211*ee754c2dSkamil REAL(RMD160Init)(context); 8212*ee754c2dSkamil if (context) 8213*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, RMD160_CTX_sz); 8214*ee754c2dSkamil} 8215*ee754c2dSkamilINTERCEPTOR(void, RMD160Update, void *context, const u8 *data, unsigned len) { 8216*ee754c2dSkamil void *ctx; 8217*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, RMD160Update, context, data, len); 8218*ee754c2dSkamil if (data && len > 0) 8219*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); 8220*ee754c2dSkamil if (context) 8221*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, context, RMD160_CTX_sz); 8222*ee754c2dSkamil REAL(RMD160Update)(context, data, len); 8223*ee754c2dSkamil if (context) 8224*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, RMD160_CTX_sz); 8225*ee754c2dSkamil} 8226*ee754c2dSkamilINTERCEPTOR(void, RMD160Final, u8 digest[20], void *context) { 8227*ee754c2dSkamil void *ctx; 8228*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, RMD160Final, digest, context); 8229*ee754c2dSkamil if (context) 8230*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, context, RMD160_CTX_sz); 8231*ee754c2dSkamil REAL(RMD160Final)(digest, context); 8232*ee754c2dSkamil if (digest) 8233*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(u8) * 20); 8234*ee754c2dSkamil} 8235*ee754c2dSkamilINTERCEPTOR(void, RMD160Transform, u32 state[5], u16 buffer[16]) { 8236*ee754c2dSkamil void *ctx; 8237*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, RMD160Transform, state, buffer); 8238*ee754c2dSkamil if (state) 8239*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, state, sizeof(u32) * 5); 8240*ee754c2dSkamil if (buffer) 8241*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, sizeof(u32) * 16); 8242*ee754c2dSkamil REAL(RMD160Transform)(state, buffer); 8243*ee754c2dSkamil if (state) 8244*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, state, sizeof(u32) * 5); 8245*ee754c2dSkamil} 8246*ee754c2dSkamilINTERCEPTOR(char *, RMD160End, void *context, char *buf) { 8247*ee754c2dSkamil void *ctx; 8248*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, RMD160End, context, buf); 8249*ee754c2dSkamil if (context) 8250*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, context, RMD160_CTX_sz); 8251*ee754c2dSkamil char *ret = REAL(RMD160End)(context, buf); 8252*ee754c2dSkamil if (ret) 8253*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length); 8254*ee754c2dSkamil return ret; 8255*ee754c2dSkamil} 8256*ee754c2dSkamilINTERCEPTOR(char *, RMD160File, char *filename, char *buf) { 8257*ee754c2dSkamil void *ctx; 8258*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, RMD160File, filename, buf); 8259*ee754c2dSkamil if (filename) 8260*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1); 8261*ee754c2dSkamil char *ret = REAL(RMD160File)(filename, buf); 8262*ee754c2dSkamil if (ret) 8263*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length); 8264*ee754c2dSkamil return ret; 8265*ee754c2dSkamil} 8266*ee754c2dSkamilINTERCEPTOR(char *, RMD160FileChunk, char *filename, char *buf, OFF_T offset, 8267*ee754c2dSkamil OFF_T length) { 8268*ee754c2dSkamil void *ctx; 8269*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, RMD160FileChunk, filename, buf, offset, length); 8270*ee754c2dSkamil if (filename) 8271*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1); 8272*ee754c2dSkamil char *ret = REAL(RMD160FileChunk)(filename, buf, offset, length); 8273*ee754c2dSkamil if (ret) 8274*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length); 8275*ee754c2dSkamil return ret; 8276*ee754c2dSkamil} 8277*ee754c2dSkamilINTERCEPTOR(char *, RMD160Data, u8 *data, SIZE_T len, char *buf) { 8278*ee754c2dSkamil void *ctx; 8279*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, RMD160Data, data, len, buf); 8280*ee754c2dSkamil if (data && len > 0) 8281*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); 8282*ee754c2dSkamil char *ret = REAL(RMD160Data)(data, len, buf); 8283*ee754c2dSkamil if (ret) 8284*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length); 8285*ee754c2dSkamil return ret; 8286*ee754c2dSkamil} 8287*ee754c2dSkamil#define INIT_RMD160 \ 8288*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(RMD160Init); \ 8289*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(RMD160Update); \ 8290*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(RMD160Final); \ 8291*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(RMD160Transform); \ 8292*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(RMD160End); \ 8293*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(RMD160File); \ 8294*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(RMD160FileChunk); \ 8295*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(RMD160Data) 8296*ee754c2dSkamil#else 8297*ee754c2dSkamil#define INIT_RMD160 8298*ee754c2dSkamil#endif 8299*ee754c2dSkamil 8300*ee754c2dSkamil#if SANITIZER_INTERCEPT_MD5 8301*ee754c2dSkamilINTERCEPTOR(void, MD5Init, void *context) { 8302*ee754c2dSkamil void *ctx; 8303*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, MD5Init, context); 8304*ee754c2dSkamil REAL(MD5Init)(context); 8305*ee754c2dSkamil if (context) 8306*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD5_CTX_sz); 8307*ee754c2dSkamil} 8308*ee754c2dSkamil 8309*ee754c2dSkamilINTERCEPTOR(void, MD5Update, void *context, const unsigned char *data, 8310*ee754c2dSkamil unsigned int len) { 8311*ee754c2dSkamil void *ctx; 8312*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, MD5Update, context, data, len); 8313*ee754c2dSkamil if (data && len > 0) 8314*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); 8315*ee754c2dSkamil if (context) 8316*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD5_CTX_sz); 8317*ee754c2dSkamil REAL(MD5Update)(context, data, len); 8318*ee754c2dSkamil if (context) 8319*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD5_CTX_sz); 8320*ee754c2dSkamil} 8321*ee754c2dSkamil 8322*ee754c2dSkamilINTERCEPTOR(void, MD5Final, unsigned char digest[16], void *context) { 8323*ee754c2dSkamil void *ctx; 8324*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, MD5Final, digest, context); 8325*ee754c2dSkamil if (context) 8326*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD5_CTX_sz); 8327*ee754c2dSkamil REAL(MD5Final)(digest, context); 8328*ee754c2dSkamil if (digest) 8329*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(unsigned char) * 16); 8330*ee754c2dSkamil} 8331*ee754c2dSkamil 8332*ee754c2dSkamilINTERCEPTOR(char *, MD5End, void *context, char *buf) { 8333*ee754c2dSkamil void *ctx; 8334*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, MD5End, context, buf); 8335*ee754c2dSkamil if (context) 8336*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD5_CTX_sz); 8337*ee754c2dSkamil char *ret = REAL(MD5End)(context, buf); 8338*ee754c2dSkamil if (ret) 8339*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD5_return_length); 8340*ee754c2dSkamil return ret; 8341*ee754c2dSkamil} 8342*ee754c2dSkamil 8343*ee754c2dSkamilINTERCEPTOR(char *, MD5File, const char *filename, char *buf) { 8344*ee754c2dSkamil void *ctx; 8345*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, MD5File, filename, buf); 8346*ee754c2dSkamil if (filename) 8347*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1); 8348*ee754c2dSkamil char *ret = REAL(MD5File)(filename, buf); 8349*ee754c2dSkamil if (ret) 8350*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD5_return_length); 8351*ee754c2dSkamil return ret; 8352*ee754c2dSkamil} 8353*ee754c2dSkamil 8354*ee754c2dSkamilINTERCEPTOR(char *, MD5Data, const unsigned char *data, unsigned int len, 8355*ee754c2dSkamil char *buf) { 8356*ee754c2dSkamil void *ctx; 8357*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, MD5Data, data, len, buf); 8358*ee754c2dSkamil if (data && len > 0) 8359*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); 8360*ee754c2dSkamil char *ret = REAL(MD5Data)(data, len, buf); 8361*ee754c2dSkamil if (ret) 8362*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD5_return_length); 8363*ee754c2dSkamil return ret; 8364*ee754c2dSkamil} 8365*ee754c2dSkamil 8366*ee754c2dSkamil#define INIT_MD5 \ 8367*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(MD5Init); \ 8368*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(MD5Update); \ 8369*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(MD5Final); \ 8370*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(MD5End); \ 8371*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(MD5File); \ 8372*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(MD5Data) 8373*ee754c2dSkamil#else 8374*ee754c2dSkamil#define INIT_MD5 8375*ee754c2dSkamil#endif 8376*ee754c2dSkamil 8377*ee754c2dSkamil#if SANITIZER_INTERCEPT_FSEEK 8378*ee754c2dSkamilINTERCEPTOR(int, fseek, __sanitizer_FILE *stream, long int offset, int whence) { 8379*ee754c2dSkamil void *ctx; 8380*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, fseek, stream, offset, whence); 8381*ee754c2dSkamil return REAL(fseek)(stream, offset, whence); 8382*ee754c2dSkamil} 8383*ee754c2dSkamilINTERCEPTOR(int, fseeko, __sanitizer_FILE *stream, OFF_T offset, int whence) { 8384*ee754c2dSkamil void *ctx; 8385*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, fseeko, stream, offset, whence); 8386*ee754c2dSkamil return REAL(fseeko)(stream, offset, whence); 8387*ee754c2dSkamil} 8388*ee754c2dSkamilINTERCEPTOR(long int, ftell, __sanitizer_FILE *stream) { 8389*ee754c2dSkamil void *ctx; 8390*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, ftell, stream); 8391*ee754c2dSkamil return REAL(ftell)(stream); 8392*ee754c2dSkamil} 8393*ee754c2dSkamilINTERCEPTOR(OFF_T, ftello, __sanitizer_FILE *stream) { 8394*ee754c2dSkamil void *ctx; 8395*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, ftello, stream); 8396*ee754c2dSkamil return REAL(ftello)(stream); 8397*ee754c2dSkamil} 8398*ee754c2dSkamilINTERCEPTOR(void, rewind, __sanitizer_FILE *stream) { 8399*ee754c2dSkamil void *ctx; 8400*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, rewind, stream); 8401*ee754c2dSkamil return REAL(rewind)(stream); 8402*ee754c2dSkamil} 8403*ee754c2dSkamilINTERCEPTOR(int, fgetpos, __sanitizer_FILE *stream, void *pos) { 8404*ee754c2dSkamil void *ctx; 8405*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, fgetpos, stream, pos); 8406*ee754c2dSkamil int ret = REAL(fgetpos)(stream, pos); 8407*ee754c2dSkamil if (pos && !ret) 8408*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pos, fpos_t_sz); 8409*ee754c2dSkamil return ret; 8410*ee754c2dSkamil} 8411*ee754c2dSkamilINTERCEPTOR(int, fsetpos, __sanitizer_FILE *stream, const void *pos) { 8412*ee754c2dSkamil void *ctx; 8413*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, fsetpos, stream, pos); 8414*ee754c2dSkamil if (pos) 8415*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, pos, fpos_t_sz); 8416*ee754c2dSkamil return REAL(fsetpos)(stream, pos); 8417*ee754c2dSkamil} 8418*ee754c2dSkamil#define INIT_FSEEK \ 8419*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(fseek); \ 8420*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(fseeko); \ 8421*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(ftell); \ 8422*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(ftello); \ 8423*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(rewind); \ 8424*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(fgetpos); \ 8425*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(fsetpos) 8426*ee754c2dSkamil#else 8427*ee754c2dSkamil#define INIT_FSEEK 8428*ee754c2dSkamil#endif 8429*ee754c2dSkamil 8430*ee754c2dSkamil#if SANITIZER_INTERCEPT_MD2 8431*ee754c2dSkamilINTERCEPTOR(void, MD2Init, void *context) { 8432*ee754c2dSkamil void *ctx; 8433*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, MD2Init, context); 8434*ee754c2dSkamil REAL(MD2Init)(context); 8435*ee754c2dSkamil if (context) 8436*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD2_CTX_sz); 8437*ee754c2dSkamil} 8438*ee754c2dSkamil 8439*ee754c2dSkamilINTERCEPTOR(void, MD2Update, void *context, const unsigned char *data, 8440*ee754c2dSkamil unsigned int len) { 8441*ee754c2dSkamil void *ctx; 8442*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, MD2Update, context, data, len); 8443*ee754c2dSkamil if (data && len > 0) 8444*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); 8445*ee754c2dSkamil if (context) 8446*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD2_CTX_sz); 8447*ee754c2dSkamil REAL(MD2Update)(context, data, len); 8448*ee754c2dSkamil if (context) 8449*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD2_CTX_sz); 8450*ee754c2dSkamil} 8451*ee754c2dSkamil 8452*ee754c2dSkamilINTERCEPTOR(void, MD2Final, unsigned char digest[16], void *context) { 8453*ee754c2dSkamil void *ctx; 8454*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, MD2Final, digest, context); 8455*ee754c2dSkamil if (context) 8456*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD2_CTX_sz); 8457*ee754c2dSkamil REAL(MD2Final)(digest, context); 8458*ee754c2dSkamil if (digest) 8459*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(unsigned char) * 16); 8460*ee754c2dSkamil} 8461*ee754c2dSkamil 8462*ee754c2dSkamilINTERCEPTOR(char *, MD2End, void *context, char *buf) { 8463*ee754c2dSkamil void *ctx; 8464*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, MD2End, context, buf); 8465*ee754c2dSkamil if (context) 8466*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD2_CTX_sz); 8467*ee754c2dSkamil char *ret = REAL(MD2End)(context, buf); 8468*ee754c2dSkamil if (ret) 8469*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD2_return_length); 8470*ee754c2dSkamil return ret; 8471*ee754c2dSkamil} 8472*ee754c2dSkamil 8473*ee754c2dSkamilINTERCEPTOR(char *, MD2File, const char *filename, char *buf) { 8474*ee754c2dSkamil void *ctx; 8475*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, MD2File, filename, buf); 8476*ee754c2dSkamil if (filename) 8477*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1); 8478*ee754c2dSkamil char *ret = REAL(MD2File)(filename, buf); 8479*ee754c2dSkamil if (ret) 8480*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD2_return_length); 8481*ee754c2dSkamil return ret; 8482*ee754c2dSkamil} 8483*ee754c2dSkamil 8484*ee754c2dSkamilINTERCEPTOR(char *, MD2Data, const unsigned char *data, unsigned int len, 8485*ee754c2dSkamil char *buf) { 8486*ee754c2dSkamil void *ctx; 8487*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, MD2Data, data, len, buf); 8488*ee754c2dSkamil if (data && len > 0) 8489*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); 8490*ee754c2dSkamil char *ret = REAL(MD2Data)(data, len, buf); 8491*ee754c2dSkamil if (ret) 8492*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD2_return_length); 8493*ee754c2dSkamil return ret; 8494*ee754c2dSkamil} 8495*ee754c2dSkamil 8496*ee754c2dSkamil#define INIT_MD2 \ 8497*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(MD2Init); \ 8498*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(MD2Update); \ 8499*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(MD2Final); \ 8500*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(MD2End); \ 8501*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(MD2File); \ 8502*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(MD2Data) 8503*ee754c2dSkamil#else 8504*ee754c2dSkamil#define INIT_MD2 8505*ee754c2dSkamil#endif 8506*ee754c2dSkamil 8507*ee754c2dSkamil#if SANITIZER_INTERCEPT_SHA2 8508*ee754c2dSkamil#define SHA2_INTERCEPTORS(LEN, SHA2_STATE_T) \ 8509*ee754c2dSkamil INTERCEPTOR(void, SHA##LEN##_Init, void *context) { \ 8510*ee754c2dSkamil void *ctx; \ 8511*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_Init, context); \ 8512*ee754c2dSkamil REAL(SHA##LEN##_Init)(context); \ 8513*ee754c2dSkamil if (context) \ 8514*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, SHA##LEN##_CTX_sz); \ 8515*ee754c2dSkamil } \ 8516*ee754c2dSkamil INTERCEPTOR(void, SHA##LEN##_Update, void *context, \ 8517*ee754c2dSkamil const u8 *data, SIZE_T len) { \ 8518*ee754c2dSkamil void *ctx; \ 8519*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_Update, context, data, len); \ 8520*ee754c2dSkamil if (data && len > 0) \ 8521*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); \ 8522*ee754c2dSkamil if (context) \ 8523*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA##LEN##_CTX_sz); \ 8524*ee754c2dSkamil REAL(SHA##LEN##_Update)(context, data, len); \ 8525*ee754c2dSkamil if (context) \ 8526*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, SHA##LEN##_CTX_sz); \ 8527*ee754c2dSkamil } \ 8528*ee754c2dSkamil INTERCEPTOR(void, SHA##LEN##_Final, u8 digest[LEN/8], \ 8529*ee754c2dSkamil void *context) { \ 8530*ee754c2dSkamil void *ctx; \ 8531*ee754c2dSkamil CHECK_EQ(SHA##LEN##_digest_length, LEN/8); \ 8532*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_Final, digest, context); \ 8533*ee754c2dSkamil if (context) \ 8534*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA##LEN##_CTX_sz); \ 8535*ee754c2dSkamil REAL(SHA##LEN##_Final)(digest, context); \ 8536*ee754c2dSkamil if (digest) \ 8537*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, \ 8538*ee754c2dSkamil sizeof(digest[0]) * \ 8539*ee754c2dSkamil SHA##LEN##_digest_length); \ 8540*ee754c2dSkamil } \ 8541*ee754c2dSkamil INTERCEPTOR(char *, SHA##LEN##_End, void *context, char *buf) { \ 8542*ee754c2dSkamil void *ctx; \ 8543*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_End, context, buf); \ 8544*ee754c2dSkamil if (context) \ 8545*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA##LEN##_CTX_sz); \ 8546*ee754c2dSkamil char *ret = REAL(SHA##LEN##_End)(context, buf); \ 8547*ee754c2dSkamil if (ret) \ 8548*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA##LEN##_return_length); \ 8549*ee754c2dSkamil return ret; \ 8550*ee754c2dSkamil } \ 8551*ee754c2dSkamil INTERCEPTOR(char *, SHA##LEN##_File, const char *filename, char *buf) { \ 8552*ee754c2dSkamil void *ctx; \ 8553*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_File, filename, buf); \ 8554*ee754c2dSkamil if (filename) \ 8555*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1);\ 8556*ee754c2dSkamil char *ret = REAL(SHA##LEN##_File)(filename, buf); \ 8557*ee754c2dSkamil if (ret) \ 8558*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA##LEN##_return_length); \ 8559*ee754c2dSkamil return ret; \ 8560*ee754c2dSkamil } \ 8561*ee754c2dSkamil INTERCEPTOR(char *, SHA##LEN##_FileChunk, const char *filename, char *buf, \ 8562*ee754c2dSkamil OFF_T offset, OFF_T length) { \ 8563*ee754c2dSkamil void *ctx; \ 8564*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_FileChunk, filename, buf, offset, \ 8565*ee754c2dSkamil length); \ 8566*ee754c2dSkamil if (filename) \ 8567*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1);\ 8568*ee754c2dSkamil char *ret = REAL(SHA##LEN##_FileChunk)(filename, buf, offset, length); \ 8569*ee754c2dSkamil if (ret) \ 8570*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA##LEN##_return_length); \ 8571*ee754c2dSkamil return ret; \ 8572*ee754c2dSkamil } \ 8573*ee754c2dSkamil INTERCEPTOR(char *, SHA##LEN##_Data, u8 *data, SIZE_T len, char *buf) { \ 8574*ee754c2dSkamil void *ctx; \ 8575*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_Data, data, len, buf); \ 8576*ee754c2dSkamil if (data && len > 0) \ 8577*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); \ 8578*ee754c2dSkamil char *ret = REAL(SHA##LEN##_Data)(data, len, buf); \ 8579*ee754c2dSkamil if (ret) \ 8580*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA##LEN##_return_length); \ 8581*ee754c2dSkamil return ret; \ 8582*ee754c2dSkamil } 8583*ee754c2dSkamil 8584*ee754c2dSkamilSHA2_INTERCEPTORS(224, u32); 8585*ee754c2dSkamilSHA2_INTERCEPTORS(256, u32); 8586*ee754c2dSkamilSHA2_INTERCEPTORS(384, u64); 8587*ee754c2dSkamilSHA2_INTERCEPTORS(512, u64); 8588*ee754c2dSkamil 8589*ee754c2dSkamil#define INIT_SHA2_INTECEPTORS(LEN) \ 8590*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(SHA##LEN##_Init); \ 8591*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(SHA##LEN##_Update); \ 8592*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(SHA##LEN##_Final); \ 8593*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(SHA##LEN##_End); \ 8594*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(SHA##LEN##_File); \ 8595*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(SHA##LEN##_FileChunk); \ 8596*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(SHA##LEN##_Data) 8597*ee754c2dSkamil 8598*ee754c2dSkamil#define INIT_SHA2 \ 8599*ee754c2dSkamil INIT_SHA2_INTECEPTORS(224); \ 8600*ee754c2dSkamil INIT_SHA2_INTECEPTORS(256); \ 8601*ee754c2dSkamil INIT_SHA2_INTECEPTORS(384); \ 8602*ee754c2dSkamil INIT_SHA2_INTECEPTORS(512) 8603*ee754c2dSkamil#undef SHA2_INTERCEPTORS 8604*ee754c2dSkamil#else 8605*ee754c2dSkamil#define INIT_SHA2 8606*ee754c2dSkamil#endif 8607*ee754c2dSkamil 8608*ee754c2dSkamil#if SANITIZER_INTERCEPT_VIS 8609*ee754c2dSkamilINTERCEPTOR(char *, vis, char *dst, int c, int flag, int nextc) { 8610*ee754c2dSkamil void *ctx; 8611*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, vis, dst, c, flag, nextc); 8612*ee754c2dSkamil char *end = REAL(vis)(dst, c, flag, nextc); 8613*ee754c2dSkamil // dst is NULL terminated and end points to the NULL char 8614*ee754c2dSkamil if (dst && end) 8615*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, end - dst + 1); 8616*ee754c2dSkamil return end; 8617*ee754c2dSkamil} 8618*ee754c2dSkamilINTERCEPTOR(char *, nvis, char *dst, SIZE_T dlen, int c, int flag, int nextc) { 8619*ee754c2dSkamil void *ctx; 8620*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, nvis, dst, dlen, c, flag, nextc); 8621*ee754c2dSkamil char *end = REAL(nvis)(dst, dlen, c, flag, nextc); 8622*ee754c2dSkamil // nvis cannot make sure the dst is NULL terminated 8623*ee754c2dSkamil if (dst && end) 8624*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, end - dst + 1); 8625*ee754c2dSkamil return end; 8626*ee754c2dSkamil} 8627*ee754c2dSkamilINTERCEPTOR(int, strvis, char *dst, const char *src, int flag) { 8628*ee754c2dSkamil void *ctx; 8629*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strvis, dst, src, flag); 8630*ee754c2dSkamil if (src) 8631*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1); 8632*ee754c2dSkamil int len = REAL(strvis)(dst, src, flag); 8633*ee754c2dSkamil if (dst) 8634*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1); 8635*ee754c2dSkamil return len; 8636*ee754c2dSkamil} 8637*ee754c2dSkamilINTERCEPTOR(int, stravis, char **dst, const char *src, int flag) { 8638*ee754c2dSkamil void *ctx; 8639*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, stravis, dst, src, flag); 8640*ee754c2dSkamil if (src) 8641*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1); 8642*ee754c2dSkamil int len = REAL(stravis)(dst, src, flag); 8643*ee754c2dSkamil if (dst) { 8644*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(char *)); 8645*ee754c2dSkamil if (*dst) 8646*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *dst, len + 1); 8647*ee754c2dSkamil } 8648*ee754c2dSkamil return len; 8649*ee754c2dSkamil} 8650*ee754c2dSkamilINTERCEPTOR(int, strnvis, char *dst, SIZE_T dlen, const char *src, int flag) { 8651*ee754c2dSkamil void *ctx; 8652*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strnvis, dst, dlen, src, flag); 8653*ee754c2dSkamil if (src) 8654*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1); 8655*ee754c2dSkamil int len = REAL(strnvis)(dst, dlen, src, flag); 8656*ee754c2dSkamil // The interface will be valid even if there is no space for NULL char 8657*ee754c2dSkamil if (dst && len > 0) 8658*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1); 8659*ee754c2dSkamil return len; 8660*ee754c2dSkamil} 8661*ee754c2dSkamilINTERCEPTOR(int, strvisx, char *dst, const char *src, SIZE_T len, int flag) { 8662*ee754c2dSkamil void *ctx; 8663*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strvisx, dst, src, len, flag); 8664*ee754c2dSkamil if (src) 8665*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len); 8666*ee754c2dSkamil int ret = REAL(strvisx)(dst, src, len, flag); 8667*ee754c2dSkamil if (dst) 8668*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1); 8669*ee754c2dSkamil return ret; 8670*ee754c2dSkamil} 8671*ee754c2dSkamilINTERCEPTOR(int, strnvisx, char *dst, SIZE_T dlen, const char *src, SIZE_T len, 8672*ee754c2dSkamil int flag) { 8673*ee754c2dSkamil void *ctx; 8674*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strnvisx, dst, dlen, src, len, flag); 8675*ee754c2dSkamil if (src) 8676*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len); 8677*ee754c2dSkamil int ret = REAL(strnvisx)(dst, dlen, src, len, flag); 8678*ee754c2dSkamil if (dst && ret >= 0) 8679*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1); 8680*ee754c2dSkamil return ret; 8681*ee754c2dSkamil} 8682*ee754c2dSkamilINTERCEPTOR(int, strenvisx, char *dst, SIZE_T dlen, const char *src, SIZE_T len, 8683*ee754c2dSkamil int flag, int *cerr_ptr) { 8684*ee754c2dSkamil void *ctx; 8685*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strenvisx, dst, dlen, src, len, flag, cerr_ptr); 8686*ee754c2dSkamil if (src) 8687*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len); 8688*ee754c2dSkamil // FIXME: only need to be checked when "flag | VIS_NOLOCALE" doesn't hold 8689*ee754c2dSkamil // according to the implementation 8690*ee754c2dSkamil if (cerr_ptr) 8691*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, cerr_ptr, sizeof(int)); 8692*ee754c2dSkamil int ret = REAL(strenvisx)(dst, dlen, src, len, flag, cerr_ptr); 8693*ee754c2dSkamil if (dst && ret >= 0) 8694*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1); 8695*ee754c2dSkamil if (cerr_ptr) 8696*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cerr_ptr, sizeof(int)); 8697*ee754c2dSkamil return ret; 8698*ee754c2dSkamil} 8699*ee754c2dSkamilINTERCEPTOR(char *, svis, char *dst, int c, int flag, int nextc, 8700*ee754c2dSkamil const char *extra) { 8701*ee754c2dSkamil void *ctx; 8702*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, svis, dst, c, flag, nextc, extra); 8703*ee754c2dSkamil if (extra) 8704*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1); 8705*ee754c2dSkamil char *end = REAL(svis)(dst, c, flag, nextc, extra); 8706*ee754c2dSkamil if (dst && end) 8707*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, end - dst + 1); 8708*ee754c2dSkamil return end; 8709*ee754c2dSkamil} 8710*ee754c2dSkamilINTERCEPTOR(char *, snvis, char *dst, SIZE_T dlen, int c, int flag, int nextc, 8711*ee754c2dSkamil const char *extra) { 8712*ee754c2dSkamil void *ctx; 8713*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, snvis, dst, dlen, c, flag, nextc, extra); 8714*ee754c2dSkamil if (extra) 8715*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1); 8716*ee754c2dSkamil char *end = REAL(snvis)(dst, dlen, c, flag, nextc, extra); 8717*ee754c2dSkamil if (dst && end) 8718*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, 8719*ee754c2dSkamil Min((SIZE_T)(end - dst + 1), dlen)); 8720*ee754c2dSkamil return end; 8721*ee754c2dSkamil} 8722*ee754c2dSkamilINTERCEPTOR(int, strsvis, char *dst, const char *src, int flag, 8723*ee754c2dSkamil const char *extra) { 8724*ee754c2dSkamil void *ctx; 8725*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strsvis, dst, src, flag, extra); 8726*ee754c2dSkamil if (src) 8727*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1); 8728*ee754c2dSkamil if (extra) 8729*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1); 8730*ee754c2dSkamil int len = REAL(strsvis)(dst, src, flag, extra); 8731*ee754c2dSkamil if (dst) 8732*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1); 8733*ee754c2dSkamil return len; 8734*ee754c2dSkamil} 8735*ee754c2dSkamilINTERCEPTOR(int, strsnvis, char *dst, SIZE_T dlen, const char *src, int flag, 8736*ee754c2dSkamil const char *extra) { 8737*ee754c2dSkamil void *ctx; 8738*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strsnvis, dst, dlen, src, flag, extra); 8739*ee754c2dSkamil if (src) 8740*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1); 8741*ee754c2dSkamil if (extra) 8742*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1); 8743*ee754c2dSkamil int len = REAL(strsnvis)(dst, dlen, src, flag, extra); 8744*ee754c2dSkamil // The interface will be valid even if there is no space for NULL char 8745*ee754c2dSkamil if (dst && len >= 0) 8746*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1); 8747*ee754c2dSkamil return len; 8748*ee754c2dSkamil} 8749*ee754c2dSkamilINTERCEPTOR(int, strsvisx, char *dst, const char *src, SIZE_T len, int flag, 8750*ee754c2dSkamil const char *extra) { 8751*ee754c2dSkamil void *ctx; 8752*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strsvisx, dst, src, len, flag, extra); 8753*ee754c2dSkamil if (src) 8754*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len); 8755*ee754c2dSkamil if (extra) 8756*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1); 8757*ee754c2dSkamil int ret = REAL(strsvisx)(dst, src, len, flag, extra); 8758*ee754c2dSkamil if (dst) 8759*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1); 8760*ee754c2dSkamil return ret; 8761*ee754c2dSkamil} 8762*ee754c2dSkamilINTERCEPTOR(int, strsnvisx, char *dst, SIZE_T dlen, const char *src, SIZE_T len, 8763*ee754c2dSkamil int flag, const char *extra) { 8764*ee754c2dSkamil void *ctx; 8765*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strsnvisx, dst, dlen, src, len, flag, extra); 8766*ee754c2dSkamil if (src) 8767*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len); 8768*ee754c2dSkamil if (extra) 8769*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1); 8770*ee754c2dSkamil int ret = REAL(strsnvisx)(dst, dlen, src, len, flag, extra); 8771*ee754c2dSkamil if (dst && ret >= 0) 8772*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1); 8773*ee754c2dSkamil return ret; 8774*ee754c2dSkamil} 8775*ee754c2dSkamilINTERCEPTOR(int, strsenvisx, char *dst, SIZE_T dlen, const char *src, 8776*ee754c2dSkamil SIZE_T len, int flag, const char *extra, int *cerr_ptr) { 8777*ee754c2dSkamil void *ctx; 8778*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strsenvisx, dst, dlen, src, len, flag, extra, 8779*ee754c2dSkamil cerr_ptr); 8780*ee754c2dSkamil if (src) 8781*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len); 8782*ee754c2dSkamil if (extra) 8783*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1); 8784*ee754c2dSkamil // FIXME: only need to be checked when "flag | VIS_NOLOCALE" doesn't hold 8785*ee754c2dSkamil // according to the implementation 8786*ee754c2dSkamil if (cerr_ptr) 8787*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, cerr_ptr, sizeof(int)); 8788*ee754c2dSkamil int ret = REAL(strsenvisx)(dst, dlen, src, len, flag, extra, cerr_ptr); 8789*ee754c2dSkamil if (dst && ret >= 0) 8790*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1); 8791*ee754c2dSkamil if (cerr_ptr) 8792*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cerr_ptr, sizeof(int)); 8793*ee754c2dSkamil return ret; 8794*ee754c2dSkamil} 8795*ee754c2dSkamilINTERCEPTOR(int, unvis, char *cp, int c, int *astate, int flag) { 8796*ee754c2dSkamil void *ctx; 8797*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, unvis, cp, c, astate, flag); 8798*ee754c2dSkamil if (astate) 8799*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, astate, sizeof(*astate)); 8800*ee754c2dSkamil int ret = REAL(unvis)(cp, c, astate, flag); 8801*ee754c2dSkamil if (ret == unvis_valid || ret == unvis_validpush) { 8802*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cp, sizeof(*cp)); 8803*ee754c2dSkamil } 8804*ee754c2dSkamil return ret; 8805*ee754c2dSkamil} 8806*ee754c2dSkamilINTERCEPTOR(int, strunvis, char *dst, const char *src) { 8807*ee754c2dSkamil void *ctx; 8808*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strunvis, dst, src); 8809*ee754c2dSkamil if (src) 8810*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1); 8811*ee754c2dSkamil int ret = REAL(strunvis)(dst, src); 8812*ee754c2dSkamil if (ret != -1) 8813*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1); 8814*ee754c2dSkamil return ret; 8815*ee754c2dSkamil} 8816*ee754c2dSkamilINTERCEPTOR(int, strnunvis, char *dst, SIZE_T dlen, const char *src) { 8817*ee754c2dSkamil void *ctx; 8818*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strnunvis, dst, dlen, src); 8819*ee754c2dSkamil if (src) 8820*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1); 8821*ee754c2dSkamil int ret = REAL(strnunvis)(dst, dlen, src); 8822*ee754c2dSkamil if (ret != -1) 8823*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1); 8824*ee754c2dSkamil return ret; 8825*ee754c2dSkamil} 8826*ee754c2dSkamilINTERCEPTOR(int, strunvisx, char *dst, const char *src, int flag) { 8827*ee754c2dSkamil void *ctx; 8828*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strunvisx, dst, src, flag); 8829*ee754c2dSkamil if (src) 8830*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1); 8831*ee754c2dSkamil int ret = REAL(strunvisx)(dst, src, flag); 8832*ee754c2dSkamil if (ret != -1) 8833*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1); 8834*ee754c2dSkamil return ret; 8835*ee754c2dSkamil} 8836*ee754c2dSkamilINTERCEPTOR(int, strnunvisx, char *dst, SIZE_T dlen, const char *src, 8837*ee754c2dSkamil int flag) { 8838*ee754c2dSkamil void *ctx; 8839*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, strnunvisx, dst, dlen, src, flag); 8840*ee754c2dSkamil if (src) 8841*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1); 8842*ee754c2dSkamil int ret = REAL(strnunvisx)(dst, dlen, src, flag); 8843*ee754c2dSkamil if (ret != -1) 8844*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1); 8845*ee754c2dSkamil return ret; 8846*ee754c2dSkamil} 8847*ee754c2dSkamil#define INIT_VIS \ 8848*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(vis); \ 8849*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(nvis); \ 8850*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(strvis); \ 8851*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(stravis); \ 8852*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(strnvis); \ 8853*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(strvisx); \ 8854*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(strnvisx); \ 8855*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(strenvisx); \ 8856*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(svis); \ 8857*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(snvis); \ 8858*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(strsvis); \ 8859*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(strsnvis); \ 8860*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(strsvisx); \ 8861*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(strsnvisx); \ 8862*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(strsenvisx); \ 8863*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(unvis); \ 8864*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(strunvis); \ 8865*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(strnunvis); \ 8866*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(strunvisx); \ 8867*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(strnunvisx) 8868*ee754c2dSkamil#else 8869*ee754c2dSkamil#define INIT_VIS 8870*ee754c2dSkamil#endif 8871*ee754c2dSkamil 8872*ee754c2dSkamil#if SANITIZER_INTERCEPT_CDB 8873*ee754c2dSkamilINTERCEPTOR(struct __sanitizer_cdbr *, cdbr_open, const char *path, int flags) { 8874*ee754c2dSkamil void *ctx; 8875*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, cdbr_open, path, flags); 8876*ee754c2dSkamil if (path) 8877*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 8878*ee754c2dSkamil struct __sanitizer_cdbr *cdbr = REAL(cdbr_open)(path, flags); 8879*ee754c2dSkamil if (cdbr) 8880*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbr, sizeof(*cdbr)); 8881*ee754c2dSkamil return cdbr; 8882*ee754c2dSkamil} 8883*ee754c2dSkamil 8884*ee754c2dSkamilINTERCEPTOR(struct __sanitizer_cdbr *, cdbr_open_mem, void *base, SIZE_T size, 8885*ee754c2dSkamil int flags, void (*unmap)(void *, void *, SIZE_T), void *cookie) { 8886*ee754c2dSkamil void *ctx; 8887*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, cdbr_open_mem, base, size, flags, unmap, 8888*ee754c2dSkamil cookie); 8889*ee754c2dSkamil if (base && size) 8890*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, base, size); 8891*ee754c2dSkamil struct __sanitizer_cdbr *cdbr = 8892*ee754c2dSkamil REAL(cdbr_open_mem)(base, size, flags, unmap, cookie); 8893*ee754c2dSkamil if (cdbr) 8894*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbr, sizeof(*cdbr)); 8895*ee754c2dSkamil return cdbr; 8896*ee754c2dSkamil} 8897*ee754c2dSkamil 8898*ee754c2dSkamilINTERCEPTOR(u32, cdbr_entries, struct __sanitizer_cdbr *cdbr) { 8899*ee754c2dSkamil void *ctx; 8900*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, cdbr_entries, cdbr); 8901*ee754c2dSkamil if (cdbr) 8902*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr)); 8903*ee754c2dSkamil return REAL(cdbr_entries)(cdbr); 8904*ee754c2dSkamil} 8905*ee754c2dSkamil 8906*ee754c2dSkamilINTERCEPTOR(int, cdbr_get, struct __sanitizer_cdbr *cdbr, u32 index, 8907*ee754c2dSkamil const void **data, SIZE_T *datalen) { 8908*ee754c2dSkamil void *ctx; 8909*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, cdbr_get, cdbr, index, data, datalen); 8910*ee754c2dSkamil if (cdbr) 8911*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr)); 8912*ee754c2dSkamil int ret = REAL(cdbr_get)(cdbr, index, data, datalen); 8913*ee754c2dSkamil if (!ret) { 8914*ee754c2dSkamil if (data) 8915*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, sizeof(*data)); 8916*ee754c2dSkamil if (datalen) 8917*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, datalen, sizeof(*datalen)); 8918*ee754c2dSkamil if (data && datalen) 8919*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *data, *datalen); 8920*ee754c2dSkamil } 8921*ee754c2dSkamil return ret; 8922*ee754c2dSkamil} 8923*ee754c2dSkamil 8924*ee754c2dSkamilINTERCEPTOR(int, cdbr_find, struct __sanitizer_cdbr *cdbr, const void *key, 8925*ee754c2dSkamil SIZE_T keylen, const void **data, SIZE_T *datalen) { 8926*ee754c2dSkamil void *ctx; 8927*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, cdbr_find, cdbr, key, keylen, data, datalen); 8928*ee754c2dSkamil if (cdbr) 8929*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr)); 8930*ee754c2dSkamil if (key) 8931*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, key, keylen); 8932*ee754c2dSkamil int ret = REAL(cdbr_find)(cdbr, key, keylen, data, datalen); 8933*ee754c2dSkamil if (!ret) { 8934*ee754c2dSkamil if (data) 8935*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, sizeof(*data)); 8936*ee754c2dSkamil if (datalen) 8937*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, datalen, sizeof(*datalen)); 8938*ee754c2dSkamil if (data && datalen) 8939*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *data, *datalen); 8940*ee754c2dSkamil } 8941*ee754c2dSkamil return ret; 8942*ee754c2dSkamil} 8943*ee754c2dSkamil 8944*ee754c2dSkamilINTERCEPTOR(void, cdbr_close, struct __sanitizer_cdbr *cdbr) { 8945*ee754c2dSkamil void *ctx; 8946*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, cdbr_close, cdbr); 8947*ee754c2dSkamil if (cdbr) 8948*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr)); 8949*ee754c2dSkamil REAL(cdbr_close)(cdbr); 8950*ee754c2dSkamil} 8951*ee754c2dSkamil 8952*ee754c2dSkamilINTERCEPTOR(struct __sanitizer_cdbw *, cdbw_open) { 8953*ee754c2dSkamil void *ctx; 8954*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, cdbw_open); 8955*ee754c2dSkamil struct __sanitizer_cdbw *ret = REAL(cdbw_open)(); 8956*ee754c2dSkamil if (ret) 8957*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret)); 8958*ee754c2dSkamil return ret; 8959*ee754c2dSkamil} 8960*ee754c2dSkamil 8961*ee754c2dSkamilINTERCEPTOR(int, cdbw_put, struct __sanitizer_cdbw *cdbw, const void *key, 8962*ee754c2dSkamil SIZE_T keylen, const void *data, SIZE_T datalen) { 8963*ee754c2dSkamil void *ctx; 8964*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, cdbw_put, cdbw, key, keylen, data, datalen); 8965*ee754c2dSkamil if (cdbw) 8966*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw)); 8967*ee754c2dSkamil if (data && datalen) 8968*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, data, datalen); 8969*ee754c2dSkamil if (key && keylen) 8970*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, key, keylen); 8971*ee754c2dSkamil int ret = REAL(cdbw_put)(cdbw, key, keylen, data, datalen); 8972*ee754c2dSkamil if (!ret && cdbw) 8973*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw)); 8974*ee754c2dSkamil return ret; 8975*ee754c2dSkamil} 8976*ee754c2dSkamil 8977*ee754c2dSkamilINTERCEPTOR(int, cdbw_put_data, struct __sanitizer_cdbw *cdbw, const void *data, 8978*ee754c2dSkamil SIZE_T datalen, u32 *index) { 8979*ee754c2dSkamil void *ctx; 8980*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, cdbw_put_data, cdbw, data, datalen, index); 8981*ee754c2dSkamil if (cdbw) 8982*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw)); 8983*ee754c2dSkamil if (data && datalen) 8984*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, data, datalen); 8985*ee754c2dSkamil int ret = REAL(cdbw_put_data)(cdbw, data, datalen, index); 8986*ee754c2dSkamil if (!ret) { 8987*ee754c2dSkamil if (index) 8988*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, index, sizeof(*index)); 8989*ee754c2dSkamil if (cdbw) 8990*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw)); 8991*ee754c2dSkamil } 8992*ee754c2dSkamil return ret; 8993*ee754c2dSkamil} 8994*ee754c2dSkamil 8995*ee754c2dSkamilINTERCEPTOR(int, cdbw_put_key, struct __sanitizer_cdbw *cdbw, const void *key, 8996*ee754c2dSkamil SIZE_T keylen, u32 index) { 8997*ee754c2dSkamil void *ctx; 8998*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, cdbw_put_key, cdbw, key, keylen, index); 8999*ee754c2dSkamil if (cdbw) 9000*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw)); 9001*ee754c2dSkamil if (key && keylen) 9002*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, key, keylen); 9003*ee754c2dSkamil int ret = REAL(cdbw_put_key)(cdbw, key, keylen, index); 9004*ee754c2dSkamil if (!ret && cdbw) 9005*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw)); 9006*ee754c2dSkamil return ret; 9007*ee754c2dSkamil} 9008*ee754c2dSkamil 9009*ee754c2dSkamilINTERCEPTOR(int, cdbw_output, struct __sanitizer_cdbw *cdbw, int output, 9010*ee754c2dSkamil const char descr[16], u32 (*seedgen)(void)) { 9011*ee754c2dSkamil void *ctx; 9012*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, cdbw_output, cdbw, output, descr, seedgen); 9013*ee754c2dSkamil COMMON_INTERCEPTOR_FD_ACCESS(ctx, output); 9014*ee754c2dSkamil if (cdbw) 9015*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw)); 9016*ee754c2dSkamil if (descr) 9017*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, descr, internal_strnlen(descr, 16)); 9018*ee754c2dSkamil if (seedgen) 9019*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, (void *)seedgen, sizeof(seedgen)); 9020*ee754c2dSkamil int ret = REAL(cdbw_output)(cdbw, output, descr, seedgen); 9021*ee754c2dSkamil if (!ret) { 9022*ee754c2dSkamil if (cdbw) 9023*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw)); 9024*ee754c2dSkamil if (output >= 0) 9025*ee754c2dSkamil COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, output); 9026*ee754c2dSkamil } 9027*ee754c2dSkamil return ret; 9028*ee754c2dSkamil} 9029*ee754c2dSkamil 9030*ee754c2dSkamilINTERCEPTOR(void, cdbw_close, struct __sanitizer_cdbw *cdbw) { 9031*ee754c2dSkamil void *ctx; 9032*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, cdbw_close, cdbw); 9033*ee754c2dSkamil if (cdbw) 9034*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw)); 9035*ee754c2dSkamil REAL(cdbw_close)(cdbw); 9036*ee754c2dSkamil} 9037*ee754c2dSkamil 9038*ee754c2dSkamil#define INIT_CDB \ 9039*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(cdbr_open); \ 9040*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(cdbr_open_mem); \ 9041*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(cdbr_entries); \ 9042*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(cdbr_get); \ 9043*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(cdbr_find); \ 9044*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(cdbr_close); \ 9045*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(cdbw_open); \ 9046*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(cdbw_put); \ 9047*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(cdbw_put_data); \ 9048*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(cdbw_put_key); \ 9049*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(cdbw_output); \ 9050*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(cdbw_close) 9051*ee754c2dSkamil#else 9052*ee754c2dSkamil#define INIT_CDB 9053*ee754c2dSkamil#endif 9054*ee754c2dSkamil 9055*ee754c2dSkamil#if SANITIZER_INTERCEPT_GETFSENT 9056*ee754c2dSkamilINTERCEPTOR(void *, getfsent) { 9057*ee754c2dSkamil void *ctx; 9058*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getfsent); 9059*ee754c2dSkamil void *ret = REAL(getfsent)(); 9060*ee754c2dSkamil if (ret) 9061*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, struct_fstab_sz); 9062*ee754c2dSkamil return ret; 9063*ee754c2dSkamil} 9064*ee754c2dSkamil 9065*ee754c2dSkamilINTERCEPTOR(void *, getfsspec, const char *spec) { 9066*ee754c2dSkamil void *ctx; 9067*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getfsspec, spec); 9068*ee754c2dSkamil if (spec) 9069*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, spec, REAL(strlen)(spec) + 1); 9070*ee754c2dSkamil void *ret = REAL(getfsspec)(spec); 9071*ee754c2dSkamil if (ret) 9072*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, struct_fstab_sz); 9073*ee754c2dSkamil return ret; 9074*ee754c2dSkamil} 9075*ee754c2dSkamil 9076*ee754c2dSkamilINTERCEPTOR(void *, getfsfile, const char *file) { 9077*ee754c2dSkamil void *ctx; 9078*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, getfsfile, file); 9079*ee754c2dSkamil if (file) 9080*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, file, REAL(strlen)(file) + 1); 9081*ee754c2dSkamil void *ret = REAL(getfsfile)(file); 9082*ee754c2dSkamil if (ret) 9083*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, struct_fstab_sz); 9084*ee754c2dSkamil return ret; 9085*ee754c2dSkamil} 9086*ee754c2dSkamil 9087*ee754c2dSkamil#define INIT_GETFSENT \ 9088*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(getfsent); \ 9089*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(getfsspec); \ 9090*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(getfsfile); 9091*ee754c2dSkamil#else 9092*ee754c2dSkamil#define INIT_GETFSENT 9093*ee754c2dSkamil#endif 9094*ee754c2dSkamil 9095*ee754c2dSkamil#if SANITIZER_INTERCEPT_ARC4RANDOM 9096*ee754c2dSkamilINTERCEPTOR(void, arc4random_buf, void *buf, SIZE_T len) { 9097*ee754c2dSkamil void *ctx; 9098*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, arc4random_buf, buf, len); 9099*ee754c2dSkamil REAL(arc4random_buf)(buf, len); 9100*ee754c2dSkamil if (buf && len) 9101*ee754c2dSkamil COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, len); 9102*ee754c2dSkamil} 9103*ee754c2dSkamil 9104*ee754c2dSkamilINTERCEPTOR(void, arc4random_addrandom, u8 *dat, int datlen) { 9105*ee754c2dSkamil void *ctx; 9106*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, arc4random_addrandom, dat, datlen); 9107*ee754c2dSkamil if (dat && datlen) 9108*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, dat, datlen); 9109*ee754c2dSkamil REAL(arc4random_addrandom)(dat, datlen); 9110*ee754c2dSkamil} 9111*ee754c2dSkamil 9112*ee754c2dSkamil#define INIT_ARC4RANDOM \ 9113*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(arc4random_buf); \ 9114*ee754c2dSkamil COMMON_INTERCEPT_FUNCTION(arc4random_addrandom); 9115*ee754c2dSkamil#else 9116*ee754c2dSkamil#define INIT_ARC4RANDOM 9117*ee754c2dSkamil#endif 9118*ee754c2dSkamil 9119*ee754c2dSkamil#if SANITIZER_INTERCEPT_POPEN 9120*ee754c2dSkamilINTERCEPTOR(__sanitizer_FILE *, popen, const char *command, const char *type) { 9121*ee754c2dSkamil void *ctx; 9122*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, popen, command, type); 9123*ee754c2dSkamil if (command) 9124*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, command, REAL(strlen)(command) + 1); 9125*ee754c2dSkamil if (type) 9126*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, type, REAL(strlen)(type) + 1); 9127*ee754c2dSkamil __sanitizer_FILE *res = REAL(popen)(command, type); 9128*ee754c2dSkamil COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, nullptr); 9129*ee754c2dSkamil if (res) unpoison_file(res); 9130*ee754c2dSkamil return res; 9131*ee754c2dSkamil} 9132*ee754c2dSkamil#define INIT_POPEN COMMON_INTERCEPT_FUNCTION(popen) 9133*ee754c2dSkamil#else 9134*ee754c2dSkamil#define INIT_POPEN 9135*ee754c2dSkamil#endif 9136*ee754c2dSkamil 9137*ee754c2dSkamil#if SANITIZER_INTERCEPT_POPENVE 9138*ee754c2dSkamilINTERCEPTOR(__sanitizer_FILE *, popenve, const char *path, 9139*ee754c2dSkamil char *const *argv, char *const *envp, const char *type) { 9140*ee754c2dSkamil void *ctx; 9141*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, popenve, path, argv, envp, type); 9142*ee754c2dSkamil if (path) 9143*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 9144*ee754c2dSkamil if (argv) { 9145*ee754c2dSkamil for (char *const *pa = argv; ; ++pa) { 9146*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, pa, sizeof(char **)); 9147*ee754c2dSkamil if (!*pa) 9148*ee754c2dSkamil break; 9149*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, REAL(strlen)(*pa) + 1); 9150*ee754c2dSkamil } 9151*ee754c2dSkamil } 9152*ee754c2dSkamil if (envp) { 9153*ee754c2dSkamil for (char *const *pa = envp; ; ++pa) { 9154*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, pa, sizeof(char **)); 9155*ee754c2dSkamil if (!*pa) 9156*ee754c2dSkamil break; 9157*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, REAL(strlen)(*pa) + 1); 9158*ee754c2dSkamil } 9159*ee754c2dSkamil } 9160*ee754c2dSkamil if (type) 9161*ee754c2dSkamil COMMON_INTERCEPTOR_READ_RANGE(ctx, type, REAL(strlen)(type) + 1); 9162*ee754c2dSkamil __sanitizer_FILE *res = REAL(popenve)(path, argv, envp, type); 9163*ee754c2dSkamil COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, nullptr); 9164*ee754c2dSkamil if (res) unpoison_file(res); 9165*ee754c2dSkamil return res; 9166*ee754c2dSkamil} 9167*ee754c2dSkamil#define INIT_POPENVE COMMON_INTERCEPT_FUNCTION(popenve) 9168*ee754c2dSkamil#else 9169*ee754c2dSkamil#define INIT_POPENVE 9170*ee754c2dSkamil#endif 9171*ee754c2dSkamil 9172*ee754c2dSkamil#if SANITIZER_INTERCEPT_PCLOSE 9173*ee754c2dSkamilINTERCEPTOR(int, pclose, __sanitizer_FILE *fp) { 9174*ee754c2dSkamil void *ctx; 9175*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, pclose, fp); 9176*ee754c2dSkamil COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp); 9177*ee754c2dSkamil const FileMetadata *m = GetInterceptorMetadata(fp); 9178*ee754c2dSkamil int res = REAL(pclose)(fp); 9179*ee754c2dSkamil if (m) { 9180*ee754c2dSkamil COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size); 9181*ee754c2dSkamil DeleteInterceptorMetadata(fp); 9182*ee754c2dSkamil } 9183*ee754c2dSkamil return res; 9184*ee754c2dSkamil} 9185*ee754c2dSkamil#define INIT_PCLOSE COMMON_INTERCEPT_FUNCTION(pclose); 9186*ee754c2dSkamil#else 9187*ee754c2dSkamil#define INIT_PCLOSE 9188*ee754c2dSkamil#endif 9189*ee754c2dSkamil 9190*ee754c2dSkamil#if SANITIZER_INTERCEPT_FUNOPEN 9191*ee754c2dSkamiltypedef int (*funopen_readfn)(void *cookie, char *buf, int len); 9192*ee754c2dSkamiltypedef int (*funopen_writefn)(void *cookie, const char *buf, int len); 9193*ee754c2dSkamiltypedef OFF_T (*funopen_seekfn)(void *cookie, OFF_T offset, int whence); 9194*ee754c2dSkamiltypedef int (*funopen_closefn)(void *cookie); 9195*ee754c2dSkamil 9196*ee754c2dSkamilstruct WrappedFunopenCookie { 9197*ee754c2dSkamil void *real_cookie; 9198*ee754c2dSkamil funopen_readfn real_read; 9199*ee754c2dSkamil funopen_writefn real_write; 9200*ee754c2dSkamil funopen_seekfn real_seek; 9201*ee754c2dSkamil funopen_closefn real_close; 9202*ee754c2dSkamil}; 9203*ee754c2dSkamil 9204*ee754c2dSkamilstatic int wrapped_funopen_read(void *cookie, char *buf, int len) { 9205*ee754c2dSkamil COMMON_INTERCEPTOR_UNPOISON_PARAM(3); 9206*ee754c2dSkamil WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie; 9207*ee754c2dSkamil funopen_readfn real_read = wrapped_cookie->real_read; 9208*ee754c2dSkamil return real_read(wrapped_cookie->real_cookie, buf, len); 9209*ee754c2dSkamil} 9210*ee754c2dSkamil 9211*ee754c2dSkamilstatic int wrapped_funopen_write(void *cookie, const char *buf, int len) { 9212*ee754c2dSkamil COMMON_INTERCEPTOR_UNPOISON_PARAM(3); 9213*ee754c2dSkamil WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie; 9214*ee754c2dSkamil funopen_writefn real_write = wrapped_cookie->real_write; 9215*ee754c2dSkamil return real_write(wrapped_cookie->real_cookie, buf, len); 9216*ee754c2dSkamil} 9217*ee754c2dSkamil 9218*ee754c2dSkamilstatic OFF_T wrapped_funopen_seek(void *cookie, OFF_T offset, int whence) { 9219*ee754c2dSkamil COMMON_INTERCEPTOR_UNPOISON_PARAM(3); 9220*ee754c2dSkamil WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie; 9221*ee754c2dSkamil funopen_seekfn real_seek = wrapped_cookie->real_seek; 9222*ee754c2dSkamil return real_seek(wrapped_cookie->real_cookie, offset, whence); 9223*ee754c2dSkamil} 9224*ee754c2dSkamil 9225*ee754c2dSkamilstatic int wrapped_funopen_close(void *cookie) { 9226*ee754c2dSkamil COMMON_INTERCEPTOR_UNPOISON_PARAM(1); 9227*ee754c2dSkamil WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie; 9228*ee754c2dSkamil funopen_closefn real_close = wrapped_cookie->real_close; 9229*ee754c2dSkamil int res = real_close(wrapped_cookie->real_cookie); 9230*ee754c2dSkamil InternalFree(wrapped_cookie); 9231*ee754c2dSkamil return res; 9232*ee754c2dSkamil} 9233*ee754c2dSkamil 9234*ee754c2dSkamilINTERCEPTOR(__sanitizer_FILE *, funopen, void *cookie, funopen_readfn readfn, 9235*ee754c2dSkamil funopen_writefn writefn, funopen_seekfn seekfn, 9236*ee754c2dSkamil funopen_closefn closefn) { 9237*ee754c2dSkamil void *ctx; 9238*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, funopen, cookie, readfn, writefn, seekfn, 9239*ee754c2dSkamil closefn); 9240*ee754c2dSkamil 9241*ee754c2dSkamil WrappedFunopenCookie *wrapped_cookie = 9242*ee754c2dSkamil (WrappedFunopenCookie *)InternalAlloc(sizeof(WrappedFunopenCookie)); 9243*ee754c2dSkamil wrapped_cookie->real_cookie = cookie; 9244*ee754c2dSkamil wrapped_cookie->real_read = readfn; 9245*ee754c2dSkamil wrapped_cookie->real_write = writefn; 9246*ee754c2dSkamil wrapped_cookie->real_seek = seekfn; 9247*ee754c2dSkamil wrapped_cookie->real_close = closefn; 9248*ee754c2dSkamil 9249*ee754c2dSkamil __sanitizer_FILE *res = 9250*ee754c2dSkamil REAL(funopen)(wrapped_cookie, 9251*ee754c2dSkamil readfn ? wrapped_funopen_read : nullptr, 9252*ee754c2dSkamil writefn ? wrapped_funopen_write : nullptr, 9253*ee754c2dSkamil seekfn ? wrapped_funopen_seek : nullptr, 9254*ee754c2dSkamil closefn ? wrapped_funopen_close : nullptr); 9255*ee754c2dSkamil if (res) 9256*ee754c2dSkamil unpoison_file(res); 9257*ee754c2dSkamil return res; 9258*ee754c2dSkamil} 9259*ee754c2dSkamil#define INIT_FUNOPEN COMMON_INTERCEPT_FUNCTION(funopen) 9260*ee754c2dSkamil#else 9261*ee754c2dSkamil#define INIT_FUNOPEN 9262*ee754c2dSkamil#endif 9263*ee754c2dSkamil 9264*ee754c2dSkamil#if SANITIZER_INTERCEPT_FUNOPEN2 9265*ee754c2dSkamiltypedef SSIZE_T (*funopen2_readfn)(void *cookie, void *buf, SIZE_T len); 9266*ee754c2dSkamiltypedef SSIZE_T (*funopen2_writefn)(void *cookie, const void *buf, SIZE_T len); 9267*ee754c2dSkamiltypedef OFF_T (*funopen2_seekfn)(void *cookie, OFF_T offset, int whence); 9268*ee754c2dSkamiltypedef int (*funopen2_flushfn)(void *cookie); 9269*ee754c2dSkamiltypedef int (*funopen2_closefn)(void *cookie); 9270*ee754c2dSkamil 9271*ee754c2dSkamilstruct WrappedFunopen2Cookie { 9272*ee754c2dSkamil void *real_cookie; 9273*ee754c2dSkamil funopen2_readfn real_read; 9274*ee754c2dSkamil funopen2_writefn real_write; 9275*ee754c2dSkamil funopen2_seekfn real_seek; 9276*ee754c2dSkamil funopen2_flushfn real_flush; 9277*ee754c2dSkamil funopen2_closefn real_close; 9278*ee754c2dSkamil}; 9279*ee754c2dSkamil 9280*ee754c2dSkamilstatic SSIZE_T wrapped_funopen2_read(void *cookie, void *buf, SIZE_T len) { 9281*ee754c2dSkamil COMMON_INTERCEPTOR_UNPOISON_PARAM(3); 9282*ee754c2dSkamil WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie; 9283*ee754c2dSkamil funopen2_readfn real_read = wrapped_cookie->real_read; 9284*ee754c2dSkamil return real_read(wrapped_cookie->real_cookie, buf, len); 9285*ee754c2dSkamil} 9286*ee754c2dSkamil 9287*ee754c2dSkamilstatic SSIZE_T wrapped_funopen2_write(void *cookie, const void *buf, 9288*ee754c2dSkamil SIZE_T len) { 9289*ee754c2dSkamil COMMON_INTERCEPTOR_UNPOISON_PARAM(3); 9290*ee754c2dSkamil WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie; 9291*ee754c2dSkamil funopen2_writefn real_write = wrapped_cookie->real_write; 9292*ee754c2dSkamil return real_write(wrapped_cookie->real_cookie, buf, len); 9293*ee754c2dSkamil} 9294*ee754c2dSkamil 9295*ee754c2dSkamilstatic OFF_T wrapped_funopen2_seek(void *cookie, OFF_T offset, int whence) { 9296*ee754c2dSkamil COMMON_INTERCEPTOR_UNPOISON_PARAM(3); 9297*ee754c2dSkamil WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie; 9298*ee754c2dSkamil funopen2_seekfn real_seek = wrapped_cookie->real_seek; 9299*ee754c2dSkamil return real_seek(wrapped_cookie->real_cookie, offset, whence); 9300*ee754c2dSkamil} 9301*ee754c2dSkamil 9302*ee754c2dSkamilstatic int wrapped_funopen2_flush(void *cookie) { 9303*ee754c2dSkamil COMMON_INTERCEPTOR_UNPOISON_PARAM(1); 9304*ee754c2dSkamil WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie; 9305*ee754c2dSkamil funopen2_flushfn real_flush = wrapped_cookie->real_flush; 9306*ee754c2dSkamil return real_flush(wrapped_cookie->real_cookie); 9307*ee754c2dSkamil} 9308*ee754c2dSkamil 9309*ee754c2dSkamilstatic int wrapped_funopen2_close(void *cookie) { 9310*ee754c2dSkamil COMMON_INTERCEPTOR_UNPOISON_PARAM(1); 9311*ee754c2dSkamil WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie; 9312*ee754c2dSkamil funopen2_closefn real_close = wrapped_cookie->real_close; 9313*ee754c2dSkamil int res = real_close(wrapped_cookie->real_cookie); 9314*ee754c2dSkamil InternalFree(wrapped_cookie); 9315*ee754c2dSkamil return res; 9316*ee754c2dSkamil} 9317*ee754c2dSkamil 9318*ee754c2dSkamilINTERCEPTOR(__sanitizer_FILE *, funopen2, void *cookie, funopen2_readfn readfn, 9319*ee754c2dSkamil funopen2_writefn writefn, funopen2_seekfn seekfn, 9320*ee754c2dSkamil funopen2_flushfn flushfn, funopen2_closefn closefn) { 9321*ee754c2dSkamil void *ctx; 9322*ee754c2dSkamil COMMON_INTERCEPTOR_ENTER(ctx, funopen2, cookie, readfn, writefn, seekfn, 9323*ee754c2dSkamil flushfn, closefn); 9324*ee754c2dSkamil 9325*ee754c2dSkamil WrappedFunopen2Cookie *wrapped_cookie = 9326*ee754c2dSkamil (WrappedFunopen2Cookie *)InternalAlloc(sizeof(WrappedFunopen2Cookie)); 9327*ee754c2dSkamil wrapped_cookie->real_cookie = cookie; 9328*ee754c2dSkamil wrapped_cookie->real_read = readfn; 9329*ee754c2dSkamil wrapped_cookie->real_write = writefn; 9330*ee754c2dSkamil wrapped_cookie->real_seek = seekfn; 9331*ee754c2dSkamil wrapped_cookie->real_flush = flushfn; 9332*ee754c2dSkamil wrapped_cookie->real_close = closefn; 9333*ee754c2dSkamil 9334*ee754c2dSkamil __sanitizer_FILE *res = 9335*ee754c2dSkamil REAL(funopen2)(wrapped_cookie, 9336*ee754c2dSkamil readfn ? wrapped_funopen2_read : nullptr, 9337*ee754c2dSkamil writefn ? wrapped_funopen2_write : nullptr, 9338*ee754c2dSkamil seekfn ? wrapped_funopen2_seek : nullptr, 9339*ee754c2dSkamil flushfn ? wrapped_funopen2_flush : nullptr, 9340*ee754c2dSkamil closefn ? wrapped_funopen2_close : nullptr); 9341*ee754c2dSkamil if (res) 9342*ee754c2dSkamil unpoison_file(res); 9343*ee754c2dSkamil return res; 9344*ee754c2dSkamil} 9345*ee754c2dSkamil#define INIT_FUNOPEN2 COMMON_INTERCEPT_FUNCTION(funopen2) 9346*ee754c2dSkamil#else 9347*ee754c2dSkamil#define INIT_FUNOPEN2 9348*ee754c2dSkamil#endif 9349*ee754c2dSkamil 9350*ee754c2dSkamilstatic void InitializeCommonInterceptors() { 9351*ee754c2dSkamil static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1]; 9352*ee754c2dSkamil interceptor_metadata_map = 9353*ee754c2dSkamil new ((void *)&metadata_mem) MetadataHashMap(); // NOLINT 9354*ee754c2dSkamil 9355*ee754c2dSkamil INIT_MMAP; 9356*ee754c2dSkamil INIT_MMAP64; 9357*ee754c2dSkamil INIT_TEXTDOMAIN; 9358*ee754c2dSkamil INIT_STRLEN; 9359*ee754c2dSkamil INIT_STRNLEN; 9360*ee754c2dSkamil INIT_STRNDUP; 9361*ee754c2dSkamil INIT___STRNDUP; 9362*ee754c2dSkamil INIT_STRCMP; 9363*ee754c2dSkamil INIT_STRNCMP; 9364*ee754c2dSkamil INIT_STRCASECMP; 9365*ee754c2dSkamil INIT_STRNCASECMP; 9366*ee754c2dSkamil INIT_STRSTR; 9367*ee754c2dSkamil INIT_STRCASESTR; 9368*ee754c2dSkamil INIT_STRCHR; 9369*ee754c2dSkamil INIT_STRCHRNUL; 9370*ee754c2dSkamil INIT_STRRCHR; 9371*ee754c2dSkamil INIT_STRSPN; 9372*ee754c2dSkamil INIT_STRTOK; 9373*ee754c2dSkamil INIT_STRPBRK; 9374*ee754c2dSkamil INIT_STRXFRM; 9375*ee754c2dSkamil INIT___STRXFRM_L; 9376*ee754c2dSkamil INIT_MEMSET; 9377*ee754c2dSkamil INIT_MEMMOVE; 9378*ee754c2dSkamil INIT_MEMCPY; 9379*ee754c2dSkamil INIT_MEMCHR; 9380*ee754c2dSkamil INIT_MEMCMP; 9381*ee754c2dSkamil INIT_MEMRCHR; 9382*ee754c2dSkamil INIT_MEMMEM; 9383*ee754c2dSkamil INIT_READ; 9384*ee754c2dSkamil INIT_FREAD; 9385*ee754c2dSkamil INIT_PREAD; 9386*ee754c2dSkamil INIT_PREAD64; 9387*ee754c2dSkamil INIT_READV; 9388*ee754c2dSkamil INIT_PREADV; 9389*ee754c2dSkamil INIT_PREADV64; 9390*ee754c2dSkamil INIT_WRITE; 9391*ee754c2dSkamil INIT_FWRITE; 9392*ee754c2dSkamil INIT_PWRITE; 9393*ee754c2dSkamil INIT_PWRITE64; 9394*ee754c2dSkamil INIT_WRITEV; 9395*ee754c2dSkamil INIT_PWRITEV; 9396*ee754c2dSkamil INIT_PWRITEV64; 9397*ee754c2dSkamil INIT_FGETS; 9398*ee754c2dSkamil INIT_FPUTS; 9399*ee754c2dSkamil INIT_PUTS; 9400*ee754c2dSkamil INIT_PRCTL; 9401*ee754c2dSkamil INIT_LOCALTIME_AND_FRIENDS; 9402*ee754c2dSkamil INIT_STRPTIME; 9403*ee754c2dSkamil INIT_SCANF; 9404*ee754c2dSkamil INIT_ISOC99_SCANF; 9405*ee754c2dSkamil INIT_PRINTF; 9406*ee754c2dSkamil INIT_PRINTF_L; 9407*ee754c2dSkamil INIT_ISOC99_PRINTF; 9408*ee754c2dSkamil INIT_FREXP; 9409*ee754c2dSkamil INIT_FREXPF_FREXPL; 9410*ee754c2dSkamil INIT_GETPWNAM_AND_FRIENDS; 9411*ee754c2dSkamil INIT_GETPWNAM_R_AND_FRIENDS; 9412*ee754c2dSkamil INIT_GETPWENT; 9413*ee754c2dSkamil INIT_FGETPWENT; 9414*ee754c2dSkamil INIT_GETPWENT_R; 9415*ee754c2dSkamil INIT_FGETPWENT_R; 9416*ee754c2dSkamil INIT_FGETGRENT_R; 9417*ee754c2dSkamil INIT_SETPWENT; 9418*ee754c2dSkamil INIT_CLOCK_GETTIME; 9419*ee754c2dSkamil INIT_GETITIMER; 9420*ee754c2dSkamil INIT_TIME; 9421*ee754c2dSkamil INIT_GLOB; 9422*ee754c2dSkamil INIT_GLOB64; 9423*ee754c2dSkamil INIT_WAIT; 9424*ee754c2dSkamil INIT_WAIT4; 9425*ee754c2dSkamil INIT_INET; 9426*ee754c2dSkamil INIT_PTHREAD_GETSCHEDPARAM; 9427*ee754c2dSkamil INIT_GETADDRINFO; 9428*ee754c2dSkamil INIT_GETNAMEINFO; 9429*ee754c2dSkamil INIT_GETSOCKNAME; 9430*ee754c2dSkamil INIT_GETHOSTBYNAME; 9431*ee754c2dSkamil INIT_GETHOSTBYNAME2; 9432*ee754c2dSkamil INIT_GETHOSTBYNAME_R; 9433*ee754c2dSkamil INIT_GETHOSTBYNAME2_R; 9434*ee754c2dSkamil INIT_GETHOSTBYADDR_R; 9435*ee754c2dSkamil INIT_GETHOSTENT_R; 9436*ee754c2dSkamil INIT_GETSOCKOPT; 9437*ee754c2dSkamil INIT_ACCEPT; 9438*ee754c2dSkamil INIT_ACCEPT4; 9439*ee754c2dSkamil INIT_PACCEPT; 9440*ee754c2dSkamil INIT_MODF; 9441*ee754c2dSkamil INIT_RECVMSG; 9442*ee754c2dSkamil INIT_SENDMSG; 9443*ee754c2dSkamil INIT_RECVMMSG; 9444*ee754c2dSkamil INIT_SENDMMSG; 9445*ee754c2dSkamil INIT_GETPEERNAME; 9446*ee754c2dSkamil INIT_IOCTL; 9447*ee754c2dSkamil INIT_INET_ATON; 9448*ee754c2dSkamil INIT_SYSINFO; 9449*ee754c2dSkamil INIT_READDIR; 9450*ee754c2dSkamil INIT_READDIR64; 9451*ee754c2dSkamil INIT_PTRACE; 9452*ee754c2dSkamil INIT_SETLOCALE; 9453*ee754c2dSkamil INIT_GETCWD; 9454*ee754c2dSkamil INIT_GET_CURRENT_DIR_NAME; 9455*ee754c2dSkamil INIT_STRTOIMAX; 9456*ee754c2dSkamil INIT_MBSTOWCS; 9457*ee754c2dSkamil INIT_MBSNRTOWCS; 9458*ee754c2dSkamil INIT_WCSTOMBS; 9459*ee754c2dSkamil INIT_WCSNRTOMBS; 9460*ee754c2dSkamil INIT_WCRTOMB; 9461*ee754c2dSkamil INIT_TCGETATTR; 9462*ee754c2dSkamil INIT_REALPATH; 9463*ee754c2dSkamil INIT_CANONICALIZE_FILE_NAME; 9464*ee754c2dSkamil INIT_CONFSTR; 9465*ee754c2dSkamil INIT_SCHED_GETAFFINITY; 9466*ee754c2dSkamil INIT_SCHED_GETPARAM; 9467*ee754c2dSkamil INIT_STRERROR; 9468*ee754c2dSkamil INIT_STRERROR_R; 9469*ee754c2dSkamil INIT_XPG_STRERROR_R; 9470*ee754c2dSkamil INIT_SCANDIR; 9471*ee754c2dSkamil INIT_SCANDIR64; 9472*ee754c2dSkamil INIT_GETGROUPS; 9473*ee754c2dSkamil INIT_POLL; 9474*ee754c2dSkamil INIT_PPOLL; 9475*ee754c2dSkamil INIT_WORDEXP; 9476*ee754c2dSkamil INIT_SIGWAIT; 9477*ee754c2dSkamil INIT_SIGWAITINFO; 9478*ee754c2dSkamil INIT_SIGTIMEDWAIT; 9479*ee754c2dSkamil INIT_SIGSETOPS; 9480*ee754c2dSkamil INIT_SIGPENDING; 9481*ee754c2dSkamil INIT_SIGPROCMASK; 9482*ee754c2dSkamil INIT_BACKTRACE; 9483*ee754c2dSkamil INIT__EXIT; 9484*ee754c2dSkamil INIT_PTHREAD_MUTEX_LOCK; 9485*ee754c2dSkamil INIT_PTHREAD_MUTEX_UNLOCK; 9486*ee754c2dSkamil INIT___PTHREAD_MUTEX_LOCK; 9487*ee754c2dSkamil INIT___PTHREAD_MUTEX_UNLOCK; 9488*ee754c2dSkamil INIT___LIBC_MUTEX_LOCK; 9489*ee754c2dSkamil INIT___LIBC_MUTEX_UNLOCK; 9490*ee754c2dSkamil INIT___LIBC_THR_SETCANCELSTATE; 9491*ee754c2dSkamil INIT_GETMNTENT; 9492*ee754c2dSkamil INIT_GETMNTENT_R; 9493*ee754c2dSkamil INIT_STATFS; 9494*ee754c2dSkamil INIT_STATFS64; 9495*ee754c2dSkamil INIT_STATVFS; 9496*ee754c2dSkamil INIT_STATVFS64; 9497*ee754c2dSkamil INIT_INITGROUPS; 9498*ee754c2dSkamil INIT_ETHER_NTOA_ATON; 9499*ee754c2dSkamil INIT_ETHER_HOST; 9500*ee754c2dSkamil INIT_ETHER_R; 9501*ee754c2dSkamil INIT_SHMCTL; 9502*ee754c2dSkamil INIT_RANDOM_R; 9503*ee754c2dSkamil INIT_PTHREAD_ATTR_GET; 9504*ee754c2dSkamil INIT_PTHREAD_ATTR_GET_SCHED; 9505*ee754c2dSkamil INIT_PTHREAD_ATTR_GETINHERITSCHED; 9506*ee754c2dSkamil INIT_PTHREAD_ATTR_GETAFFINITY_NP; 9507*ee754c2dSkamil INIT_PTHREAD_MUTEXATTR_GETPSHARED; 9508*ee754c2dSkamil INIT_PTHREAD_MUTEXATTR_GETTYPE; 9509*ee754c2dSkamil INIT_PTHREAD_MUTEXATTR_GETPROTOCOL; 9510*ee754c2dSkamil INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING; 9511*ee754c2dSkamil INIT_PTHREAD_MUTEXATTR_GETROBUST; 9512*ee754c2dSkamil INIT_PTHREAD_MUTEXATTR_GETROBUST_NP; 9513*ee754c2dSkamil INIT_PTHREAD_RWLOCKATTR_GETPSHARED; 9514*ee754c2dSkamil INIT_PTHREAD_RWLOCKATTR_GETKIND_NP; 9515*ee754c2dSkamil INIT_PTHREAD_CONDATTR_GETPSHARED; 9516*ee754c2dSkamil INIT_PTHREAD_CONDATTR_GETCLOCK; 9517*ee754c2dSkamil INIT_PTHREAD_BARRIERATTR_GETPSHARED; 9518*ee754c2dSkamil INIT_TMPNAM; 9519*ee754c2dSkamil INIT_TMPNAM_R; 9520*ee754c2dSkamil INIT_TTYNAME_R; 9521*ee754c2dSkamil INIT_TEMPNAM; 9522*ee754c2dSkamil INIT_PTHREAD_SETNAME_NP; 9523*ee754c2dSkamil INIT_PTHREAD_GETNAME_NP; 9524*ee754c2dSkamil INIT_SINCOS; 9525*ee754c2dSkamil INIT_REMQUO; 9526*ee754c2dSkamil INIT_REMQUOL; 9527*ee754c2dSkamil INIT_LGAMMA; 9528*ee754c2dSkamil INIT_LGAMMAL; 9529*ee754c2dSkamil INIT_LGAMMA_R; 9530*ee754c2dSkamil INIT_LGAMMAL_R; 9531*ee754c2dSkamil INIT_DRAND48_R; 9532*ee754c2dSkamil INIT_RAND_R; 9533*ee754c2dSkamil INIT_GETLINE; 9534*ee754c2dSkamil INIT_ICONV; 9535*ee754c2dSkamil INIT_TIMES; 9536*ee754c2dSkamil INIT_TLS_GET_ADDR; 9537*ee754c2dSkamil INIT_LISTXATTR; 9538*ee754c2dSkamil INIT_GETXATTR; 9539*ee754c2dSkamil INIT_GETRESID; 9540*ee754c2dSkamil INIT_GETIFADDRS; 9541*ee754c2dSkamil INIT_IF_INDEXTONAME; 9542*ee754c2dSkamil INIT_CAPGET; 9543*ee754c2dSkamil INIT_AEABI_MEM; 9544*ee754c2dSkamil INIT___BZERO; 9545*ee754c2dSkamil INIT_FTIME; 9546*ee754c2dSkamil INIT_XDR; 9547*ee754c2dSkamil INIT_TSEARCH; 9548*ee754c2dSkamil INIT_LIBIO_INTERNALS; 9549*ee754c2dSkamil INIT_FOPEN; 9550*ee754c2dSkamil INIT_FOPEN64; 9551*ee754c2dSkamil INIT_OPEN_MEMSTREAM; 9552*ee754c2dSkamil INIT_OBSTACK; 9553*ee754c2dSkamil INIT_FFLUSH; 9554*ee754c2dSkamil INIT_FCLOSE; 9555*ee754c2dSkamil INIT_DLOPEN_DLCLOSE; 9556*ee754c2dSkamil INIT_GETPASS; 9557*ee754c2dSkamil INIT_TIMERFD; 9558*ee754c2dSkamil INIT_MLOCKX; 9559*ee754c2dSkamil INIT_FOPENCOOKIE; 9560*ee754c2dSkamil INIT_SEM; 9561*ee754c2dSkamil INIT_PTHREAD_SETCANCEL; 9562*ee754c2dSkamil INIT_MINCORE; 9563*ee754c2dSkamil INIT_PROCESS_VM_READV; 9564*ee754c2dSkamil INIT_CTERMID; 9565*ee754c2dSkamil INIT_CTERMID_R; 9566*ee754c2dSkamil INIT_RECV_RECVFROM; 9567*ee754c2dSkamil INIT_SEND_SENDTO; 9568*ee754c2dSkamil INIT_STAT; 9569*ee754c2dSkamil INIT_EVENTFD_READ_WRITE; 9570*ee754c2dSkamil INIT_LSTAT; 9571*ee754c2dSkamil INIT___XSTAT; 9572*ee754c2dSkamil INIT___XSTAT64; 9573*ee754c2dSkamil INIT___LXSTAT; 9574*ee754c2dSkamil INIT___LXSTAT64; 9575*ee754c2dSkamil // FIXME: add other *stat interceptors. 9576*ee754c2dSkamil INIT_UTMP; 9577*ee754c2dSkamil INIT_UTMPX; 9578*ee754c2dSkamil INIT_GETLOADAVG; 9579*ee754c2dSkamil INIT_WCSLEN; 9580*ee754c2dSkamil INIT_WCSCAT; 9581*ee754c2dSkamil INIT_WCSXFRM; 9582*ee754c2dSkamil INIT___WCSXFRM_L; 9583*ee754c2dSkamil INIT_ACCT; 9584*ee754c2dSkamil INIT_USER_FROM_UID; 9585*ee754c2dSkamil INIT_UID_FROM_USER; 9586*ee754c2dSkamil INIT_GROUP_FROM_GID; 9587*ee754c2dSkamil INIT_GID_FROM_GROUP; 9588*ee754c2dSkamil INIT_ACCESS; 9589*ee754c2dSkamil INIT_FACCESSAT; 9590*ee754c2dSkamil INIT_GETGROUPLIST; 9591*ee754c2dSkamil INIT_GETGROUPMEMBERSHIP; 9592*ee754c2dSkamil INIT_READLINK; 9593*ee754c2dSkamil INIT_READLINKAT; 9594*ee754c2dSkamil INIT_NAME_TO_HANDLE_AT; 9595*ee754c2dSkamil INIT_OPEN_BY_HANDLE_AT; 9596*ee754c2dSkamil INIT_STRLCPY; 9597*ee754c2dSkamil INIT_DEVNAME; 9598*ee754c2dSkamil INIT_DEVNAME_R; 9599*ee754c2dSkamil INIT_FGETLN; 9600*ee754c2dSkamil INIT_STRMODE; 9601*ee754c2dSkamil INIT_TTYENT; 9602*ee754c2dSkamil INIT_PROTOENT; 9603*ee754c2dSkamil INIT_NETENT; 9604*ee754c2dSkamil INIT_GETMNTINFO; 9605*ee754c2dSkamil INIT_MI_VECTOR_HASH; 9606*ee754c2dSkamil INIT_SETVBUF; 9607*ee754c2dSkamil INIT_GETVFSSTAT; 9608*ee754c2dSkamil INIT_REGEX; 9609*ee754c2dSkamil INIT_REGEXSUB; 9610*ee754c2dSkamil INIT_FTS; 9611*ee754c2dSkamil INIT_SYSCTL; 9612*ee754c2dSkamil INIT_ASYSCTL; 9613*ee754c2dSkamil INIT_SYSCTLGETMIBINFO; 9614*ee754c2dSkamil INIT_NL_LANGINFO; 9615*ee754c2dSkamil INIT_MODCTL; 9616*ee754c2dSkamil INIT_STRTONUM; 9617*ee754c2dSkamil INIT_FPARSELN; 9618*ee754c2dSkamil INIT_STATVFS1; 9619*ee754c2dSkamil INIT_STRTOI; 9620*ee754c2dSkamil INIT_CAPSICUM; 9621*ee754c2dSkamil INIT_SHA1; 9622*ee754c2dSkamil INIT_MD4; 9623*ee754c2dSkamil INIT_RMD160; 9624*ee754c2dSkamil INIT_MD5; 9625*ee754c2dSkamil INIT_FSEEK; 9626*ee754c2dSkamil INIT_MD2; 9627*ee754c2dSkamil INIT_SHA2; 9628*ee754c2dSkamil INIT_VIS; 9629*ee754c2dSkamil INIT_CDB; 9630*ee754c2dSkamil INIT_GETFSENT; 9631*ee754c2dSkamil INIT_ARC4RANDOM; 9632*ee754c2dSkamil INIT_POPEN; 9633*ee754c2dSkamil INIT_POPENVE; 9634*ee754c2dSkamil INIT_PCLOSE; 9635*ee754c2dSkamil INIT_FUNOPEN; 9636*ee754c2dSkamil INIT_FUNOPEN2; 9637*ee754c2dSkamil 9638*ee754c2dSkamil INIT___PRINTF_CHK; 9639*ee754c2dSkamil} 9640