10720 lines · plain
1//===-- sanitizer_common_interceptors.inc -----------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// Common function interceptors for tools like AddressSanitizer,10// ThreadSanitizer, MemorySanitizer, etc.11//12// This file should be included into the tool's interceptor file,13// which has to define its own macros:14// COMMON_INTERCEPTOR_ENTER15// COMMON_INTERCEPTOR_ENTER_NOIGNORE16// COMMON_INTERCEPTOR_READ_RANGE17// COMMON_INTERCEPTOR_WRITE_RANGE18// COMMON_INTERCEPTOR_INITIALIZE_RANGE19// COMMON_INTERCEPTOR_DIR_ACQUIRE20// COMMON_INTERCEPTOR_FD_ACQUIRE21// COMMON_INTERCEPTOR_FD_RELEASE22// COMMON_INTERCEPTOR_FD_ACCESS23// COMMON_INTERCEPTOR_SET_THREAD_NAME24// COMMON_INTERCEPTOR_DLOPEN25// COMMON_INTERCEPTOR_ON_EXIT26// COMMON_INTERCEPTOR_SET_PTHREAD_NAME27// COMMON_INTERCEPTOR_HANDLE_RECVMSG28// COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED29// COMMON_INTERCEPTOR_MMAP_IMPL30// COMMON_INTERCEPTOR_MUNMAP_IMPL31// COMMON_INTERCEPTOR_COPY_STRING32// COMMON_INTERCEPTOR_STRNDUP_IMPL33// COMMON_INTERCEPTOR_STRERROR34//===----------------------------------------------------------------------===//35 36#include <stdarg.h>37 38#include "interception/interception.h"39#include "sanitizer_addrhashmap.h"40#include "sanitizer_dl.h"41#include "sanitizer_errno.h"42#include "sanitizer_placement_new.h"43#include "sanitizer_platform_interceptors.h"44#include "sanitizer_platform_limits_posix.h"45#include "sanitizer_symbolizer.h"46#include "sanitizer_tls_get_addr.h"47 48#if SANITIZER_INTERCEPTOR_HOOKS49#define CALL_WEAK_INTERCEPTOR_HOOK(f, ...) f(__VA_ARGS__);50#define DECLARE_WEAK_INTERCEPTOR_HOOK(f, ...) \51 SANITIZER_INTERFACE_WEAK_DEF(void, f, __VA_ARGS__) {}52#else53#define DECLARE_WEAK_INTERCEPTOR_HOOK(f, ...)54#define CALL_WEAK_INTERCEPTOR_HOOK(f, ...)55 56#endif // SANITIZER_INTERCEPTOR_HOOKS57 58#if SANITIZER_WINDOWS && !defined(va_copy)59#define va_copy(dst, src) ((dst) = (src))60#endif // _WIN3261 62#if SANITIZER_FREEBSD63#define pthread_setname_np pthread_set_name_np64#define inet_aton __inet_aton65#define inet_pton __inet_pton66#define iconv __bsd_iconv67#endif68 69#if SANITIZER_NETBSD70#define clock_getres __clock_getres5071#define clock_gettime __clock_gettime5072#define clock_settime __clock_settime5073#define ctime __ctime5074#define ctime_r __ctime_r5075#define devname __devname5076#define fgetpos __fgetpos5077#define fsetpos __fsetpos5078#define fstatvfs __fstatvfs9079#define fstatvfs1 __fstatvfs19080#define fts_children __fts_children6081#define fts_close __fts_close6082#define fts_open __fts_open6083#define fts_read __fts_read6084#define fts_set __fts_set6085#define getitimer __getitimer5086#define getmntinfo __getmntinfo9087#define getpwent __getpwent5088#define getpwnam __getpwnam5089#define getpwnam_r __getpwnam_r5090#define getpwuid __getpwuid5091#define getpwuid_r __getpwuid_r5092#define getutent __getutent5093#define getutxent __getutxent5094#define getutxid __getutxid5095#define getutxline __getutxline5096#define getvfsstat __getvfsstat9097#define pututxline __pututxline5098#define glob __glob3099#define gmtime __gmtime50100#define gmtime_r __gmtime_r50101#define localtime __locatime50102#define localtime_r __localtime_r50103#define mktime __mktime50104#define lstat __lstat50105#define opendir __opendir30106#define readdir __readdir30107#define readdir_r __readdir_r30108#define scandir __scandir30109#define setitimer __setitimer50110#define setlocale __setlocale50111#define shmctl __shmctl50112#define sigaltstack __sigaltstack14113#define sigemptyset __sigemptyset14114#define sigfillset __sigfillset14115#define sigpending __sigpending14116#define sigprocmask __sigprocmask14117#define sigtimedwait __sigtimedwait50118#define stat __stat50119#define statvfs __statvfs90120#define statvfs1 __statvfs190121#define time __time50122#define times __times13123#define unvis __unvis50124#define wait3 __wait350125#define wait4 __wait450126extern const unsigned short *_ctype_tab_;127extern const short *_toupper_tab_;128extern const short *_tolower_tab_;129#endif130 131#if SANITIZER_LINUX && SANITIZER_SPARC32132// On 32-bit Linux/sparc64, double and long double are identical and glibc133// uses a __nldbl_ (no long double) prefix for various stdio functions.134# define __isoc23_fscanf __nldbl___isoc23_fscanf135# define __isoc23_scanf __nldbl___isoc23_scanf136# define __isoc23_sscanf __nldbl___isoc23_sscanf137# define __isoc23_vfscanf __nldbl___isoc23_vfscanf138# define __isoc23_vscanf __nldbl___isoc23_vscanf139# define __isoc23_vsscanf __nldbl___isoc23_vsscanf140# define __isoc99_fscanf __nldbl___isoc99_fscanf141# define __isoc99_scanf __nldbl___isoc99_scanf142# define __isoc99_sscanf __nldbl___isoc99_sscanf143# define __isoc99_vfscanf __nldbl___isoc99_vfscanf144# define __isoc99_vscanf __nldbl___isoc99_vscanf145# define __isoc99_vsscanf __nldbl___isoc99_vsscanf146# define asprintf __nldbl_asprintf147# define fprintf __nldbl_fprintf148# define fscanf __nldbl_fscanf149# define printf __nldbl_printf150# define scanf __nldbl_scanf151# define snprintf __nldbl_snprintf152# define sprintf __nldbl_sprintf153# define sscanf __nldbl_sscanf154# define vasprintf __nldbl_vasprintf155# define vfprintf __nldbl_vfprintf156# define vfscanf __nldbl_vfscanf157# define vprintf __nldbl_vprintf158# define vscanf __nldbl_vscanf159# define vsnprintf __nldbl_vsnprintf160# define vsprintf __nldbl_vsprintf161# define vsscanf __nldbl_vsscanf162#endif163 164#if SANITIZER_MUSL && \165 (defined(__i386__) || defined(__arm__) || SANITIZER_MIPS32 || SANITIZER_PPC32)166// musl 1.2.0 on existing 32-bit architectures uses new symbol names for the167// time-related functions that take 64-bit time_t values. See168// https://musl.libc.org/time64.html169#define adjtime __adjtime64170#define adjtimex __adjtimex_time64171#define aio_suspend __aio_suspend_time64172#define clock_adjtime __clock_adjtime64173#define clock_getres __clock_getres_time64174#define clock_gettime __clock_gettime64175#define clock_nanosleep __clock_nanosleep_time64176#define clock_settime __clock_settime64177#define cnd_timedwait __cnd_timedwait_time64178#define ctime __ctime64179#define ctime_r __ctime64_r180#define difftime __difftime64181#define dlsym __dlsym_time64182#define fstatat __fstatat_time64183#define fstat __fstat_time64184#define ftime __ftime64185#define futimens __futimens_time64186#define futimesat __futimesat_time64187#define futimes __futimes_time64188#define getitimer __getitimer_time64189#define getrusage __getrusage_time64190#define gettimeofday __gettimeofday_time64191#define gmtime __gmtime64192#define gmtime_r __gmtime64_r193#define localtime __localtime64194#define localtime_r __localtime64_r195#define lstat __lstat_time64196#define lutimes __lutimes_time64197#define mktime __mktime64198#define mq_timedreceive __mq_timedreceive_time64199#define mq_timedsend __mq_timedsend_time64200#define mtx_timedlock __mtx_timedlock_time64201#define nanosleep __nanosleep_time64202#define ppoll __ppoll_time64203#define pselect __pselect_time64204#define pthread_cond_timedwait __pthread_cond_timedwait_time64205#define pthread_mutex_timedlock __pthread_mutex_timedlock_time64206#define pthread_rwlock_timedrdlock __pthread_rwlock_timedrdlock_time64207#define pthread_rwlock_timedwrlock __pthread_rwlock_timedwrlock_time64208#define pthread_timedjoin_np __pthread_timedjoin_np_time64209#define recvmmsg __recvmmsg_time64210#define sched_rr_get_interval __sched_rr_get_interval_time64211#define select __select_time64212#define semtimedop __semtimedop_time64213#define sem_timedwait __sem_timedwait_time64214#define setitimer __setitimer_time64215#define settimeofday __settimeofday_time64216#define sigtimedwait __sigtimedwait_time64217#define stat __stat_time64218#define stime __stime64219#define thrd_sleep __thrd_sleep_time64220#define timegm __timegm_time64221#define timerfd_gettime __timerfd_gettime64222#define timerfd_settime __timerfd_settime64223#define timer_gettime __timer_gettime64224#define timer_settime __timer_settime64225#define timespec_get __timespec_get_time64226#define time __time64227#define utimensat __utimensat_time64228#define utimes __utimes_time64229#define utime __utime64230#define wait3 __wait3_time64231#define wait4 __wait4_time64232#endif233 234#ifndef COMMON_INTERCEPTOR_INITIALIZE_RANGE235#define COMMON_INTERCEPTOR_INITIALIZE_RANGE(p, size) {}236#endif237 238#ifndef COMMON_INTERCEPTOR_UNPOISON_PARAM239#define COMMON_INTERCEPTOR_UNPOISON_PARAM(count) {}240#endif241 242#ifndef COMMON_INTERCEPTOR_FD_ACCESS243#define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd) {}244#endif245 246#ifndef COMMON_INTERCEPTOR_HANDLE_RECVMSG247#define COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg) ((void)(msg))248#endif249 250#ifndef COMMON_INTERCEPTOR_FILE_OPEN251#define COMMON_INTERCEPTOR_FILE_OPEN(ctx, file, path) {}252#endif253 254#ifndef COMMON_INTERCEPTOR_FILE_CLOSE255#define COMMON_INTERCEPTOR_FILE_CLOSE(ctx, file) {}256#endif257 258#ifndef COMMON_INTERCEPTOR_LIBRARY_LOADED259#define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle) {}260#endif261 262#ifndef COMMON_INTERCEPTOR_LIBRARY_UNLOADED263#define COMMON_INTERCEPTOR_LIBRARY_UNLOADED() {}264#endif265 266#ifndef COMMON_INTERCEPTOR_ENTER_NOIGNORE267#define COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, ...) \268 COMMON_INTERCEPTOR_ENTER(ctx, __VA_ARGS__)269#endif270 271#ifndef COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED272#define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (0)273#endif274 275#define COMMON_INTERCEPTOR_READ_STRING(ctx, s, n) \276 COMMON_INTERCEPTOR_READ_RANGE((ctx), (s), \277 common_flags()->strict_string_checks ? (internal_strlen(s)) + 1 : (n) )278 279#ifndef COMMON_INTERCEPTOR_DLOPEN280#define COMMON_INTERCEPTOR_DLOPEN(filename, flag) \281 ({ CheckNoDeepBind(filename, flag); REAL(dlopen)(filename, flag); })282#endif283 284#ifndef COMMON_INTERCEPTOR_GET_TLS_RANGE285#define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end) *begin = *end = 0;286#endif287 288#ifndef COMMON_INTERCEPTOR_ACQUIRE289#define COMMON_INTERCEPTOR_ACQUIRE(ctx, u) {}290#endif291 292#ifndef COMMON_INTERCEPTOR_RELEASE293#define COMMON_INTERCEPTOR_RELEASE(ctx, u) {}294#endif295 296#ifndef COMMON_INTERCEPTOR_USER_CALLBACK_START297#define COMMON_INTERCEPTOR_USER_CALLBACK_START() {}298#endif299 300#ifndef COMMON_INTERCEPTOR_USER_CALLBACK_END301#define COMMON_INTERCEPTOR_USER_CALLBACK_END() {}302#endif303 304#ifdef SANITIZER_NLDBL_VERSION305#define COMMON_INTERCEPT_FUNCTION_LDBL(fn) \306 COMMON_INTERCEPT_FUNCTION_VER(fn, SANITIZER_NLDBL_VERSION)307#else308#define COMMON_INTERCEPT_FUNCTION_LDBL(fn) \309 COMMON_INTERCEPT_FUNCTION(fn)310#endif311 312#if SANITIZER_GLIBC313// If we could not find the versioned symbol, fall back to an unversioned314// lookup. This is needed to work around a GLibc bug that causes dlsym315// with RTLD_NEXT to return the oldest versioned symbol.316// See https://sourceware.org/bugzilla/show_bug.cgi?id=14932.317// For certain symbols (e.g. regexec) we have to perform a versioned lookup,318// but that versioned symbol will only exist for architectures where the319// oldest Glibc version pre-dates support for that architecture.320// For example, regexec@GLIBC_2.3.4 exists on x86_64, but not RISC-V.321// See also https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98920.322#define COMMON_INTERCEPT_FUNCTION_GLIBC_VER_MIN(fn, ver) \323 COMMON_INTERCEPT_FUNCTION_VER_UNVERSIONED_FALLBACK(fn, ver)324#else325#define COMMON_INTERCEPT_FUNCTION_GLIBC_VER_MIN(fn, ver) \326 COMMON_INTERCEPT_FUNCTION(fn)327#endif328 329#ifndef COMMON_INTERCEPTOR_MMAP_IMPL330#define COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, sz, prot, flags, fd, \331 off) \332 { return REAL(mmap)(addr, sz, prot, flags, fd, off); }333#endif334 335#ifndef COMMON_INTERCEPTOR_MUNMAP_IMPL336#define COMMON_INTERCEPTOR_MUNMAP_IMPL(ctx, addr, sz) \337 { return REAL(munmap)(addr, sz); }338#endif339 340#ifndef COMMON_INTERCEPTOR_COPY_STRING341#define COMMON_INTERCEPTOR_COPY_STRING(ctx, to, from, size) {}342#endif343 344#ifndef COMMON_INTERCEPTOR_STRNDUP_IMPL345#define COMMON_INTERCEPTOR_STRNDUP_IMPL(ctx, s, size) \346 COMMON_INTERCEPTOR_ENTER(ctx, strndup, s, size); \347 uptr copy_length = internal_strnlen(s, size); \348 char *new_mem = (char *)WRAP(malloc)(copy_length + 1); \349 if (common_flags()->intercept_strndup) { \350 COMMON_INTERCEPTOR_READ_STRING(ctx, s, Min<uptr>(size, copy_length + 1)); \351 } \352 if (new_mem) { \353 COMMON_INTERCEPTOR_COPY_STRING(ctx, new_mem, s, copy_length); \354 internal_memcpy(new_mem, s, copy_length); \355 new_mem[copy_length] = '\0'; \356 } \357 return new_mem;358#endif359 360#ifndef COMMON_INTERCEPTOR_STRERROR361#define COMMON_INTERCEPTOR_STRERROR() {}362#endif363 364struct FileMetadata {365 // For open_memstream().366 char **addr;367 SIZE_T *size;368};369 370struct CommonInterceptorMetadata {371 enum {372 CIMT_INVALID = 0,373 CIMT_FILE374 } type;375 union {376 FileMetadata file;377 };378};379 380#if SI_POSIX381typedef AddrHashMap<CommonInterceptorMetadata, 31051> MetadataHashMap;382 383static MetadataHashMap *interceptor_metadata_map;384 385UNUSED static void SetInterceptorMetadata(__sanitizer_FILE *addr,386 const FileMetadata &file) {387 MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr);388 CHECK(h.created());389 h->type = CommonInterceptorMetadata::CIMT_FILE;390 h->file = file;391}392 393UNUSED static const FileMetadata *GetInterceptorMetadata(394 __sanitizer_FILE *addr) {395 MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr,396 /* remove */ false,397 /* create */ false);398 if (addr && h.exists()) {399 CHECK(!h.created());400 CHECK(h->type == CommonInterceptorMetadata::CIMT_FILE);401 return &h->file;402 } else {403 return 0;404 }405}406 407UNUSED static void DeleteInterceptorMetadata(void *addr) {408 MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr, true);409 CHECK(h.exists());410}411#endif // SI_POSIX412 413#if SANITIZER_INTERCEPT_STRLEN414INTERCEPTOR(SIZE_T, strlen, const char *s) {415 // Sometimes strlen is called prior to InitializeCommonInterceptors,416 // in which case the REAL(strlen) typically used in417 // COMMON_INTERCEPTOR_ENTER will fail. We use internal_strlen here418 // to handle that.419 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)420 return internal_strlen(s);421 void *ctx;422 COMMON_INTERCEPTOR_ENTER(ctx, strlen, s);423 SIZE_T result = REAL(strlen)(s);424 if (common_flags()->intercept_strlen)425 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, result + 1);426 return result;427}428#define INIT_STRLEN COMMON_INTERCEPT_FUNCTION(strlen)429#else430#define INIT_STRLEN431#endif432 433#if SANITIZER_INTERCEPT_STRNLEN434INTERCEPTOR(SIZE_T, strnlen, const char *s, SIZE_T maxlen) {435 void *ctx;436 COMMON_INTERCEPTOR_ENTER(ctx, strnlen, s, maxlen);437 SIZE_T length = REAL(strnlen)(s, maxlen);438 if (common_flags()->intercept_strlen)439 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, Min(length + 1, maxlen));440 return length;441}442#define INIT_STRNLEN COMMON_INTERCEPT_FUNCTION(strnlen)443#else444#define INIT_STRNLEN445#endif446 447#if SANITIZER_INTERCEPT_STRNDUP448INTERCEPTOR(char*, strndup, const char *s, usize size) {449 void *ctx;450 COMMON_INTERCEPTOR_STRNDUP_IMPL(ctx, s, size);451}452#define INIT_STRNDUP COMMON_INTERCEPT_FUNCTION(strndup)453#else454#define INIT_STRNDUP455#endif // SANITIZER_INTERCEPT_STRNDUP456 457#if SANITIZER_INTERCEPT___STRNDUP458INTERCEPTOR(char*, __strndup, const char *s, usize size) {459 void *ctx;460 COMMON_INTERCEPTOR_STRNDUP_IMPL(ctx, s, size);461}462#define INIT___STRNDUP COMMON_INTERCEPT_FUNCTION(__strndup)463#else464#define INIT___STRNDUP465#endif // SANITIZER_INTERCEPT___STRNDUP466 467#if SANITIZER_INTERCEPT_TEXTDOMAIN468INTERCEPTOR(char*, textdomain, const char *domainname) {469 void *ctx;470 COMMON_INTERCEPTOR_ENTER(ctx, textdomain, domainname);471 if (domainname) COMMON_INTERCEPTOR_READ_STRING(ctx, domainname, 0);472 char *domain = REAL(textdomain)(domainname);473 if (domain) {474 COMMON_INTERCEPTOR_INITIALIZE_RANGE(domain, internal_strlen(domain) + 1);475 }476 return domain;477}478#define INIT_TEXTDOMAIN COMMON_INTERCEPT_FUNCTION(textdomain)479#else480#define INIT_TEXTDOMAIN481#endif482 483#if SANITIZER_INTERCEPT_STRCMP || SANITIZER_INTERCEPT_MEMCMP484[[maybe_unused]] static inline int CharCmpX(unsigned char c1,485 unsigned char c2) {486 return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1;487}488#endif489 490#if SANITIZER_INTERCEPT_STRCMP491DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcmp, uptr called_pc,492 const char *s1, const char *s2, int result)493 494INTERCEPTOR(int, strcmp, const char *s1, const char *s2) {495 void *ctx;496 COMMON_INTERCEPTOR_ENTER(ctx, strcmp, s1, s2);497 unsigned char c1, c2;498 uptr i;499 for (i = 0;; i++) {500 c1 = (unsigned char)s1[i];501 c2 = (unsigned char)s2[i];502 if (c1 != c2 || c1 == '\0') break;503 }504 if (common_flags()->intercept_strcmp) {505 COMMON_INTERCEPTOR_READ_STRING(ctx, s1, i + 1);506 COMMON_INTERCEPTOR_READ_STRING(ctx, s2, i + 1);507 }508 int result = CharCmpX(c1, c2);509 CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcmp, GET_CALLER_PC(), s1,510 s2, result);511 return result;512}513 514DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncmp, uptr called_pc,515 const char *s1, const char *s2, usize n,516 int result)517 518INTERCEPTOR(int, strncmp, const char *s1, const char *s2, usize size) {519 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)520 return internal_strncmp(s1, s2, size);521 void *ctx;522 COMMON_INTERCEPTOR_ENTER(ctx, strncmp, s1, s2, size);523 unsigned char c1 = 0, c2 = 0;524 usize i;525 for (i = 0; i < size; i++) {526 c1 = (unsigned char)s1[i];527 c2 = (unsigned char)s2[i];528 if (c1 != c2 || c1 == '\0') break;529 }530 usize i1 = i;531 usize i2 = i;532 if (common_flags()->strict_string_checks) {533 for (; i1 < size && s1[i1]; i1++) {}534 for (; i2 < size && s2[i2]; i2++) {}535 }536 COMMON_INTERCEPTOR_READ_RANGE((ctx), (s1), Min(i1 + 1, size));537 COMMON_INTERCEPTOR_READ_RANGE((ctx), (s2), Min(i2 + 1, size));538 int result = CharCmpX(c1, c2);539 CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncmp, GET_CALLER_PC(), s1,540 s2, size, result);541 return result;542}543 544#define INIT_STRCMP COMMON_INTERCEPT_FUNCTION(strcmp)545#define INIT_STRNCMP COMMON_INTERCEPT_FUNCTION(strncmp)546#else547#define INIT_STRCMP548#define INIT_STRNCMP549#endif550 551#if SANITIZER_INTERCEPT_STRCASECMP552static inline int CharCaseCmp(unsigned char c1, unsigned char c2) {553 int c1_low = ToLower(c1);554 int c2_low = ToLower(c2);555 return c1_low - c2_low;556}557 558DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasecmp, uptr called_pc,559 const char *s1, const char *s2, int result)560 561INTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) {562 void *ctx;563 COMMON_INTERCEPTOR_ENTER(ctx, strcasecmp, s1, s2);564 unsigned char c1 = 0, c2 = 0;565 uptr i;566 for (i = 0;; i++) {567 c1 = (unsigned char)s1[i];568 c2 = (unsigned char)s2[i];569 if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break;570 }571 COMMON_INTERCEPTOR_READ_STRING(ctx, s1, i + 1);572 COMMON_INTERCEPTOR_READ_STRING(ctx, s2, i + 1);573 int result = CharCaseCmp(c1, c2);574 CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasecmp, GET_CALLER_PC(),575 s1, s2, result);576 return result;577}578 579DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncasecmp, uptr called_pc,580 const char *s1, const char *s2, usize size,581 int result)582 583INTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, SIZE_T size) {584 void *ctx;585 COMMON_INTERCEPTOR_ENTER(ctx, strncasecmp, s1, s2, size);586 unsigned char c1 = 0, c2 = 0;587 usize i;588 for (i = 0; i < size; i++) {589 c1 = (unsigned char)s1[i];590 c2 = (unsigned char)s2[i];591 if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break;592 }593 usize i1 = i;594 usize i2 = i;595 if (common_flags()->strict_string_checks) {596 for (; i1 < size && s1[i1]; i1++) {}597 for (; i2 < size && s2[i2]; i2++) {}598 }599 COMMON_INTERCEPTOR_READ_RANGE((ctx), (s1), Min(i1 + 1, size));600 COMMON_INTERCEPTOR_READ_RANGE((ctx), (s2), Min(i2 + 1, size));601 int result = CharCaseCmp(c1, c2);602 CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncasecmp, GET_CALLER_PC(),603 s1, s2, size, result);604 return result;605}606 607#define INIT_STRCASECMP COMMON_INTERCEPT_FUNCTION(strcasecmp)608#define INIT_STRNCASECMP COMMON_INTERCEPT_FUNCTION(strncasecmp)609#else610#define INIT_STRCASECMP611#define INIT_STRNCASECMP612#endif613 614#if SANITIZER_INTERCEPT_STRSTR || SANITIZER_INTERCEPT_STRCASESTR615static inline void StrstrCheck(void *ctx, char *r, const char *s1,616 const char *s2) {617 uptr len1 = internal_strlen(s1);618 uptr len2 = internal_strlen(s2);619 COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r ? r - s1 + len2 : len1 + 1);620 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, len2 + 1);621}622#endif623 624#if SANITIZER_INTERCEPT_STRSTR625 626DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strstr, uptr called_pc,627 const char *s1, const char *s2, char *result)628 629INTERCEPTOR(char*, strstr, const char *s1, const char *s2) {630 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)631 return internal_strstr(s1, s2);632 void *ctx;633 COMMON_INTERCEPTOR_ENTER(ctx, strstr, s1, s2);634 char *r = REAL(strstr)(s1, s2);635 if (common_flags()->intercept_strstr)636 StrstrCheck(ctx, r, s1, s2);637 CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strstr, GET_CALLER_PC(), s1,638 s2, r);639 return r;640}641 642#define INIT_STRSTR COMMON_INTERCEPT_FUNCTION(strstr);643#else644#define INIT_STRSTR645#endif646 647#if SANITIZER_INTERCEPT_STRCASESTR648 649DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasestr, uptr called_pc,650 const char *s1, const char *s2, char *result)651 652INTERCEPTOR(char*, strcasestr, const char *s1, const char *s2) {653 void *ctx;654 COMMON_INTERCEPTOR_ENTER(ctx, strcasestr, s1, s2);655 char *r = REAL(strcasestr)(s1, s2);656 if (common_flags()->intercept_strstr)657 StrstrCheck(ctx, r, s1, s2);658 CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasestr, GET_CALLER_PC(),659 s1, s2, r);660 return r;661}662 663#define INIT_STRCASESTR COMMON_INTERCEPT_FUNCTION(strcasestr);664#else665#define INIT_STRCASESTR666#endif667 668#if SANITIZER_INTERCEPT_STRTOK669 670INTERCEPTOR(char*, strtok, char *str, const char *delimiters) {671 void *ctx;672 COMMON_INTERCEPTOR_ENTER(ctx, strtok, str, delimiters);673 if (!common_flags()->intercept_strtok) {674 return REAL(strtok)(str, delimiters);675 }676 if (common_flags()->strict_string_checks) {677 // If strict_string_checks is enabled, we check the whole first argument678 // string on the first call (strtok saves this string in a static buffer679 // for subsequent calls). We do not need to check strtok's result.680 // As the delimiters can change, we check them every call.681 if (str != nullptr) {682 COMMON_INTERCEPTOR_READ_RANGE(ctx, str, internal_strlen(str) + 1);683 }684 COMMON_INTERCEPTOR_READ_RANGE(ctx, delimiters,685 internal_strlen(delimiters) + 1);686 return REAL(strtok)(str, delimiters);687 } else {688 // However, when strict_string_checks is disabled we cannot check the689 // whole string on the first call. Instead, we check the result string690 // which is guaranteed to be a NULL-terminated substring of the first691 // argument. We also conservatively check one character of str and the692 // delimiters.693 if (str != nullptr) {694 COMMON_INTERCEPTOR_READ_STRING(ctx, str, 1);695 }696 COMMON_INTERCEPTOR_READ_RANGE(ctx, delimiters, 1);697 char *result = REAL(strtok)(str, delimiters);698 if (result != nullptr) {699 COMMON_INTERCEPTOR_READ_RANGE(ctx, result, internal_strlen(result) + 1);700 } else if (str != nullptr) {701 // No delimiter were found, it's safe to assume that the entire str was702 // scanned.703 COMMON_INTERCEPTOR_READ_RANGE(ctx, str, internal_strlen(str) + 1);704 }705 return result;706 }707}708 709#define INIT_STRTOK COMMON_INTERCEPT_FUNCTION(strtok)710#else711#define INIT_STRTOK712#endif713 714#if SANITIZER_INTERCEPT_MEMMEM715DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memmem, uptr called_pc,716 const void *s1, SIZE_T len1, const void *s2,717 SIZE_T len2, void *result)718 719INTERCEPTOR(void*, memmem, const void *s1, SIZE_T len1, const void *s2,720 SIZE_T len2) {721 void *ctx;722 COMMON_INTERCEPTOR_ENTER(ctx, memmem, s1, len1, s2, len2);723 void *r = REAL(memmem)(s1, len1, s2, len2);724 if (common_flags()->intercept_memmem) {725 COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, len1);726 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, len2);727 }728 CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memmem, GET_CALLER_PC(),729 s1, len1, s2, len2, r);730 return r;731}732 733#define INIT_MEMMEM COMMON_INTERCEPT_FUNCTION(memmem);734#else735#define INIT_MEMMEM736#endif // SANITIZER_INTERCEPT_MEMMEM737 738#if SANITIZER_INTERCEPT_STRCHR739INTERCEPTOR(char*, strchr, const char *s, int c) {740 void *ctx;741 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)742 return internal_strchr(s, c);743 COMMON_INTERCEPTOR_ENTER(ctx, strchr, s, c);744 char *result = REAL(strchr)(s, c);745 if (common_flags()->intercept_strchr) {746 // Keep strlen as macro argument, as macro may ignore it.747 COMMON_INTERCEPTOR_READ_STRING(ctx, s,748 (result ? result - s : internal_strlen(s)) + 1);749 }750 return result;751}752#define INIT_STRCHR COMMON_INTERCEPT_FUNCTION(strchr)753#else754#define INIT_STRCHR755#endif756 757#if SANITIZER_INTERCEPT_STRCHRNUL758INTERCEPTOR(char*, strchrnul, const char *s, int c) {759 void *ctx;760 COMMON_INTERCEPTOR_ENTER(ctx, strchrnul, s, c);761 char *result = REAL(strchrnul)(s, c);762 uptr len = result - s + 1;763 if (common_flags()->intercept_strchr)764 COMMON_INTERCEPTOR_READ_STRING(ctx, s, len);765 return result;766}767#define INIT_STRCHRNUL COMMON_INTERCEPT_FUNCTION(strchrnul)768#else769#define INIT_STRCHRNUL770#endif771 772#if SANITIZER_INTERCEPT_STRRCHR773INTERCEPTOR(char*, strrchr, const char *s, int c) {774 void *ctx;775 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)776 return internal_strrchr(s, c);777 COMMON_INTERCEPTOR_ENTER(ctx, strrchr, s, c);778 if (common_flags()->intercept_strchr)779 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, internal_strlen(s) + 1);780 return REAL(strrchr)(s, c);781}782#define INIT_STRRCHR COMMON_INTERCEPT_FUNCTION(strrchr)783#else784#define INIT_STRRCHR785#endif786 787#if SANITIZER_INTERCEPT_STRSPN788INTERCEPTOR(SIZE_T, strspn, const char *s1, const char *s2) {789 void *ctx;790 COMMON_INTERCEPTOR_ENTER(ctx, strspn, s1, s2);791 SIZE_T r = REAL(strspn)(s1, s2);792 if (common_flags()->intercept_strspn) {793 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, internal_strlen(s2) + 1);794 COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r + 1);795 }796 return r;797}798 799INTERCEPTOR(SIZE_T, strcspn, const char *s1, const char *s2) {800 void *ctx;801 COMMON_INTERCEPTOR_ENTER(ctx, strcspn, s1, s2);802 SIZE_T r = REAL(strcspn)(s1, s2);803 if (common_flags()->intercept_strspn) {804 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, internal_strlen(s2) + 1);805 COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r + 1);806 }807 return r;808}809 810#define INIT_STRSPN \811 COMMON_INTERCEPT_FUNCTION(strspn); \812 COMMON_INTERCEPT_FUNCTION(strcspn);813#else814#define INIT_STRSPN815#endif816 817#if SANITIZER_INTERCEPT_STRPBRK818INTERCEPTOR(char *, strpbrk, const char *s1, const char *s2) {819 void *ctx;820 COMMON_INTERCEPTOR_ENTER(ctx, strpbrk, s1, s2);821 char *r = REAL(strpbrk)(s1, s2);822 if (common_flags()->intercept_strpbrk) {823 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, internal_strlen(s2) + 1);824 COMMON_INTERCEPTOR_READ_STRING(ctx, s1,825 r ? r - s1 + 1 : internal_strlen(s1) + 1);826 }827 return r;828}829 830#define INIT_STRPBRK COMMON_INTERCEPT_FUNCTION(strpbrk);831#else832#define INIT_STRPBRK833#endif834 835#if SANITIZER_INTERCEPT_MEMCMP836DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, uptr called_pc,837 const void *s1, const void *s2, usize n,838 int result)839 840// Common code for `memcmp` and `bcmp`.841int MemcmpInterceptorCommon(void *ctx,842 int (*real_fn)(const void *, const void *, usize),843 const void *a1, const void *a2, usize size) {844 if (common_flags()->intercept_memcmp) {845 if (common_flags()->strict_memcmp) {846 // Check the entire regions even if the first bytes of the buffers are847 // different.848 COMMON_INTERCEPTOR_READ_RANGE(ctx, a1, size);849 COMMON_INTERCEPTOR_READ_RANGE(ctx, a2, size);850 // Fallthrough to REAL(memcmp) below.851 } else {852 unsigned char c1 = 0, c2 = 0;853 const unsigned char *s1 = (const unsigned char*)a1;854 const unsigned char *s2 = (const unsigned char*)a2;855 usize i;856 for (i = 0; i < size; i++) {857 c1 = s1[i];858 c2 = s2[i];859 if (c1 != c2) break;860 }861 COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, size));862 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, size));863 int r = CharCmpX(c1, c2);864 CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, GET_CALLER_PC(),865 a1, a2, size, r);866 return r;867 }868 }869 int result = real_fn(a1, a2, size);870 CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, GET_CALLER_PC(), a1,871 a2, size, result);872 return result;873}874 875INTERCEPTOR(int, memcmp, const void *a1, const void *a2, usize size) {876 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)877 return internal_memcmp(a1, a2, size);878 void *ctx;879 COMMON_INTERCEPTOR_ENTER(ctx, memcmp, a1, a2, size);880 return MemcmpInterceptorCommon(ctx, REAL(memcmp), a1, a2, size);881}882 883#define INIT_MEMCMP COMMON_INTERCEPT_FUNCTION(memcmp)884#else885#define INIT_MEMCMP886#endif887 888#if SANITIZER_INTERCEPT_BCMP889INTERCEPTOR(int, bcmp, const void *a1, const void *a2, usize size) {890 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)891 return internal_memcmp(a1, a2, size);892 void *ctx;893 COMMON_INTERCEPTOR_ENTER(ctx, bcmp, a1, a2, size);894 return MemcmpInterceptorCommon(ctx, REAL(bcmp), a1, a2, size);895}896 897#define INIT_BCMP COMMON_INTERCEPT_FUNCTION(bcmp)898#else899#define INIT_BCMP900#endif901 902#if SANITIZER_INTERCEPT_MEMCHR903INTERCEPTOR(void*, memchr, const void *s, int c, SIZE_T n) {904 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)905 return internal_memchr(s, c, n);906 void *ctx;907 COMMON_INTERCEPTOR_ENTER(ctx, memchr, s, c, n);908#if SANITIZER_WINDOWS909 void *res;910 if (REAL(memchr)) {911 res = REAL(memchr)(s, c, n);912 } else {913 res = internal_memchr(s, c, n);914 }915#else916 void *res = REAL(memchr)(s, c, n);917#endif918 uptr len = res ? (char *)res - (const char *)s + 1 : n;919 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, len);920 return res;921}922 923#define INIT_MEMCHR COMMON_INTERCEPT_FUNCTION(memchr)924#else925#define INIT_MEMCHR926#endif927 928#if SANITIZER_INTERCEPT_MEMRCHR929INTERCEPTOR(void*, memrchr, const void *s, int c, SIZE_T n) {930 void *ctx;931 COMMON_INTERCEPTOR_ENTER(ctx, memrchr, s, c, n);932 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, n);933 return REAL(memrchr)(s, c, n);934}935 936#define INIT_MEMRCHR COMMON_INTERCEPT_FUNCTION(memrchr)937#else938#define INIT_MEMRCHR939#endif940 941#if SANITIZER_INTERCEPT_FREXP942INTERCEPTOR(double, frexp, double x, int *exp) {943 void *ctx;944 COMMON_INTERCEPTOR_ENTER(ctx, frexp, x, exp);945 // Assuming frexp() always writes to |exp|.946 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));947 double res = REAL(frexp)(x, exp);948 COMMON_INTERCEPTOR_INITIALIZE_RANGE(exp, sizeof(*exp));949 return res;950}951 952#define INIT_FREXP COMMON_INTERCEPT_FUNCTION(frexp);953#else954#define INIT_FREXP955#endif // SANITIZER_INTERCEPT_FREXP956 957#if SANITIZER_INTERCEPT_FREXPF958INTERCEPTOR(float, frexpf, float x, int *exp) {959 void *ctx;960 COMMON_INTERCEPTOR_ENTER(ctx, frexpf, x, exp);961 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));962 float res = REAL(frexpf)(x, exp);963 COMMON_INTERCEPTOR_INITIALIZE_RANGE(exp, sizeof(*exp));964 return res;965}966 967# define INIT_FREXPF COMMON_INTERCEPT_FUNCTION(frexpf);968#else969# define INIT_FREXPF970#endif971 972#if SANITIZER_INTERCEPT_FREXPL973INTERCEPTOR(long double, frexpl, long double x, int *exp) {974 void *ctx;975 COMMON_INTERCEPTOR_ENTER(ctx, frexpl, x, exp);976 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));977 long double res = REAL(frexpl)(x, exp);978 COMMON_INTERCEPTOR_INITIALIZE_RANGE(exp, sizeof(*exp));979 return res;980}981 982# define INIT_FREXPL COMMON_INTERCEPT_FUNCTION_LDBL(frexpl)983#else984# define INIT_FREXPL985#endif986 987#if SI_POSIX988static void write_iovec(void *ctx, struct __sanitizer_iovec *iovec,989 SIZE_T iovlen, SIZE_T maxlen) {990 for (SIZE_T i = 0; i < iovlen && maxlen; ++i) {991 SSIZE_T sz = Min(iovec[i].iov_len, maxlen);992 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec[i].iov_base, sz);993 maxlen -= sz;994 }995}996 997static void read_iovec(void *ctx, struct __sanitizer_iovec *iovec,998 SIZE_T iovlen, SIZE_T maxlen) {999 COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec) * iovlen);1000 for (SIZE_T i = 0; i < iovlen && maxlen; ++i) {1001 SSIZE_T sz = Min(iovec[i].iov_len, maxlen);1002 COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec[i].iov_base, sz);1003 maxlen -= sz;1004 }1005}1006#endif1007 1008#if SANITIZER_INTERCEPT_READ1009INTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) {1010 void *ctx;1011 COMMON_INTERCEPTOR_ENTER(ctx, read, fd, ptr, count);1012 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);1013 // FIXME: under ASan the call below may write to freed memory and corrupt1014 // its metadata. See1015 // https://github.com/google/sanitizers/issues/321.1016 SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(read)(fd, ptr, count);1017 if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);1018 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);1019 return res;1020}1021#define INIT_READ COMMON_INTERCEPT_FUNCTION(read)1022#else1023#define INIT_READ1024#endif1025 1026#if SANITIZER_INTERCEPT_FREAD1027INTERCEPTOR(SIZE_T, fread, void *ptr, SIZE_T size, SIZE_T nmemb, void *file) {1028 // libc file streams can call user-supplied functions, see fopencookie.1029 void *ctx;1030 COMMON_INTERCEPTOR_ENTER(ctx, fread, ptr, size, nmemb, file);1031 // FIXME: under ASan the call below may write to freed memory and corrupt1032 // its metadata. See1033 // https://github.com/google/sanitizers/issues/321.1034 SIZE_T res = REAL(fread)(ptr, size, nmemb, file);1035 if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res * size);1036 return res;1037}1038#define INIT_FREAD COMMON_INTERCEPT_FUNCTION(fread)1039#else1040#define INIT_FREAD1041#endif1042 1043#if SANITIZER_INTERCEPT_PREAD1044INTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) {1045 void *ctx;1046 COMMON_INTERCEPTOR_ENTER(ctx, pread, fd, ptr, count, offset);1047 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);1048 // FIXME: under ASan the call below may write to freed memory and corrupt1049 // its metadata. See1050 // https://github.com/google/sanitizers/issues/321.1051 SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(pread)(fd, ptr, count, offset);1052 if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);1053 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);1054 return res;1055}1056#define INIT_PREAD COMMON_INTERCEPT_FUNCTION(pread)1057#else1058#define INIT_PREAD1059#endif1060 1061#if SANITIZER_INTERCEPT_PREAD641062INTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) {1063 void *ctx;1064 COMMON_INTERCEPTOR_ENTER(ctx, pread64, fd, ptr, count, offset);1065 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);1066 // FIXME: under ASan the call below may write to freed memory and corrupt1067 // its metadata. See1068 // https://github.com/google/sanitizers/issues/321.1069 SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(pread64)(fd, ptr, count, offset);1070 if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);1071 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);1072 return res;1073}1074#define INIT_PREAD64 COMMON_INTERCEPT_FUNCTION(pread64)1075#else1076#define INIT_PREAD641077#endif1078 1079#if SANITIZER_INTERCEPT_READV1080INTERCEPTOR_WITH_SUFFIX(SSIZE_T, readv, int fd, __sanitizer_iovec *iov,1081 int iovcnt) {1082 void *ctx;1083 COMMON_INTERCEPTOR_ENTER(ctx, readv, fd, iov, iovcnt);1084 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);1085 SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(readv)(fd, iov, iovcnt);1086 if (res > 0) write_iovec(ctx, iov, iovcnt, res);1087 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);1088 return res;1089}1090#define INIT_READV COMMON_INTERCEPT_FUNCTION(readv)1091#else1092#define INIT_READV1093#endif1094 1095#if SANITIZER_INTERCEPT_PREADV1096INTERCEPTOR(SSIZE_T, preadv, int fd, __sanitizer_iovec *iov, int iovcnt,1097 OFF_T offset) {1098 void *ctx;1099 COMMON_INTERCEPTOR_ENTER(ctx, preadv, fd, iov, iovcnt, offset);1100 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);1101 SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(preadv)(fd, iov, iovcnt, offset);1102 if (res > 0) write_iovec(ctx, iov, iovcnt, res);1103 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);1104 return res;1105}1106#define INIT_PREADV COMMON_INTERCEPT_FUNCTION(preadv)1107#else1108#define INIT_PREADV1109#endif1110 1111#if SANITIZER_INTERCEPT_PREADV641112INTERCEPTOR(SSIZE_T, preadv64, int fd, __sanitizer_iovec *iov, int iovcnt,1113 OFF64_T offset) {1114 void *ctx;1115 COMMON_INTERCEPTOR_ENTER(ctx, preadv64, fd, iov, iovcnt, offset);1116 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);1117 SSIZE_T res =1118 COMMON_INTERCEPTOR_BLOCK_REAL(preadv64)(fd, iov, iovcnt, offset);1119 if (res > 0) write_iovec(ctx, iov, iovcnt, res);1120 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);1121 return res;1122}1123#define INIT_PREADV64 COMMON_INTERCEPT_FUNCTION(preadv64)1124#else1125#define INIT_PREADV641126#endif1127 1128#if SANITIZER_INTERCEPT_WRITE1129INTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) {1130 void *ctx;1131 COMMON_INTERCEPTOR_ENTER(ctx, write, fd, ptr, count);1132 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);1133 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);1134 SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(write)(fd, ptr, count);1135 // FIXME: this check should be _before_ the call to1136 // COMMON_INTERCEPTOR_BLOCK_REAL(write), not after1137 if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);1138 return res;1139}1140#define INIT_WRITE COMMON_INTERCEPT_FUNCTION(write)1141#else1142#define INIT_WRITE1143#endif1144 1145#if SANITIZER_INTERCEPT_FWRITE1146INTERCEPTOR(SIZE_T, fwrite, const void *p, usize size, usize nmemb, void *file) {1147 // libc file streams can call user-supplied functions, see fopencookie.1148 void *ctx;1149 COMMON_INTERCEPTOR_ENTER(ctx, fwrite, p, size, nmemb, file);1150 SIZE_T res = REAL(fwrite)(p, size, nmemb, file);1151 if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, p, res * size);1152 return res;1153}1154#define INIT_FWRITE COMMON_INTERCEPT_FUNCTION(fwrite)1155#else1156#define INIT_FWRITE1157#endif1158 1159#if SANITIZER_INTERCEPT_PWRITE1160INTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) {1161 void *ctx;1162 COMMON_INTERCEPTOR_ENTER(ctx, pwrite, fd, ptr, count, offset);1163 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);1164 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);1165 SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(pwrite)(fd, ptr, count, offset);1166 if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);1167 return res;1168}1169#define INIT_PWRITE COMMON_INTERCEPT_FUNCTION(pwrite)1170#else1171#define INIT_PWRITE1172#endif1173 1174#if SANITIZER_INTERCEPT_PWRITE641175INTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count,1176 OFF64_T offset) {1177 void *ctx;1178 COMMON_INTERCEPTOR_ENTER(ctx, pwrite64, fd, ptr, count, offset);1179 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);1180 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);1181 SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(pwrite64)(fd, ptr, count, offset);1182 if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);1183 return res;1184}1185#define INIT_PWRITE64 COMMON_INTERCEPT_FUNCTION(pwrite64)1186#else1187#define INIT_PWRITE641188#endif1189 1190#if SANITIZER_INTERCEPT_WRITEV1191INTERCEPTOR_WITH_SUFFIX(SSIZE_T, writev, int fd, __sanitizer_iovec *iov,1192 int iovcnt) {1193 void *ctx;1194 COMMON_INTERCEPTOR_ENTER(ctx, writev, fd, iov, iovcnt);1195 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);1196 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);1197 SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(writev)(fd, iov, iovcnt);1198 if (res > 0) read_iovec(ctx, iov, iovcnt, res);1199 return res;1200}1201#define INIT_WRITEV COMMON_INTERCEPT_FUNCTION(writev)1202#else1203#define INIT_WRITEV1204#endif1205 1206#if SANITIZER_INTERCEPT_PWRITEV1207INTERCEPTOR(SSIZE_T, pwritev, int fd, __sanitizer_iovec *iov, int iovcnt,1208 OFF_T offset) {1209 void *ctx;1210 COMMON_INTERCEPTOR_ENTER(ctx, pwritev, fd, iov, iovcnt, offset);1211 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);1212 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);1213 SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(pwritev)(fd, iov, iovcnt, offset);1214 if (res > 0) read_iovec(ctx, iov, iovcnt, res);1215 return res;1216}1217#define INIT_PWRITEV COMMON_INTERCEPT_FUNCTION(pwritev)1218#else1219#define INIT_PWRITEV1220#endif1221 1222#if SANITIZER_INTERCEPT_PWRITEV641223INTERCEPTOR(SSIZE_T, pwritev64, int fd, __sanitizer_iovec *iov, int iovcnt,1224 OFF64_T offset) {1225 void *ctx;1226 COMMON_INTERCEPTOR_ENTER(ctx, pwritev64, fd, iov, iovcnt, offset);1227 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);1228 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);1229 SSIZE_T res =1230 COMMON_INTERCEPTOR_BLOCK_REAL(pwritev64)(fd, iov, iovcnt, offset);1231 if (res > 0) read_iovec(ctx, iov, iovcnt, res);1232 return res;1233}1234#define INIT_PWRITEV64 COMMON_INTERCEPT_FUNCTION(pwritev64)1235#else1236#define INIT_PWRITEV641237#endif1238 1239#if SANITIZER_INTERCEPT_FGETS1240INTERCEPTOR(char *, fgets, char *s, SIZE_T size, void *file) {1241 // libc file streams can call user-supplied functions, see fopencookie.1242 void *ctx;1243 COMMON_INTERCEPTOR_ENTER(ctx, fgets, s, size, file);1244 // FIXME: under ASan the call below may write to freed memory and corrupt1245 // its metadata. See1246 // https://github.com/google/sanitizers/issues/321.1247 char *res = REAL(fgets)(s, size, file);1248 if (res)1249 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, internal_strlen(s) + 1);1250 return res;1251}1252#define INIT_FGETS COMMON_INTERCEPT_FUNCTION(fgets)1253#else1254#define INIT_FGETS1255#endif1256 1257#if SANITIZER_INTERCEPT_FPUTS1258INTERCEPTOR_WITH_SUFFIX(int, fputs, char *s, void *file) {1259 // libc file streams can call user-supplied functions, see fopencookie.1260 void *ctx;1261 COMMON_INTERCEPTOR_ENTER(ctx, fputs, s, file);1262 if (!SANITIZER_APPLE || s) { // `fputs(NULL, file)` is supported on Darwin.1263 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, internal_strlen(s) + 1);1264 }1265 return REAL(fputs)(s, file);1266}1267#define INIT_FPUTS COMMON_INTERCEPT_FUNCTION(fputs)1268#else1269#define INIT_FPUTS1270#endif1271 1272#if SANITIZER_INTERCEPT_PUTS1273INTERCEPTOR(int, puts, char *s) {1274 // libc file streams can call user-supplied functions, see fopencookie.1275 void *ctx;1276 COMMON_INTERCEPTOR_ENTER(ctx, puts, s);1277 if (!SANITIZER_APPLE || s) { // `puts(NULL)` is supported on Darwin.1278 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, internal_strlen(s) + 1);1279 }1280 return REAL(puts)(s);1281}1282#define INIT_PUTS COMMON_INTERCEPT_FUNCTION(puts)1283#else1284#define INIT_PUTS1285#endif1286 1287#if SANITIZER_INTERCEPT_PRCTL1288 1289# if defined(__aarch64__)1290// https://llvm.org/docs/PointerAuth.html1291// AArch64 is currently the only architecture with full PAC support.1292// Avoid adding PAC instructions to prevent crashes caused by1293// prctl(PR_PAC_RESET_KEYS, ...). Since PR_PAC_RESET_KEYS resets the1294// authentication key, using the old key afterward will lead to a crash.1295 1296# if defined(__ARM_FEATURE_BTI_DEFAULT)1297# define BRANCH_PROTECTION_ATTRIBUTE \1298 __attribute__((target("branch-protection=bti")))1299# else1300# define BRANCH_PROTECTION_ATTRIBUTE \1301 __attribute__((target("branch-protection=none")))1302# endif1303 1304# define PRCTL_INTERCEPTOR(ret_type, func, ...) \1305 DEFINE_REAL(ret_type, func, __VA_ARGS__) \1306 DECLARE_WRAPPER(ret_type, func, __VA_ARGS__) \1307 extern "C" INTERCEPTOR_ATTRIBUTE BRANCH_PROTECTION_ATTRIBUTE ret_type \1308 WRAP(func)(__VA_ARGS__)1309 1310# else1311# define PRCTL_INTERCEPTOR INTERCEPTOR1312# endif1313 1314PRCTL_INTERCEPTOR(int, prctl, int option, unsigned long arg2,1315 unsigned long arg3, unsigned long arg4, unsigned long arg5) {1316 void *ctx;1317 COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5);1318 static const int PR_SET_NAME = 15;1319 static const int PR_GET_NAME = 16;1320 static const int PR_SET_VMA = 0x53564d41;1321 static const int PR_SCHED_CORE = 62;1322 static const int PR_SCHED_CORE_GET = 0;1323 static const int PR_GET_PDEATHSIG = 2;1324 1325# if !SANITIZER_ANDROID1326 static const int PR_SET_SECCOMP = 22;1327 static const int SECCOMP_MODE_FILTER = 2;1328# endif1329 if (option == PR_SET_VMA && arg2 == 0UL && arg5 != 0UL) {1330 char *name = (char *)arg5;1331 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);1332 }1333 int res = REAL(prctl)(option, arg2, arg3, arg4, arg5);1334 if (option == PR_SET_NAME) {1335 char buff[16];1336 internal_strncpy(buff, (char *)arg2, 15);1337 buff[15] = 0;1338 COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff);1339 } else if (res == 0 && option == PR_GET_NAME) {1340 char *name = (char *)arg2;1341 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, internal_strlen(name) + 1);1342 } else if (res != -1 && option == PR_SCHED_CORE &&1343 arg2 == PR_SCHED_CORE_GET) {1344 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (u64 *)(arg5), sizeof(u64));1345 } else if (res != -1 && option == PR_GET_PDEATHSIG) {1346 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (u64 *)(arg2), sizeof(int));1347# if SANITIZER_GLIBC1348 } else if (res != -1 && option == PR_SET_SECCOMP &&1349 arg2 == SECCOMP_MODE_FILTER) {1350 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (u64 *)(arg3), struct_sock_fprog_sz);1351# endif1352 }1353 return res;1354}1355# define INIT_PRCTL COMMON_INTERCEPT_FUNCTION(prctl)1356#else1357#define INIT_PRCTL1358#endif // SANITIZER_INTERCEPT_PRCTL1359 1360#if SANITIZER_INTERCEPT_TIME1361INTERCEPTOR(unsigned long, time, unsigned long *t) {1362 void *ctx;1363 COMMON_INTERCEPTOR_ENTER(ctx, time, t);1364 unsigned long local_t;1365 unsigned long res = REAL(time)(&local_t);1366 if (t && res != (unsigned long)-1) {1367 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, t, sizeof(*t));1368 *t = local_t;1369 }1370 return res;1371}1372#define INIT_TIME COMMON_INTERCEPT_FUNCTION(time);1373#else1374#define INIT_TIME1375#endif // SANITIZER_INTERCEPT_TIME1376 1377#if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS1378static void unpoison_tm(void *ctx, __sanitizer_tm *tm) {1379 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm));1380// AIX tm struct does not have tm_zone field.1381# if !SANITIZER_SOLARIS && !SANITIZER_AIX1382 if (tm->tm_zone) {1383 // Can not use COMMON_INTERCEPTOR_WRITE_RANGE here, because tm->tm_zone1384 // can point to shared memory and tsan would report a data race.1385 COMMON_INTERCEPTOR_INITIALIZE_RANGE(tm->tm_zone,1386 internal_strlen(tm->tm_zone) + 1);1387 }1388#endif1389}1390INTERCEPTOR(__sanitizer_tm *, localtime, unsigned long *timep) {1391 void *ctx;1392 COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep);1393 __sanitizer_tm *res = REAL(localtime)(timep);1394 if (res) {1395 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));1396 unpoison_tm(ctx, res);1397 }1398 return res;1399}1400INTERCEPTOR(__sanitizer_tm *, localtime_r, unsigned long *timep, void *result) {1401 void *ctx;1402 COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result);1403 __sanitizer_tm *res = REAL(localtime_r)(timep, result);1404 if (res) {1405 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));1406 unpoison_tm(ctx, res);1407 }1408 return res;1409}1410INTERCEPTOR(__sanitizer_tm *, gmtime, unsigned long *timep) {1411 void *ctx;1412 COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep);1413 __sanitizer_tm *res = REAL(gmtime)(timep);1414 if (res) {1415 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));1416 unpoison_tm(ctx, res);1417 }1418 return res;1419}1420INTERCEPTOR(__sanitizer_tm *, gmtime_r, unsigned long *timep, void *result) {1421 void *ctx;1422 COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result);1423 __sanitizer_tm *res = REAL(gmtime_r)(timep, result);1424 if (res) {1425 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));1426 unpoison_tm(ctx, res);1427 }1428 return res;1429}1430INTERCEPTOR(char *, ctime, unsigned long *timep) {1431 void *ctx;1432 COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep);1433 // FIXME: under ASan the call below may write to freed memory and corrupt1434 // its metadata. See1435 // https://github.com/google/sanitizers/issues/321.1436 char *res = REAL(ctime)(timep);1437 if (res) {1438 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));1439 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);1440 }1441 return res;1442}1443INTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) {1444 void *ctx;1445 COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result);1446 // FIXME: under ASan the call below may write to freed memory and corrupt1447 // its metadata. See1448 // https://github.com/google/sanitizers/issues/321.1449 char *res = REAL(ctime_r)(timep, result);1450 if (res) {1451 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));1452 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);1453 }1454 return res;1455}1456INTERCEPTOR(char *, asctime, __sanitizer_tm *tm) {1457 void *ctx;1458 COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm);1459 // FIXME: under ASan the call below may write to freed memory and corrupt1460 // its metadata. See1461 // https://github.com/google/sanitizers/issues/321.1462 char *res = REAL(asctime)(tm);1463 if (res) {1464 COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm));1465 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);1466 }1467 return res;1468}1469INTERCEPTOR(char *, asctime_r, __sanitizer_tm *tm, char *result) {1470 void *ctx;1471 COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result);1472 // FIXME: under ASan the call below may write to freed memory and corrupt1473 // its metadata. See1474 // https://github.com/google/sanitizers/issues/321.1475 char *res = REAL(asctime_r)(tm, result);1476 if (res) {1477 COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm));1478 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);1479 }1480 return res;1481}1482INTERCEPTOR(long, mktime, __sanitizer_tm *tm) {1483 void *ctx;1484 COMMON_INTERCEPTOR_ENTER(ctx, mktime, tm);1485 COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_sec, sizeof(tm->tm_sec));1486 COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_min, sizeof(tm->tm_min));1487 COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_hour, sizeof(tm->tm_hour));1488 COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_mday, sizeof(tm->tm_mday));1489 COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_mon, sizeof(tm->tm_mon));1490 COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_year, sizeof(tm->tm_year));1491 COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_isdst, sizeof(tm->tm_isdst));1492 long res = REAL(mktime)(tm);1493 if (res != -1) unpoison_tm(ctx, tm);1494 return res;1495}1496#define INIT_LOCALTIME_AND_FRIENDS \1497 COMMON_INTERCEPT_FUNCTION(localtime); \1498 COMMON_INTERCEPT_FUNCTION(localtime_r); \1499 COMMON_INTERCEPT_FUNCTION(gmtime); \1500 COMMON_INTERCEPT_FUNCTION(gmtime_r); \1501 COMMON_INTERCEPT_FUNCTION(ctime); \1502 COMMON_INTERCEPT_FUNCTION(ctime_r); \1503 COMMON_INTERCEPT_FUNCTION(asctime); \1504 COMMON_INTERCEPT_FUNCTION(asctime_r); \1505 COMMON_INTERCEPT_FUNCTION(mktime);1506#else1507#define INIT_LOCALTIME_AND_FRIENDS1508#endif // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS1509 1510#if SANITIZER_INTERCEPT_STRPTIME1511INTERCEPTOR(char *, strptime, char *s, char *format, __sanitizer_tm *tm) {1512 void *ctx;1513 COMMON_INTERCEPTOR_ENTER(ctx, strptime, s, format, tm);1514 if (format)1515 COMMON_INTERCEPTOR_READ_RANGE(ctx, format, internal_strlen(format) + 1);1516 // FIXME: under ASan the call below may write to freed memory and corrupt1517 // its metadata. See1518 // https://github.com/google/sanitizers/issues/321.1519 char *res = REAL(strptime)(s, format, tm);1520 COMMON_INTERCEPTOR_READ_STRING(ctx, s, res ? res - s : 0);1521 if (res && tm) {1522 // Do not call unpoison_tm here, because strptime does not, in fact,1523 // initialize the entire struct tm. For example, tm_zone pointer is left1524 // uninitialized.1525 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm));1526 }1527 return res;1528}1529#define INIT_STRPTIME COMMON_INTERCEPT_FUNCTION(strptime);1530#else1531#define INIT_STRPTIME1532#endif1533 1534#if SANITIZER_INTERCEPT_SCANF || SANITIZER_INTERCEPT_PRINTF1535#include "sanitizer_common_interceptors_format.inc"1536 1537#define FORMAT_INTERCEPTOR_IMPL(name, vname, ...) \1538 { \1539 void *ctx; \1540 va_list ap; \1541 va_start(ap, format); \1542 COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__, ap); \1543 int res = WRAP(vname)(__VA_ARGS__, ap); \1544 va_end(ap); \1545 return res; \1546 }1547 1548#endif1549 1550#if SANITIZER_INTERCEPT_SCANF1551 1552#define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...) \1553 { \1554 void *ctx; \1555 COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__); \1556 va_list aq; \1557 va_copy(aq, ap); \1558 int res = REAL(vname)(__VA_ARGS__); \1559 if (res > 0) \1560 scanf_common(ctx, res, allowGnuMalloc, format, aq); \1561 va_end(aq); \1562 return res; \1563 }1564 1565INTERCEPTOR(int, vscanf, const char *format, va_list ap)1566VSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap)1567 1568INTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap)1569VSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap)1570 1571INTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap)1572VSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap)1573 1574#if SANITIZER_INTERCEPT_ISOC99_SCANF1575INTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap)1576VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap)1577 1578INTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format,1579 va_list ap)1580VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap)1581 1582INTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap)1583VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap)1584 1585INTERCEPTOR(int, __isoc23_vscanf, const char *format, va_list ap)1586VSCANF_INTERCEPTOR_IMPL(__isoc23_vscanf, false, format, ap)1587 1588INTERCEPTOR(int, __isoc23_vsscanf, const char *str, const char *format,1589 va_list ap)1590VSCANF_INTERCEPTOR_IMPL(__isoc23_vsscanf, false, str, format, ap)1591 1592INTERCEPTOR(int, __isoc23_vfscanf, void *stream, const char *format, va_list ap)1593VSCANF_INTERCEPTOR_IMPL(__isoc23_vfscanf, false, stream, format, ap)1594#endif // SANITIZER_INTERCEPT_ISOC99_SCANF1595 1596INTERCEPTOR(int, scanf, const char *format, ...)1597FORMAT_INTERCEPTOR_IMPL(scanf, vscanf, format)1598 1599INTERCEPTOR(int, fscanf, void *stream, const char *format, ...)1600FORMAT_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format)1601 1602INTERCEPTOR(int, sscanf, const char *str, const char *format, ...)1603FORMAT_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format)1604 1605#if SANITIZER_INTERCEPT_ISOC99_SCANF1606INTERCEPTOR(int, __isoc99_scanf, const char *format, ...)1607FORMAT_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format)1608 1609INTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...)1610FORMAT_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format)1611 1612INTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...)1613FORMAT_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format)1614 1615INTERCEPTOR(int, __isoc23_scanf, const char *format, ...)1616FORMAT_INTERCEPTOR_IMPL(__isoc23_scanf, __isoc23_vscanf, format)1617 1618INTERCEPTOR(int, __isoc23_fscanf, void *stream, const char *format, ...)1619FORMAT_INTERCEPTOR_IMPL(__isoc23_fscanf, __isoc23_vfscanf, stream, format)1620 1621INTERCEPTOR(int, __isoc23_sscanf, const char *str, const char *format, ...)1622FORMAT_INTERCEPTOR_IMPL(__isoc23_sscanf, __isoc23_vsscanf, str, format)1623#endif1624 1625#endif1626 1627#if SANITIZER_INTERCEPT_SCANF1628#define INIT_SCANF \1629 COMMON_INTERCEPT_FUNCTION_LDBL(scanf); \1630 COMMON_INTERCEPT_FUNCTION_LDBL(sscanf); \1631 COMMON_INTERCEPT_FUNCTION_LDBL(fscanf); \1632 COMMON_INTERCEPT_FUNCTION_LDBL(vscanf); \1633 COMMON_INTERCEPT_FUNCTION_LDBL(vsscanf); \1634 COMMON_INTERCEPT_FUNCTION_LDBL(vfscanf);1635#else1636#define INIT_SCANF1637#endif1638 1639#if SANITIZER_INTERCEPT_ISOC99_SCANF1640#define INIT_ISOC99_SCANF \1641 COMMON_INTERCEPT_FUNCTION(__isoc99_scanf); \1642 COMMON_INTERCEPT_FUNCTION(__isoc99_sscanf); \1643 COMMON_INTERCEPT_FUNCTION(__isoc99_fscanf); \1644 COMMON_INTERCEPT_FUNCTION(__isoc99_vscanf); \1645 COMMON_INTERCEPT_FUNCTION(__isoc99_vsscanf); \1646 COMMON_INTERCEPT_FUNCTION(__isoc99_vfscanf); \1647 COMMON_INTERCEPT_FUNCTION(__isoc23_scanf); \1648 COMMON_INTERCEPT_FUNCTION(__isoc23_sscanf); \1649 COMMON_INTERCEPT_FUNCTION(__isoc23_fscanf); \1650 COMMON_INTERCEPT_FUNCTION(__isoc23_vscanf); \1651 COMMON_INTERCEPT_FUNCTION(__isoc23_vsscanf); \1652 COMMON_INTERCEPT_FUNCTION(__isoc23_vfscanf);1653#else1654#define INIT_ISOC99_SCANF1655#endif1656 1657#if SANITIZER_INTERCEPT_PRINTF1658 1659#define VPRINTF_INTERCEPTOR_ENTER(vname, ...) \1660 void *ctx; \1661 COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__); \1662 va_list aq; \1663 va_copy(aq, ap);1664 1665#define VPRINTF_INTERCEPTOR_RETURN() \1666 va_end(aq);1667 1668#define VPRINTF_INTERCEPTOR_IMPL(vname, ...) \1669 { \1670 VPRINTF_INTERCEPTOR_ENTER(vname, __VA_ARGS__); \1671 if (common_flags()->check_printf) \1672 printf_common(ctx, format, aq); \1673 int res = REAL(vname)(__VA_ARGS__); \1674 VPRINTF_INTERCEPTOR_RETURN(); \1675 return res; \1676 }1677 1678// FIXME: under ASan the REAL() call below may write to freed memory and1679// corrupt its metadata. See1680// https://github.com/google/sanitizers/issues/321.1681#define VSPRINTF_INTERCEPTOR_IMPL(vname, str, ...) \1682 { \1683 VPRINTF_INTERCEPTOR_ENTER(vname, str, __VA_ARGS__) \1684 if (common_flags()->check_printf) { \1685 printf_common(ctx, format, aq); \1686 } \1687 int res = REAL(vname)(str, __VA_ARGS__); \1688 if (res >= 0) { \1689 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, res + 1); \1690 } \1691 VPRINTF_INTERCEPTOR_RETURN(); \1692 return res; \1693 }1694 1695// FIXME: under ASan the REAL() call below may write to freed memory and1696// corrupt its metadata. See1697// https://github.com/google/sanitizers/issues/321.1698#define VSNPRINTF_INTERCEPTOR_IMPL(vname, str, size, ...) \1699 { \1700 VPRINTF_INTERCEPTOR_ENTER(vname, str, size, __VA_ARGS__) \1701 if (common_flags()->check_printf) { \1702 printf_common(ctx, format, aq); \1703 } \1704 int res = REAL(vname)(str, size, __VA_ARGS__); \1705 if (res >= 0) { \1706 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, Min(size, (SIZE_T)(res + 1))); \1707 } \1708 VPRINTF_INTERCEPTOR_RETURN(); \1709 return res; \1710 }1711 1712// FIXME: under ASan the REAL() call below may write to freed memory and1713// corrupt its metadata. See1714// https://github.com/google/sanitizers/issues/321.1715#define VASPRINTF_INTERCEPTOR_IMPL(vname, strp, ...) \1716 { \1717 VPRINTF_INTERCEPTOR_ENTER(vname, strp, __VA_ARGS__) \1718 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, strp, sizeof(char *)); \1719 if (common_flags()->check_printf) { \1720 printf_common(ctx, format, aq); \1721 } \1722 int res = REAL(vname)(strp, __VA_ARGS__); \1723 if (res >= 0) { \1724 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *strp, res + 1); \1725 } \1726 VPRINTF_INTERCEPTOR_RETURN(); \1727 return res; \1728 }1729 1730INTERCEPTOR(int, vprintf, const char *format, va_list ap)1731VPRINTF_INTERCEPTOR_IMPL(vprintf, format, ap)1732 1733INTERCEPTOR(int, vfprintf, __sanitizer_FILE *stream, const char *format,1734 va_list ap)1735VPRINTF_INTERCEPTOR_IMPL(vfprintf, stream, format, ap)1736 1737INTERCEPTOR(int, vsnprintf, char *str, SIZE_T size, const char *format,1738 va_list ap)1739VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf, str, size, format, ap)1740 1741#if SANITIZER_INTERCEPT___PRINTF_CHK1742INTERCEPTOR(int, __vsnprintf_chk, char *str, SIZE_T size, int flag,1743 SIZE_T size_to, const char *format, va_list ap)1744VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf, str, size, format, ap)1745#endif1746 1747#if SANITIZER_INTERCEPT_PRINTF_L1748INTERCEPTOR(int, vsnprintf_l, char *str, SIZE_T size, void *loc,1749 const char *format, va_list ap)1750VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf_l, str, size, loc, format, ap)1751 1752INTERCEPTOR(int, snprintf_l, char *str, SIZE_T size, void *loc,1753 const char *format, ...)1754FORMAT_INTERCEPTOR_IMPL(snprintf_l, vsnprintf_l, str, size, loc, format)1755#endif // SANITIZER_INTERCEPT_PRINTF_L1756 1757INTERCEPTOR(int, vsprintf, char *str, const char *format, va_list ap)1758VSPRINTF_INTERCEPTOR_IMPL(vsprintf, str, format, ap)1759 1760#if SANITIZER_INTERCEPT___PRINTF_CHK1761INTERCEPTOR(int, __vsprintf_chk, char *str, int flag, SIZE_T size_to,1762 const char *format, va_list ap)1763VSPRINTF_INTERCEPTOR_IMPL(vsprintf, str, format, ap)1764#endif1765 1766# if SANITIZER_INTERCEPT_VASPRINTF1767INTERCEPTOR(int, vasprintf, char **strp, const char *format, va_list ap)1768VASPRINTF_INTERCEPTOR_IMPL(vasprintf, strp, format, ap)1769# endif1770 1771# if SANITIZER_INTERCEPT_ISOC99_PRINTF1772INTERCEPTOR(int, __isoc99_vprintf, const char *format, va_list ap)1773VPRINTF_INTERCEPTOR_IMPL(__isoc99_vprintf, format, ap)1774 1775INTERCEPTOR(int, __isoc99_vfprintf, __sanitizer_FILE *stream,1776 const char *format, va_list ap)1777VPRINTF_INTERCEPTOR_IMPL(__isoc99_vfprintf, stream, format, ap)1778 1779INTERCEPTOR(int, __isoc99_vsnprintf, char *str, SIZE_T size, const char *format,1780 va_list ap)1781VSNPRINTF_INTERCEPTOR_IMPL(__isoc99_vsnprintf, str, size, format, ap)1782 1783INTERCEPTOR(int, __isoc99_vsprintf, char *str, const char *format,1784 va_list ap)1785VSPRINTF_INTERCEPTOR_IMPL(__isoc99_vsprintf, str, format,1786 ap)1787 1788#endif // SANITIZER_INTERCEPT_ISOC99_PRINTF1789 1790INTERCEPTOR(int, printf, const char *format, ...)1791FORMAT_INTERCEPTOR_IMPL(printf, vprintf, format)1792 1793INTERCEPTOR(int, fprintf, __sanitizer_FILE *stream, const char *format, ...)1794FORMAT_INTERCEPTOR_IMPL(fprintf, vfprintf, stream, format)1795 1796#if SANITIZER_INTERCEPT___PRINTF_CHK1797INTERCEPTOR(int, __fprintf_chk, __sanitizer_FILE *stream, SIZE_T size,1798 const char *format, ...)1799FORMAT_INTERCEPTOR_IMPL(__fprintf_chk, vfprintf, stream, format)1800#endif1801 1802INTERCEPTOR(int, sprintf, char *str, const char *format, ...)1803FORMAT_INTERCEPTOR_IMPL(sprintf, vsprintf, str, format)1804 1805#if SANITIZER_INTERCEPT___PRINTF_CHK1806INTERCEPTOR(int, __sprintf_chk, char *str, int flag, SIZE_T size_to,1807 const char *format, ...)1808FORMAT_INTERCEPTOR_IMPL(__sprintf_chk, vsprintf, str, format)1809#endif1810 1811INTERCEPTOR(int, snprintf, char *str, SIZE_T size, const char *format, ...)1812FORMAT_INTERCEPTOR_IMPL(snprintf, vsnprintf, str, size, format)1813 1814#if SANITIZER_INTERCEPT___PRINTF_CHK1815INTERCEPTOR(int, __snprintf_chk, char *str, SIZE_T size, int flag,1816 SIZE_T size_to, const char *format, ...)1817FORMAT_INTERCEPTOR_IMPL(__snprintf_chk, vsnprintf, str, size, format)1818#endif1819 1820# if SANITIZER_INTERCEPT_ASPRINTF1821INTERCEPTOR(int, asprintf, char **strp, const char *format, ...)1822FORMAT_INTERCEPTOR_IMPL(asprintf, vasprintf, strp, format)1823# endif1824 1825# if SANITIZER_INTERCEPT_ISOC99_PRINTF1826INTERCEPTOR(int, __isoc99_printf, const char *format, ...)1827FORMAT_INTERCEPTOR_IMPL(__isoc99_printf, __isoc99_vprintf, format)1828 1829INTERCEPTOR(int, __isoc99_fprintf, __sanitizer_FILE *stream, const char *format,1830 ...)1831FORMAT_INTERCEPTOR_IMPL(__isoc99_fprintf, __isoc99_vfprintf, stream, format)1832 1833INTERCEPTOR(int, __isoc99_sprintf, char *str, const char *format, ...)1834FORMAT_INTERCEPTOR_IMPL(__isoc99_sprintf, __isoc99_vsprintf, str, format)1835 1836INTERCEPTOR(int, __isoc99_snprintf, char *str, SIZE_T size,1837 const char *format, ...)1838FORMAT_INTERCEPTOR_IMPL(__isoc99_snprintf, __isoc99_vsnprintf, str, size,1839 format)1840 1841#endif // SANITIZER_INTERCEPT_ISOC99_PRINTF1842 1843#endif // SANITIZER_INTERCEPT_PRINTF1844 1845#if SANITIZER_INTERCEPT_PRINTF1846# define INIT_PRINTF_COMMON \1847 COMMON_INTERCEPT_FUNCTION_LDBL(printf); \1848 COMMON_INTERCEPT_FUNCTION_LDBL(sprintf); \1849 COMMON_INTERCEPT_FUNCTION_LDBL(snprintf); \1850 COMMON_INTERCEPT_FUNCTION_LDBL(fprintf); \1851 COMMON_INTERCEPT_FUNCTION_LDBL(vprintf); \1852 COMMON_INTERCEPT_FUNCTION_LDBL(vsprintf); \1853 COMMON_INTERCEPT_FUNCTION_LDBL(vsnprintf); \1854 COMMON_INTERCEPT_FUNCTION_LDBL(vfprintf);1855# if !SANITIZER_AIX1856// AIX does not have [v]asprintf.1857# define INIT_PRINTF_EXTRA \1858 COMMON_INTERCEPT_FUNCTION_LDBL(asprintf); \1859 COMMON_INTERCEPT_FUNCTION_LDBL(vasprintf);1860# else1861# define INIT_PRINTF_EXTRA1862# endif1863# define INIT_PRINTF INIT_PRINTF_COMMON INIT_PRINTF_EXTRA1864#else1865#define INIT_PRINTF1866#endif1867 1868#if SANITIZER_INTERCEPT___PRINTF_CHK1869#define INIT___PRINTF_CHK \1870 COMMON_INTERCEPT_FUNCTION(__sprintf_chk); \1871 COMMON_INTERCEPT_FUNCTION(__snprintf_chk); \1872 COMMON_INTERCEPT_FUNCTION(__vsprintf_chk); \1873 COMMON_INTERCEPT_FUNCTION(__vsnprintf_chk); \1874 COMMON_INTERCEPT_FUNCTION(__fprintf_chk);1875#else1876#define INIT___PRINTF_CHK1877#endif1878 1879#if SANITIZER_INTERCEPT_PRINTF_L1880#define INIT_PRINTF_L \1881 COMMON_INTERCEPT_FUNCTION(snprintf_l); \1882 COMMON_INTERCEPT_FUNCTION(vsnprintf_l);1883#else1884#define INIT_PRINTF_L1885#endif1886 1887#if SANITIZER_INTERCEPT_ISOC99_PRINTF1888#define INIT_ISOC99_PRINTF \1889 COMMON_INTERCEPT_FUNCTION(__isoc99_printf); \1890 COMMON_INTERCEPT_FUNCTION(__isoc99_sprintf); \1891 COMMON_INTERCEPT_FUNCTION(__isoc99_snprintf); \1892 COMMON_INTERCEPT_FUNCTION(__isoc99_fprintf); \1893 COMMON_INTERCEPT_FUNCTION(__isoc99_vprintf); \1894 COMMON_INTERCEPT_FUNCTION(__isoc99_vsprintf); \1895 COMMON_INTERCEPT_FUNCTION(__isoc99_vsnprintf); \1896 COMMON_INTERCEPT_FUNCTION(__isoc99_vfprintf);1897#else1898#define INIT_ISOC99_PRINTF1899#endif1900 1901#if SANITIZER_INTERCEPT_SETPROCTITLE1902INTERCEPTOR(void, setproctitle, const char *fmt, ...) {1903 void *ctx;1904 va_list ap;1905 va_start(ap, fmt);1906 COMMON_INTERCEPTOR_ENTER(ctx, setproctitle, fmt, ap);1907 if (common_flags()->check_printf)1908 printf_common(ctx, fmt, ap);1909 REAL(setproctitle)(fmt, ap);1910 va_end(ap);1911}1912# define INIT_SETPROCTITLE COMMON_INTERCEPT_FUNCTION(setproctitle);1913#else1914# define INIT_SETPROCTITLE1915#endif1916 1917#if SANITIZER_INTERCEPT_IOCTL1918#include "sanitizer_common_interceptors_ioctl.inc"1919#include "sanitizer_interceptors_ioctl_netbsd.inc"1920INTERCEPTOR(int, ioctl, int d, unsigned long request, ...) {1921 // We need a frame pointer, because we call into ioctl_common_[pre|post] which1922 // can trigger a report and we need to be able to unwind through this1923 // function. On Mac in debug mode we might not have a frame pointer, because1924 // ioctl_common_[pre|post] doesn't get inlined here.1925 ENABLE_FRAME_POINTER;1926 1927 void *ctx;1928 va_list ap;1929 va_start(ap, request);1930 void *arg = va_arg(ap, void *);1931 va_end(ap);1932 COMMON_INTERCEPTOR_ENTER(ctx, ioctl, d, request, arg);1933 1934 CHECK(ioctl_initialized);1935 1936 // Note: TSan does not use common flags, and they are zero-initialized.1937 // This effectively disables ioctl handling in TSan.1938 if (!common_flags()->handle_ioctl) return REAL(ioctl)(d, request, arg);1939 1940 // Although request is unsigned long, the rest of the interceptor uses it1941 // as just "unsigned" to save space, because we know that all values fit in1942 // "unsigned" - they are compile-time constants.1943 1944 const ioctl_desc *desc = ioctl_lookup(request);1945 ioctl_desc decoded_desc;1946 if (!desc) {1947 VPrintf(2, "Decoding unknown ioctl 0x%lx\n", request);1948 if (!ioctl_decode(request, &decoded_desc))1949 Printf("WARNING: failed decoding unknown ioctl 0x%lx\n", request);1950 else1951 desc = &decoded_desc;1952 }1953 1954 if (desc) ioctl_common_pre(ctx, desc, d, request, arg);1955 int res = REAL(ioctl)(d, request, arg);1956 // FIXME: some ioctls have different return values for success and failure.1957 if (desc && res != -1) ioctl_common_post(ctx, desc, res, d, request, arg);1958 return res;1959}1960#define INIT_IOCTL \1961 ioctl_init(); \1962 COMMON_INTERCEPT_FUNCTION(ioctl);1963#else1964#define INIT_IOCTL1965#endif1966 1967#if SANITIZER_POSIX1968UNUSED static void unpoison_passwd(void *ctx, __sanitizer_passwd *pwd) {1969 if (pwd) {1970 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, sizeof(*pwd));1971 if (pwd->pw_name)1972 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_name,1973 internal_strlen(pwd->pw_name) + 1);1974 if (pwd->pw_passwd)1975 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_passwd,1976 internal_strlen(pwd->pw_passwd) + 1);1977#if !SANITIZER_ANDROID1978 if (pwd->pw_gecos)1979 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_gecos,1980 internal_strlen(pwd->pw_gecos) + 1);1981#endif1982#if SANITIZER_APPLE || SANITIZER_FREEBSD || SANITIZER_NETBSD1983 if (pwd->pw_class)1984 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_class,1985 internal_strlen(pwd->pw_class) + 1);1986#endif1987 if (pwd->pw_dir)1988 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_dir,1989 internal_strlen(pwd->pw_dir) + 1);1990 if (pwd->pw_shell)1991 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_shell,1992 internal_strlen(pwd->pw_shell) + 1);1993 }1994}1995 1996UNUSED static void unpoison_group(void *ctx, __sanitizer_group *grp) {1997 if (grp) {1998 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, sizeof(*grp));1999 if (grp->gr_name)2000 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp->gr_name,2001 internal_strlen(grp->gr_name) + 1);2002 if (grp->gr_passwd)2003 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp->gr_passwd,2004 internal_strlen(grp->gr_passwd) + 1);2005 char **p = grp->gr_mem;2006 for (; *p; ++p) {2007 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, internal_strlen(*p) + 1);2008 }2009 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp->gr_mem,2010 (p - grp->gr_mem + 1) * sizeof(*p));2011 }2012}2013#endif // SANITIZER_POSIX2014 2015#if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS2016INTERCEPTOR(__sanitizer_passwd *, getpwnam, const char *name) {2017 void *ctx;2018 COMMON_INTERCEPTOR_ENTER(ctx, getpwnam, name);2019 if (name)2020 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);2021 __sanitizer_passwd *res = REAL(getpwnam)(name);2022 unpoison_passwd(ctx, res);2023 return res;2024}2025INTERCEPTOR(__sanitizer_passwd *, getpwuid, u32 uid) {2026 void *ctx;2027 COMMON_INTERCEPTOR_ENTER(ctx, getpwuid, uid);2028 __sanitizer_passwd *res = REAL(getpwuid)(uid);2029 unpoison_passwd(ctx, res);2030 return res;2031}2032INTERCEPTOR(__sanitizer_group *, getgrnam, const char *name) {2033 void *ctx;2034 COMMON_INTERCEPTOR_ENTER(ctx, getgrnam, name);2035 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);2036 __sanitizer_group *res = REAL(getgrnam)(name);2037 unpoison_group(ctx, res);2038 return res;2039}2040INTERCEPTOR(__sanitizer_group *, getgrgid, u32 gid) {2041 void *ctx;2042 COMMON_INTERCEPTOR_ENTER(ctx, getgrgid, gid);2043 __sanitizer_group *res = REAL(getgrgid)(gid);2044 unpoison_group(ctx, res);2045 return res;2046}2047#define INIT_GETPWNAM_AND_FRIENDS \2048 COMMON_INTERCEPT_FUNCTION(getpwnam); \2049 COMMON_INTERCEPT_FUNCTION(getpwuid); \2050 COMMON_INTERCEPT_FUNCTION(getgrnam); \2051 COMMON_INTERCEPT_FUNCTION(getgrgid);2052#else2053#define INIT_GETPWNAM_AND_FRIENDS2054#endif2055 2056#if SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS2057INTERCEPTOR(int, getpwnam_r, const char *name, __sanitizer_passwd *pwd,2058 char *buf, SIZE_T buflen, __sanitizer_passwd **result) {2059 void *ctx;2060 COMMON_INTERCEPTOR_ENTER(ctx, getpwnam_r, name, pwd, buf, buflen, result);2061 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);2062 // FIXME: under ASan the call below may write to freed memory and corrupt2063 // its metadata. See2064 // https://github.com/google/sanitizers/issues/321.2065 int res = REAL(getpwnam_r)(name, pwd, buf, buflen, result);2066 if (!res && result)2067 unpoison_passwd(ctx, *result);2068 if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));2069 return res;2070}2071INTERCEPTOR(int, getpwuid_r, u32 uid, __sanitizer_passwd *pwd, char *buf,2072 SIZE_T buflen, __sanitizer_passwd **result) {2073 void *ctx;2074 COMMON_INTERCEPTOR_ENTER(ctx, getpwuid_r, uid, pwd, buf, buflen, result);2075 // FIXME: under ASan the call below may write to freed memory and corrupt2076 // its metadata. See2077 // https://github.com/google/sanitizers/issues/321.2078 int res = REAL(getpwuid_r)(uid, pwd, buf, buflen, result);2079 if (!res && result)2080 unpoison_passwd(ctx, *result);2081 if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));2082 return res;2083}2084INTERCEPTOR(int, getgrnam_r, const char *name, __sanitizer_group *grp,2085 char *buf, SIZE_T buflen, __sanitizer_group **result) {2086 void *ctx;2087 COMMON_INTERCEPTOR_ENTER(ctx, getgrnam_r, name, grp, buf, buflen, result);2088 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);2089 // FIXME: under ASan the call below may write to freed memory and corrupt2090 // its metadata. See2091 // https://github.com/google/sanitizers/issues/321.2092 int res = REAL(getgrnam_r)(name, grp, buf, buflen, result);2093 if (!res && result)2094 unpoison_group(ctx, *result);2095 if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));2096 return res;2097}2098INTERCEPTOR(int, getgrgid_r, u32 gid, __sanitizer_group *grp, char *buf,2099 SIZE_T buflen, __sanitizer_group **result) {2100 void *ctx;2101 COMMON_INTERCEPTOR_ENTER(ctx, getgrgid_r, gid, grp, buf, buflen, result);2102 // FIXME: under ASan the call below may write to freed memory and corrupt2103 // its metadata. See2104 // https://github.com/google/sanitizers/issues/321.2105 int res = REAL(getgrgid_r)(gid, grp, buf, buflen, result);2106 if (!res && result)2107 unpoison_group(ctx, *result);2108 if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));2109 return res;2110}2111#define INIT_GETPWNAM_R_AND_FRIENDS \2112 COMMON_INTERCEPT_FUNCTION(getpwnam_r); \2113 COMMON_INTERCEPT_FUNCTION(getpwuid_r); \2114 COMMON_INTERCEPT_FUNCTION(getgrnam_r); \2115 COMMON_INTERCEPT_FUNCTION(getgrgid_r);2116#else2117#define INIT_GETPWNAM_R_AND_FRIENDS2118#endif2119 2120#if SANITIZER_INTERCEPT_GETPWENT2121INTERCEPTOR(__sanitizer_passwd *, getpwent, int dummy) {2122 void *ctx;2123 COMMON_INTERCEPTOR_ENTER(ctx, getpwent, dummy);2124 __sanitizer_passwd *res = REAL(getpwent)(dummy);2125 unpoison_passwd(ctx, res);2126 return res;2127}2128INTERCEPTOR(__sanitizer_group *, getgrent, int dummy) {2129 void *ctx;2130 COMMON_INTERCEPTOR_ENTER(ctx, getgrent, dummy);2131 __sanitizer_group *res = REAL(getgrent)(dummy);2132 unpoison_group(ctx, res);2133 return res;2134}2135#define INIT_GETPWENT \2136 COMMON_INTERCEPT_FUNCTION(getpwent); \2137 COMMON_INTERCEPT_FUNCTION(getgrent);2138#else2139#define INIT_GETPWENT2140#endif2141 2142#if SANITIZER_INTERCEPT_FGETPWENT2143INTERCEPTOR(__sanitizer_passwd *, fgetpwent, void *fp) {2144 void *ctx;2145 COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent, fp);2146 __sanitizer_passwd *res = REAL(fgetpwent)(fp);2147 unpoison_passwd(ctx, res);2148 return res;2149}2150INTERCEPTOR(__sanitizer_group *, fgetgrent, void *fp) {2151 void *ctx;2152 COMMON_INTERCEPTOR_ENTER(ctx, fgetgrent, fp);2153 __sanitizer_group *res = REAL(fgetgrent)(fp);2154 unpoison_group(ctx, res);2155 return res;2156}2157#define INIT_FGETPWENT \2158 COMMON_INTERCEPT_FUNCTION(fgetpwent); \2159 COMMON_INTERCEPT_FUNCTION(fgetgrent);2160#else2161#define INIT_FGETPWENT2162#endif2163 2164#if SANITIZER_INTERCEPT_GETPWENT_R2165INTERCEPTOR(int, getpwent_r, __sanitizer_passwd *pwbuf, char *buf,2166 SIZE_T buflen, __sanitizer_passwd **pwbufp) {2167 void *ctx;2168 COMMON_INTERCEPTOR_ENTER(ctx, getpwent_r, pwbuf, buf, buflen, pwbufp);2169 // FIXME: under ASan the call below may write to freed memory and corrupt2170 // its metadata. See2171 // https://github.com/google/sanitizers/issues/321.2172 int res = REAL(getpwent_r)(pwbuf, buf, buflen, pwbufp);2173 if (!res && pwbufp)2174 unpoison_passwd(ctx, *pwbufp);2175 if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));2176 return res;2177}2178INTERCEPTOR(int, getgrent_r, __sanitizer_group *pwbuf, char *buf, SIZE_T buflen,2179 __sanitizer_group **pwbufp) {2180 void *ctx;2181 COMMON_INTERCEPTOR_ENTER(ctx, getgrent_r, pwbuf, buf, buflen, pwbufp);2182 // FIXME: under ASan the call below may write to freed memory and corrupt2183 // its metadata. See2184 // https://github.com/google/sanitizers/issues/321.2185 int res = REAL(getgrent_r)(pwbuf, buf, buflen, pwbufp);2186 if (!res && pwbufp)2187 unpoison_group(ctx, *pwbufp);2188 if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));2189 return res;2190}2191#define INIT_GETPWENT_R \2192 COMMON_INTERCEPT_FUNCTION(getpwent_r); \2193 COMMON_INTERCEPT_FUNCTION(getgrent_r);2194#else2195#define INIT_GETPWENT_R2196#endif2197 2198#if SANITIZER_INTERCEPT_FGETPWENT_R2199INTERCEPTOR(int, fgetpwent_r, void *fp, __sanitizer_passwd *pwbuf, char *buf,2200 SIZE_T buflen, __sanitizer_passwd **pwbufp) {2201 void *ctx;2202 COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent_r, fp, pwbuf, buf, buflen, pwbufp);2203 // FIXME: under ASan the call below may write to freed memory and corrupt2204 // its metadata. See2205 // https://github.com/google/sanitizers/issues/321.2206 int res = REAL(fgetpwent_r)(fp, pwbuf, buf, buflen, pwbufp);2207 if (!res && pwbufp)2208 unpoison_passwd(ctx, *pwbufp);2209 if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));2210 return res;2211}2212#define INIT_FGETPWENT_R \2213 COMMON_INTERCEPT_FUNCTION(fgetpwent_r);2214#else2215#define INIT_FGETPWENT_R2216#endif2217 2218#if SANITIZER_INTERCEPT_FGETGRENT_R2219INTERCEPTOR(int, fgetgrent_r, void *fp, __sanitizer_group *pwbuf, char *buf,2220 SIZE_T buflen, __sanitizer_group **pwbufp) {2221 void *ctx;2222 COMMON_INTERCEPTOR_ENTER(ctx, fgetgrent_r, fp, pwbuf, buf, buflen, pwbufp);2223 // FIXME: under ASan the call below may write to freed memory and corrupt2224 // its metadata. See2225 // https://github.com/google/sanitizers/issues/321.2226 int res = REAL(fgetgrent_r)(fp, pwbuf, buf, buflen, pwbufp);2227 if (!res && pwbufp)2228 unpoison_group(ctx, *pwbufp);2229 if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));2230 return res;2231}2232#define INIT_FGETGRENT_R \2233 COMMON_INTERCEPT_FUNCTION(fgetgrent_r);2234#else2235#define INIT_FGETGRENT_R2236#endif2237 2238#if SANITIZER_INTERCEPT_SETPWENT2239// The only thing these interceptors do is disable any nested interceptors.2240// These functions may open nss modules and call uninstrumented functions from2241// them, and we don't want things like strlen() to trigger.2242INTERCEPTOR(void, setpwent, int dummy) {2243 void *ctx;2244 COMMON_INTERCEPTOR_ENTER(ctx, setpwent, dummy);2245 REAL(setpwent)(dummy);2246}2247INTERCEPTOR(void, endpwent, int dummy) {2248 void *ctx;2249 COMMON_INTERCEPTOR_ENTER(ctx, endpwent, dummy);2250 REAL(endpwent)(dummy);2251}2252INTERCEPTOR(void, setgrent, int dummy) {2253 void *ctx;2254 COMMON_INTERCEPTOR_ENTER(ctx, setgrent, dummy);2255 REAL(setgrent)(dummy);2256}2257INTERCEPTOR(void, endgrent, int dummy) {2258 void *ctx;2259 COMMON_INTERCEPTOR_ENTER(ctx, endgrent, dummy);2260 REAL(endgrent)(dummy);2261}2262#define INIT_SETPWENT \2263 COMMON_INTERCEPT_FUNCTION(setpwent); \2264 COMMON_INTERCEPT_FUNCTION(endpwent); \2265 COMMON_INTERCEPT_FUNCTION(setgrent); \2266 COMMON_INTERCEPT_FUNCTION(endgrent);2267#else2268#define INIT_SETPWENT2269#endif2270 2271#if SANITIZER_INTERCEPT_CLOCK_GETTIME2272INTERCEPTOR(int, clock_getres, u32 clk_id, void *tp) {2273 void *ctx;2274 COMMON_INTERCEPTOR_ENTER(ctx, clock_getres, clk_id, tp);2275 // FIXME: under ASan the call below may write to freed memory and corrupt2276 // its metadata. See2277 // https://github.com/google/sanitizers/issues/321.2278 int res = REAL(clock_getres)(clk_id, tp);2279 if (!res && tp) {2280 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);2281 }2282 return res;2283}2284INTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) {2285 void *ctx;2286 COMMON_INTERCEPTOR_ENTER(ctx, clock_gettime, clk_id, tp);2287 // FIXME: under ASan the call below may write to freed memory and corrupt2288 // its metadata. See2289 // https://github.com/google/sanitizers/issues/321.2290 int res = REAL(clock_gettime)(clk_id, tp);2291 if (!res) {2292 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);2293 }2294 return res;2295}2296#if SANITIZER_GLIBC2297namespace __sanitizer {2298extern "C" {2299int real_clock_gettime(u32 clk_id, void *tp) {2300 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)2301 return internal_clock_gettime(clk_id, tp);2302 return REAL(clock_gettime)(clk_id, tp);2303}2304} // extern "C"2305} // namespace __sanitizer2306#endif2307INTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) {2308 void *ctx;2309 COMMON_INTERCEPTOR_ENTER(ctx, clock_settime, clk_id, tp);2310 COMMON_INTERCEPTOR_READ_RANGE(ctx, tp, struct_timespec_sz);2311 return REAL(clock_settime)(clk_id, tp);2312}2313#define INIT_CLOCK_GETTIME \2314 COMMON_INTERCEPT_FUNCTION(clock_getres); \2315 COMMON_INTERCEPT_FUNCTION(clock_gettime); \2316 COMMON_INTERCEPT_FUNCTION(clock_settime);2317#else2318#define INIT_CLOCK_GETTIME2319#endif2320 2321#if SANITIZER_INTERCEPT_CLOCK_GETCPUCLOCKID2322INTERCEPTOR(int, clock_getcpuclockid, pid_t pid,2323 __sanitizer_clockid_t *clockid) {2324 void *ctx;2325 COMMON_INTERCEPTOR_ENTER(ctx, clock_getcpuclockid, pid, clockid);2326 int res = REAL(clock_getcpuclockid)(pid, clockid);2327 if (!res && clockid) {2328 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, clockid, sizeof *clockid);2329 }2330 return res;2331}2332 2333INTERCEPTOR(int, pthread_getcpuclockid, uptr thread,2334 __sanitizer_clockid_t *clockid) {2335 void *ctx;2336 COMMON_INTERCEPTOR_ENTER(ctx, pthread_getcpuclockid, thread, clockid);2337 int res = REAL(pthread_getcpuclockid)(thread, clockid);2338 if (!res && clockid) {2339 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, clockid, sizeof *clockid);2340 }2341 return res;2342}2343 2344#define INIT_CLOCK_GETCPUCLOCKID \2345 COMMON_INTERCEPT_FUNCTION(clock_getcpuclockid); \2346 COMMON_INTERCEPT_FUNCTION(pthread_getcpuclockid);2347#else2348#define INIT_CLOCK_GETCPUCLOCKID2349#endif2350 2351#if SANITIZER_INTERCEPT_TIMER_CREATE2352INTERCEPTOR(int, timer_create, __sanitizer_clockid_t clockid, void *sevp,2353 __sanitizer_timer_t *timer) {2354 void *ctx;2355 COMMON_INTERCEPTOR_ENTER(ctx, timer_create, clockid, sevp, timer);2356 int res = REAL(timer_create)(clockid, sevp, timer);2357 if (!res && timer) {2358 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, timer, sizeof *timer);2359 }2360 return res;2361}2362 2363INTERCEPTOR(int, timer_delete, __sanitizer_timer_t timer) {2364 void *ctx;2365 COMMON_INTERCEPTOR_ENTER(ctx, timer_delete, timer);2366 int res = REAL(timer_delete)(timer);2367 return res;2368}2369 2370INTERCEPTOR(int, timer_gettime, __sanitizer_timer_t timer,2371 struct __sanitizer_itimerspec *curr_value) {2372 void *ctx;2373 COMMON_INTERCEPTOR_ENTER(ctx, timer_gettime, timer, curr_value);2374 int res = REAL(timer_gettime)(timer, curr_value);2375 if (!res && curr_value) {2376 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, sizeof *curr_value);2377 }2378 return res;2379}2380 2381INTERCEPTOR(int, timer_settime, __sanitizer_timer_t timer, int flags,2382 const struct __sanitizer_itimerspec *new_value,2383 struct __sanitizer_itimerspec *old_value) {2384 void *ctx;2385 COMMON_INTERCEPTOR_ENTER(ctx, timer_settime, timer, flags, new_value,2386 old_value);2387 int res = REAL(timer_settime)(timer, flags, new_value, old_value);2388 if (!res) {2389 if (new_value)2390 COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, sizeof *new_value);2391 if (old_value)2392 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, sizeof *old_value);2393 }2394 return res;2395}2396 2397# define INIT_TIMER_CREATE \2398 COMMON_INTERCEPT_FUNCTION_GLIBC_VER_MIN(timer_create, "GLIBC_2.3.3"); \2399 COMMON_INTERCEPT_FUNCTION_GLIBC_VER_MIN(timer_delete, "GLIBC_2.3.3"); \2400 COMMON_INTERCEPT_FUNCTION_GLIBC_VER_MIN(timer_gettime, "GLIBC_2.3.3"); \2401 COMMON_INTERCEPT_FUNCTION_GLIBC_VER_MIN(timer_settime, "GLIBC_2.3.3");2402#else2403# define INIT_TIMER_CREATE2404#endif2405 2406#if SANITIZER_INTERCEPT_GETITIMER2407INTERCEPTOR(int, getitimer, int which, void *curr_value) {2408 void *ctx;2409 COMMON_INTERCEPTOR_ENTER(ctx, getitimer, which, curr_value);2410 // FIXME: under ASan the call below may write to freed memory and corrupt2411 // its metadata. See2412 // https://github.com/google/sanitizers/issues/321.2413 int res = REAL(getitimer)(which, curr_value);2414 if (!res && curr_value) {2415 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerval_sz);2416 }2417 return res;2418}2419INTERCEPTOR(int, setitimer, int which, const void *new_value, void *old_value) {2420 void *ctx;2421 COMMON_INTERCEPTOR_ENTER(ctx, setitimer, which, new_value, old_value);2422 if (new_value) {2423 // itimerval can contain padding that may be legitimately uninitialized2424 const struct __sanitizer_itimerval *nv =2425 (const struct __sanitizer_itimerval *)new_value;2426 COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_interval.tv_sec,2427 sizeof(__sanitizer_time_t));2428 COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_interval.tv_usec,2429 sizeof(__sanitizer_suseconds_t));2430 COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_value.tv_sec,2431 sizeof(__sanitizer_time_t));2432 COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_value.tv_usec,2433 sizeof(__sanitizer_suseconds_t));2434 }2435 // FIXME: under ASan the call below may write to freed memory and corrupt2436 // its metadata. See2437 // https://github.com/google/sanitizers/issues/321.2438 int res = REAL(setitimer)(which, new_value, old_value);2439 if (!res && old_value) {2440 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerval_sz);2441 }2442 return res;2443}2444#define INIT_GETITIMER \2445 COMMON_INTERCEPT_FUNCTION(getitimer); \2446 COMMON_INTERCEPT_FUNCTION(setitimer);2447#else2448#define INIT_GETITIMER2449#endif2450 2451#if SANITIZER_INTERCEPT_TIMESPEC_GET2452INTERCEPTOR(int, timespec_get, struct __sanitizer_timespec *ts, int base) {2453 void *ctx;2454 COMMON_INTERCEPTOR_ENTER(ctx, timespec_get, ts, base);2455 // We don't yet know if ts is addressable, so we use our own scratch buffer2456 struct __sanitizer_timespec ts_local;2457 int res = REAL(timespec_get)(&ts_local, base);2458 if (res) {2459 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ts,2460 sizeof(struct __sanitizer_timespec));2461 internal_memcpy(ts, &ts_local, sizeof(struct __sanitizer_timespec));2462 }2463 return res;2464}2465# define INIT_TIMESPEC_GET COMMON_INTERCEPT_FUNCTION(timespec_get);2466#else2467# define INIT_TIMESPEC_GET2468#endif2469 2470#if SANITIZER_INTERCEPT_GLOB2471static void unpoison_glob_t(void *ctx, __sanitizer_glob_t *pglob) {2472 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob));2473 // +1 for NULL pointer at the end.2474 if (pglob->gl_pathv)2475 COMMON_INTERCEPTOR_WRITE_RANGE(2476 ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv));2477 for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) {2478 char *p = pglob->gl_pathv[i];2479 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, internal_strlen(p) + 1);2480 }2481}2482 2483#if SANITIZER_SOLARIS2484INTERCEPTOR(int, glob, const char *pattern, int flags,2485 int (*errfunc)(const char *epath, int eerrno),2486 __sanitizer_glob_t *pglob) {2487 void *ctx;2488 COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob);2489 COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0);2490 int res = REAL(glob)(pattern, flags, errfunc, pglob);2491 if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);2492 return res;2493}2494#else2495static THREADLOCAL __sanitizer_glob_t *pglob_copy;2496 2497static void wrapped_gl_closedir(void *dir) {2498 COMMON_INTERCEPTOR_UNPOISON_PARAM(1);2499 pglob_copy->gl_closedir(dir);2500}2501 2502static void *wrapped_gl_readdir(void *dir) {2503 COMMON_INTERCEPTOR_UNPOISON_PARAM(1);2504 return pglob_copy->gl_readdir(dir);2505}2506 2507static void *wrapped_gl_opendir(const char *s) {2508 COMMON_INTERCEPTOR_UNPOISON_PARAM(1);2509 COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, internal_strlen(s) + 1);2510 return pglob_copy->gl_opendir(s);2511}2512 2513static int wrapped_gl_lstat(const char *s, void *st) {2514 COMMON_INTERCEPTOR_UNPOISON_PARAM(2);2515 COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, internal_strlen(s) + 1);2516 return pglob_copy->gl_lstat(s, st);2517}2518 2519static int wrapped_gl_stat(const char *s, void *st) {2520 COMMON_INTERCEPTOR_UNPOISON_PARAM(2);2521 COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, internal_strlen(s) + 1);2522 return pglob_copy->gl_stat(s, st);2523}2524 2525static const __sanitizer_glob_t kGlobCopy = {2526 0, 0, 0,2527 0, wrapped_gl_closedir, wrapped_gl_readdir,2528 wrapped_gl_opendir, wrapped_gl_lstat, wrapped_gl_stat};2529 2530INTERCEPTOR(int, glob, const char *pattern, int flags,2531 int (*errfunc)(const char *epath, int eerrno),2532 __sanitizer_glob_t *pglob) {2533 void *ctx;2534 COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob);2535 COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0);2536 __sanitizer_glob_t glob_copy;2537 internal_memcpy(&glob_copy, &kGlobCopy, sizeof(glob_copy));2538 if (flags & glob_altdirfunc) {2539 Swap(pglob->gl_closedir, glob_copy.gl_closedir);2540 Swap(pglob->gl_readdir, glob_copy.gl_readdir);2541 Swap(pglob->gl_opendir, glob_copy.gl_opendir);2542 Swap(pglob->gl_lstat, glob_copy.gl_lstat);2543 Swap(pglob->gl_stat, glob_copy.gl_stat);2544 pglob_copy = &glob_copy;2545 }2546 int res = REAL(glob)(pattern, flags, errfunc, pglob);2547 if (flags & glob_altdirfunc) {2548 Swap(pglob->gl_closedir, glob_copy.gl_closedir);2549 Swap(pglob->gl_readdir, glob_copy.gl_readdir);2550 Swap(pglob->gl_opendir, glob_copy.gl_opendir);2551 Swap(pglob->gl_lstat, glob_copy.gl_lstat);2552 Swap(pglob->gl_stat, glob_copy.gl_stat);2553 }2554 pglob_copy = 0;2555 if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);2556 return res;2557}2558#endif // SANITIZER_SOLARIS2559#define INIT_GLOB \2560 COMMON_INTERCEPT_FUNCTION(glob);2561#else // SANITIZER_INTERCEPT_GLOB2562#define INIT_GLOB2563#endif // SANITIZER_INTERCEPT_GLOB2564 2565#if SANITIZER_INTERCEPT_GLOB642566INTERCEPTOR(int, glob64, const char *pattern, int flags,2567 int (*errfunc)(const char *epath, int eerrno),2568 __sanitizer_glob_t *pglob) {2569 void *ctx;2570 COMMON_INTERCEPTOR_ENTER(ctx, glob64, pattern, flags, errfunc, pglob);2571 COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0);2572 __sanitizer_glob_t glob_copy;2573 internal_memcpy(&glob_copy, &kGlobCopy, sizeof(glob_copy));2574 if (flags & glob_altdirfunc) {2575 Swap(pglob->gl_closedir, glob_copy.gl_closedir);2576 Swap(pglob->gl_readdir, glob_copy.gl_readdir);2577 Swap(pglob->gl_opendir, glob_copy.gl_opendir);2578 Swap(pglob->gl_lstat, glob_copy.gl_lstat);2579 Swap(pglob->gl_stat, glob_copy.gl_stat);2580 pglob_copy = &glob_copy;2581 }2582 int res = REAL(glob64)(pattern, flags, errfunc, pglob);2583 if (flags & glob_altdirfunc) {2584 Swap(pglob->gl_closedir, glob_copy.gl_closedir);2585 Swap(pglob->gl_readdir, glob_copy.gl_readdir);2586 Swap(pglob->gl_opendir, glob_copy.gl_opendir);2587 Swap(pglob->gl_lstat, glob_copy.gl_lstat);2588 Swap(pglob->gl_stat, glob_copy.gl_stat);2589 }2590 pglob_copy = 0;2591 if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);2592 return res;2593}2594#define INIT_GLOB64 \2595 COMMON_INTERCEPT_FUNCTION(glob64);2596#else // SANITIZER_INTERCEPT_GLOB642597#define INIT_GLOB642598#endif // SANITIZER_INTERCEPT_GLOB642599 2600#if SANITIZER_INTERCEPT___B64_TO2601INTERCEPTOR(int, __b64_ntop, unsigned char const *src, SIZE_T srclength,2602 char *target, SIZE_T targsize) {2603 void *ctx;2604 COMMON_INTERCEPTOR_ENTER(ctx, __b64_ntop, src, srclength, target, targsize);2605 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, srclength);2606 int res = REAL(__b64_ntop)(src, srclength, target, targsize);2607 if (res >= 0)2608 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, target, res + 1);2609 return res;2610}2611INTERCEPTOR(int, __b64_pton, char const *src, char *target, SIZE_T targsize) {2612 void *ctx;2613 COMMON_INTERCEPTOR_ENTER(ctx, __b64_pton, src, target, targsize);2614 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);2615 int res = REAL(__b64_pton)(src, target, targsize);2616 if (res >= 0)2617 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, target, res);2618 return res;2619}2620#define INIT___B64_TO \2621 COMMON_INTERCEPT_FUNCTION(__b64_ntop); \2622 COMMON_INTERCEPT_FUNCTION(__b64_pton);2623#else // SANITIZER_INTERCEPT___B64_TO2624#define INIT___B64_TO2625#endif // SANITIZER_INTERCEPT___B64_TO2626 2627#if SANITIZER_INTERCEPT_DN_COMP_EXPAND2628# if __GLIBC_PREREQ(2, 34)2629// Changed with https://sourceware.org/git/?p=glibc.git;h=640bbdf2630# define DN_COMP_INTERCEPTOR_NAME dn_comp2631# define DN_EXPAND_INTERCEPTOR_NAME dn_expand2632# else2633# define DN_COMP_INTERCEPTOR_NAME __dn_comp2634# define DN_EXPAND_INTERCEPTOR_NAME __dn_expand2635# endif2636INTERCEPTOR(int, DN_COMP_INTERCEPTOR_NAME, unsigned char *exp_dn,2637 unsigned char *comp_dn, int length, unsigned char **dnptrs,2638 unsigned char **lastdnptr) {2639 void *ctx;2640 COMMON_INTERCEPTOR_ENTER(ctx, DN_COMP_INTERCEPTOR_NAME, exp_dn, comp_dn,2641 length, dnptrs, lastdnptr);2642 int res = REAL(DN_COMP_INTERCEPTOR_NAME)(exp_dn, comp_dn, length, dnptrs,2643 lastdnptr);2644 if (res >= 0) {2645 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, comp_dn, res);2646 if (dnptrs && lastdnptr) {2647 unsigned char **p = dnptrs;2648 for (; p != lastdnptr && *p; ++p)2649 ;2650 if (p != lastdnptr)2651 ++p;2652 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dnptrs, (p - dnptrs) * sizeof(*p));2653 }2654 }2655 return res;2656}2657INTERCEPTOR(int, DN_EXPAND_INTERCEPTOR_NAME, unsigned char const *base,2658 unsigned char const *end, unsigned char const *src, char *dest,2659 int space) {2660 void *ctx;2661 COMMON_INTERCEPTOR_ENTER(ctx, DN_EXPAND_INTERCEPTOR_NAME, base, end, src,2662 dest, space);2663 // TODO: add read check if __dn_comp intercept added2664 int res = REAL(DN_EXPAND_INTERCEPTOR_NAME)(base, end, src, dest, space);2665 if (res >= 0)2666 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, internal_strlen(dest) + 1);2667 return res;2668}2669# define INIT_DN_COMP_EXPAND \2670 COMMON_INTERCEPT_FUNCTION(DN_COMP_INTERCEPTOR_NAME); \2671 COMMON_INTERCEPT_FUNCTION(DN_EXPAND_INTERCEPTOR_NAME);2672#else // SANITIZER_INTERCEPT_DN_COMP_EXPAND2673# define INIT_DN_COMP_EXPAND2674#endif // SANITIZER_INTERCEPT_DN_COMP_EXPAND2675 2676#if SANITIZER_INTERCEPT_POSIX_SPAWN2677 2678template <class RealSpawnPtr>2679static int PosixSpawnImpl(void *ctx, RealSpawnPtr *real_posix_spawn, pid_t *pid,2680 const char *file_or_path, const void *file_actions,2681 const void *attrp, char *const argv[],2682 char *const envp[]) {2683 COMMON_INTERCEPTOR_READ_RANGE(ctx, file_or_path,2684 internal_strlen(file_or_path) + 1);2685 if (argv) {2686 for (char *const *s = argv; ; ++s) {2687 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, sizeof(*s));2688 if (!*s) break;2689 COMMON_INTERCEPTOR_READ_RANGE(ctx, *s, internal_strlen(*s) + 1);2690 }2691 }2692 if (envp) {2693 for (char *const *s = envp; ; ++s) {2694 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, sizeof(*s));2695 if (!*s) break;2696 COMMON_INTERCEPTOR_READ_RANGE(ctx, *s, internal_strlen(*s) + 1);2697 }2698 }2699 int res =2700 real_posix_spawn(pid, file_or_path, file_actions, attrp, argv, envp);2701 if (res == 0)2702 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pid, sizeof(*pid));2703 return res;2704}2705INTERCEPTOR(int, posix_spawn, pid_t *pid, const char *path,2706 const void *file_actions, const void *attrp, char *const argv[],2707 char *const envp[]) {2708 void *ctx;2709 COMMON_INTERCEPTOR_ENTER(ctx, posix_spawn, pid, path, file_actions, attrp,2710 argv, envp);2711 return PosixSpawnImpl(ctx, REAL(posix_spawn), pid, path, file_actions, attrp,2712 argv, envp);2713}2714INTERCEPTOR(int, posix_spawnp, pid_t *pid, const char *file,2715 const void *file_actions, const void *attrp, char *const argv[],2716 char *const envp[]) {2717 void *ctx;2718 COMMON_INTERCEPTOR_ENTER(ctx, posix_spawnp, pid, file, file_actions, attrp,2719 argv, envp);2720 return PosixSpawnImpl(ctx, REAL(posix_spawnp), pid, file, file_actions, attrp,2721 argv, envp);2722}2723# define INIT_POSIX_SPAWN \2724 COMMON_INTERCEPT_FUNCTION(posix_spawn); \2725 COMMON_INTERCEPT_FUNCTION(posix_spawnp);2726#else // SANITIZER_INTERCEPT_POSIX_SPAWN2727# define INIT_POSIX_SPAWN2728#endif // SANITIZER_INTERCEPT_POSIX_SPAWN2729 2730#if SANITIZER_INTERCEPT_WAIT2731// According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version2732// suffixes on Darwin. See the declaration of INTERCEPTOR_WITH_SUFFIX for2733// details.2734INTERCEPTOR_WITH_SUFFIX(int, wait, int *status) {2735 void *ctx;2736 COMMON_INTERCEPTOR_ENTER(ctx, wait, status);2737 // FIXME: under ASan the call below may write to freed memory and corrupt2738 // its metadata. See2739 // https://github.com/google/sanitizers/issues/321.2740 int res = COMMON_INTERCEPTOR_BLOCK_REAL(wait)(status);2741 if (res != -1 && status)2742 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));2743 return res;2744}2745// On FreeBSD id_t is always 64-bit wide.2746#if SANITIZER_FREEBSD && (SANITIZER_WORDSIZE == 32)2747INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, long long id, void *infop,2748 int options) {2749#else2750INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, int id, void *infop,2751 int options) {2752#endif2753 void *ctx;2754 COMMON_INTERCEPTOR_ENTER(ctx, waitid, idtype, id, infop, options);2755 // FIXME: under ASan the call below may write to freed memory and corrupt2756 // its metadata. See2757 // https://github.com/google/sanitizers/issues/321.2758 int res = COMMON_INTERCEPTOR_BLOCK_REAL(waitid)(idtype, id, infop, options);2759 if (res != -1 && infop)2760 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, infop, siginfo_t_sz);2761 return res;2762}2763INTERCEPTOR_WITH_SUFFIX(int, waitpid, int pid, int *status, int options) {2764 void *ctx;2765 COMMON_INTERCEPTOR_ENTER(ctx, waitpid, pid, status, options);2766 // FIXME: under ASan the call below may write to freed memory and corrupt2767 // its metadata. See2768 // https://github.com/google/sanitizers/issues/321.2769 int res = COMMON_INTERCEPTOR_BLOCK_REAL(waitpid)(pid, status, options);2770 if (res != -1 && status)2771 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));2772 return res;2773}2774INTERCEPTOR(int, wait3, int *status, int options, void *rusage) {2775 void *ctx;2776 COMMON_INTERCEPTOR_ENTER(ctx, wait3, status, options, rusage);2777 // FIXME: under ASan the call below may write to freed memory and corrupt2778 // its metadata. See2779 // https://github.com/google/sanitizers/issues/321.2780 int res = COMMON_INTERCEPTOR_BLOCK_REAL(wait3)(status, options, rusage);2781 if (res != -1) {2782 if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));2783 if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);2784 }2785 return res;2786}2787#if SANITIZER_ANDROID2788INTERCEPTOR(int, __wait4, int pid, int *status, int options, void *rusage) {2789 void *ctx;2790 COMMON_INTERCEPTOR_ENTER(ctx, __wait4, pid, status, options, rusage);2791 // FIXME: under ASan the call below may write to freed memory and corrupt2792 // its metadata. See2793 // https://github.com/google/sanitizers/issues/321.2794 int res =2795 COMMON_INTERCEPTOR_BLOCK_REAL(__wait4)(pid, status, options, rusage);2796 if (res != -1) {2797 if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));2798 if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);2799 }2800 return res;2801}2802#define INIT_WAIT4 COMMON_INTERCEPT_FUNCTION(__wait4);2803#else2804INTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) {2805 void *ctx;2806 COMMON_INTERCEPTOR_ENTER(ctx, wait4, pid, status, options, rusage);2807 // FIXME: under ASan the call below may write to freed memory and corrupt2808 // its metadata. See2809 // https://github.com/google/sanitizers/issues/321.2810 int res = COMMON_INTERCEPTOR_BLOCK_REAL(wait4)(pid, status, options, rusage);2811 if (res != -1) {2812 if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));2813 if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);2814 }2815 return res;2816}2817#define INIT_WAIT4 COMMON_INTERCEPT_FUNCTION(wait4);2818#endif // SANITIZER_ANDROID2819#define INIT_WAIT \2820 COMMON_INTERCEPT_FUNCTION(wait); \2821 COMMON_INTERCEPT_FUNCTION(waitid); \2822 COMMON_INTERCEPT_FUNCTION(waitpid); \2823 COMMON_INTERCEPT_FUNCTION(wait3);2824#else2825#define INIT_WAIT2826#define INIT_WAIT42827#endif2828 2829#if SANITIZER_INTERCEPT_INET2830INTERCEPTOR(char *, inet_ntop, int af, const void *src, char *dst, u32 size) {2831 void *ctx;2832 COMMON_INTERCEPTOR_ENTER(ctx, inet_ntop, af, src, dst, size);2833 uptr sz = __sanitizer_in_addr_sz(af);2834 if (sz) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sz);2835 // FIXME: figure out read size based on the address family.2836 // FIXME: under ASan the call below may write to freed memory and corrupt2837 // its metadata. See2838 // https://github.com/google/sanitizers/issues/321.2839 char *res = REAL(inet_ntop)(af, src, dst, size);2840 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);2841 return res;2842}2843INTERCEPTOR(int, inet_pton, int af, const char *src, void *dst) {2844 void *ctx;2845 COMMON_INTERCEPTOR_ENTER(ctx, inet_pton, af, src, dst);2846 COMMON_INTERCEPTOR_READ_STRING(ctx, src, 0);2847 // FIXME: figure out read size based on the address family.2848 // FIXME: under ASan the call below may write to freed memory and corrupt2849 // its metadata. See2850 // https://github.com/google/sanitizers/issues/321.2851 int res = REAL(inet_pton)(af, src, dst);2852 if (res == 1) {2853 uptr sz = __sanitizer_in_addr_sz(af);2854 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);2855 }2856 return res;2857}2858#define INIT_INET \2859 COMMON_INTERCEPT_FUNCTION(inet_ntop); \2860 COMMON_INTERCEPT_FUNCTION(inet_pton);2861#else2862#define INIT_INET2863#endif2864 2865#if SANITIZER_INTERCEPT_INET2866INTERCEPTOR(int, inet_aton, const char *cp, void *dst) {2867 void *ctx;2868 COMMON_INTERCEPTOR_ENTER(ctx, inet_aton, cp, dst);2869 if (cp) COMMON_INTERCEPTOR_READ_RANGE(ctx, cp, internal_strlen(cp) + 1);2870 // FIXME: under ASan the call below may write to freed memory and corrupt2871 // its metadata. See2872 // https://github.com/google/sanitizers/issues/321.2873 int res = REAL(inet_aton)(cp, dst);2874 if (res != 0) {2875 uptr sz = __sanitizer_in_addr_sz(af_inet);2876 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);2877 }2878 return res;2879}2880#define INIT_INET_ATON COMMON_INTERCEPT_FUNCTION(inet_aton);2881#else2882#define INIT_INET_ATON2883#endif2884 2885#if SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM2886INTERCEPTOR(int, pthread_getschedparam, uptr thread, int *policy, int *param) {2887 void *ctx;2888 COMMON_INTERCEPTOR_ENTER(ctx, pthread_getschedparam, thread, policy, param);2889 // FIXME: under ASan the call below may write to freed memory and corrupt2890 // its metadata. See2891 // https://github.com/google/sanitizers/issues/321.2892 int res = REAL(pthread_getschedparam)(thread, policy, param);2893 if (res == 0) {2894 if (policy) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, policy, sizeof(*policy));2895 if (param) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, sizeof(*param));2896 }2897 return res;2898}2899#define INIT_PTHREAD_GETSCHEDPARAM \2900 COMMON_INTERCEPT_FUNCTION(pthread_getschedparam);2901#else2902#define INIT_PTHREAD_GETSCHEDPARAM2903#endif2904 2905#if SANITIZER_INTERCEPT_GETADDRINFO2906INTERCEPTOR(int, getaddrinfo, char *node, char *service,2907 struct __sanitizer_addrinfo *hints,2908 struct __sanitizer_addrinfo **out) {2909 void *ctx;2910 COMMON_INTERCEPTOR_ENTER(ctx, getaddrinfo, node, service, hints, out);2911 if (node) COMMON_INTERCEPTOR_READ_RANGE(ctx, node, internal_strlen(node) + 1);2912 if (service)2913 COMMON_INTERCEPTOR_READ_RANGE(ctx, service, internal_strlen(service) + 1);2914 if (hints)2915 COMMON_INTERCEPTOR_READ_RANGE(ctx, hints, sizeof(__sanitizer_addrinfo));2916 // FIXME: under ASan the call below may write to freed memory and corrupt2917 // its metadata. See2918 // https://github.com/google/sanitizers/issues/321.2919 int res = REAL(getaddrinfo)(node, service, hints, out);2920 if (res == 0 && out) {2921 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, out, sizeof(*out));2922 struct __sanitizer_addrinfo *p = *out;2923 while (p) {2924 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));2925 if (p->ai_addr)2926 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_addr, p->ai_addrlen);2927 if (p->ai_canonname)2928 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_canonname,2929 internal_strlen(p->ai_canonname) + 1);2930 p = p->ai_next;2931 }2932 }2933 return res;2934}2935#define INIT_GETADDRINFO COMMON_INTERCEPT_FUNCTION(getaddrinfo);2936#else2937#define INIT_GETADDRINFO2938#endif2939 2940#if SANITIZER_INTERCEPT_GETNAMEINFO2941INTERCEPTOR(int, getnameinfo, void *sockaddr, unsigned salen, char *host,2942 unsigned hostlen, char *serv, unsigned servlen, int flags) {2943 void *ctx;2944 COMMON_INTERCEPTOR_ENTER(ctx, getnameinfo, sockaddr, salen, host, hostlen,2945 serv, servlen, flags);2946 // FIXME: consider adding READ_RANGE(sockaddr, salen)2947 // There is padding in in_addr that may make this too noisy2948 // FIXME: under ASan the call below may write to freed memory and corrupt2949 // its metadata. See2950 // https://github.com/google/sanitizers/issues/321.2951 int res =2952 REAL(getnameinfo)(sockaddr, salen, host, hostlen, serv, servlen, flags);2953 if (res == 0) {2954 if (host && hostlen)2955 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, host, internal_strlen(host) + 1);2956 if (serv && servlen)2957 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, serv, internal_strlen(serv) + 1);2958 }2959 return res;2960}2961#define INIT_GETNAMEINFO COMMON_INTERCEPT_FUNCTION(getnameinfo);2962#else2963#define INIT_GETNAMEINFO2964#endif2965 2966#if SANITIZER_INTERCEPT_GETSOCKNAME2967INTERCEPTOR(int, getsockname, int sock_fd, void *addr, unsigned *addrlen) {2968 void *ctx;2969 COMMON_INTERCEPTOR_ENTER(ctx, getsockname, sock_fd, addr, addrlen);2970 unsigned addr_sz;2971 if (addrlen) {2972 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));2973 addr_sz = *addrlen;2974 }2975 // FIXME: under ASan the call below may write to freed memory and corrupt2976 // its metadata. See2977 // https://github.com/google/sanitizers/issues/321.2978 int res = REAL(getsockname)(sock_fd, addr, addrlen);2979 if (!res && addr && addrlen) {2980 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen));2981 }2982 return res;2983}2984#define INIT_GETSOCKNAME COMMON_INTERCEPT_FUNCTION(getsockname);2985#else2986#define INIT_GETSOCKNAME2987#endif2988 2989#if SANITIZER_INTERCEPT_GETHOSTBYNAME || SANITIZER_INTERCEPT_GETHOSTBYNAME_R2990static void write_hostent(void *ctx, struct __sanitizer_hostent *h) {2991 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h, sizeof(__sanitizer_hostent));2992 if (h->h_name)2993 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h->h_name, internal_strlen(h->h_name) + 1);2994 char **p = h->h_aliases;2995 while (*p) {2996 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, internal_strlen(*p) + 1);2997 ++p;2998 }2999 COMMON_INTERCEPTOR_WRITE_RANGE(3000 ctx, h->h_aliases, (p - h->h_aliases + 1) * sizeof(*h->h_aliases));3001 p = h->h_addr_list;3002 while (*p) {3003 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, h->h_length);3004 ++p;3005 }3006 COMMON_INTERCEPTOR_WRITE_RANGE(3007 ctx, h->h_addr_list, (p - h->h_addr_list + 1) * sizeof(*h->h_addr_list));3008}3009#endif3010 3011#if SANITIZER_INTERCEPT_GETHOSTBYNAME3012INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname, char *name) {3013 void *ctx;3014 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname, name);3015 struct __sanitizer_hostent *res = REAL(gethostbyname)(name);3016 if (res) write_hostent(ctx, res);3017 return res;3018}3019 3020INTERCEPTOR(struct __sanitizer_hostent *, gethostbyaddr, void *addr, int len,3021 int type) {3022 void *ctx;3023 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr, addr, len, type);3024 COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);3025 struct __sanitizer_hostent *res = REAL(gethostbyaddr)(addr, len, type);3026 if (res) write_hostent(ctx, res);3027 return res;3028}3029 3030INTERCEPTOR(struct __sanitizer_hostent *, gethostent, int fake) {3031 void *ctx;3032 COMMON_INTERCEPTOR_ENTER(ctx, gethostent, fake);3033 struct __sanitizer_hostent *res = REAL(gethostent)(fake);3034 if (res) write_hostent(ctx, res);3035 return res;3036}3037#define INIT_GETHOSTBYNAME \3038 COMMON_INTERCEPT_FUNCTION(gethostent); \3039 COMMON_INTERCEPT_FUNCTION(gethostbyaddr); \3040 COMMON_INTERCEPT_FUNCTION(gethostbyname);3041#else3042#define INIT_GETHOSTBYNAME3043#endif // SANITIZER_INTERCEPT_GETHOSTBYNAME3044 3045#if SANITIZER_INTERCEPT_GETHOSTBYNAME23046INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname2, char *name, int af) {3047 void *ctx;3048 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2, name, af);3049 struct __sanitizer_hostent *res = REAL(gethostbyname2)(name, af);3050 if (res) write_hostent(ctx, res);3051 return res;3052}3053#define INIT_GETHOSTBYNAME2 COMMON_INTERCEPT_FUNCTION(gethostbyname2);3054#else3055#define INIT_GETHOSTBYNAME23056#endif // SANITIZER_INTERCEPT_GETHOSTBYNAME23057 3058#if SANITIZER_INTERCEPT_GETHOSTBYNAME_R3059INTERCEPTOR(int, gethostbyname_r, char *name, struct __sanitizer_hostent *ret,3060 char *buf, SIZE_T buflen, __sanitizer_hostent **result,3061 int *h_errnop) {3062 void *ctx;3063 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname_r, name, ret, buf, buflen, result,3064 h_errnop);3065 // FIXME: under ASan the call below may write to freed memory and corrupt3066 // its metadata. See3067 // https://github.com/google/sanitizers/issues/321.3068 int res = REAL(gethostbyname_r)(name, ret, buf, buflen, result, h_errnop);3069 if (result) {3070 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));3071 if (res == 0 && *result) write_hostent(ctx, *result);3072 }3073 if (h_errnop)3074 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));3075 return res;3076}3077#define INIT_GETHOSTBYNAME_R COMMON_INTERCEPT_FUNCTION(gethostbyname_r);3078#else3079#define INIT_GETHOSTBYNAME_R3080#endif3081 3082#if SANITIZER_INTERCEPT_GETHOSTENT_R3083INTERCEPTOR(int, gethostent_r, struct __sanitizer_hostent *ret, char *buf,3084 SIZE_T buflen, __sanitizer_hostent **result, int *h_errnop) {3085 void *ctx;3086 COMMON_INTERCEPTOR_ENTER(ctx, gethostent_r, ret, buf, buflen, result,3087 h_errnop);3088 // FIXME: under ASan the call below may write to freed memory and corrupt3089 // its metadata. See3090 // https://github.com/google/sanitizers/issues/321.3091 int res = REAL(gethostent_r)(ret, buf, buflen, result, h_errnop);3092 if (result) {3093 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));3094 if (res == 0 && *result) write_hostent(ctx, *result);3095 }3096 if (h_errnop)3097 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));3098 return res;3099}3100#define INIT_GETHOSTENT_R \3101 COMMON_INTERCEPT_FUNCTION(gethostent_r);3102#else3103#define INIT_GETHOSTENT_R3104#endif3105 3106#if SANITIZER_INTERCEPT_GETHOSTBYADDR_R3107INTERCEPTOR(int, gethostbyaddr_r, void *addr, int len, int type,3108 struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,3109 __sanitizer_hostent **result, int *h_errnop) {3110 void *ctx;3111 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr_r, addr, len, type, ret, buf,3112 buflen, result, h_errnop);3113 COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);3114 // FIXME: under ASan the call below may write to freed memory and corrupt3115 // its metadata. See3116 // https://github.com/google/sanitizers/issues/321.3117 int res = REAL(gethostbyaddr_r)(addr, len, type, ret, buf, buflen, result,3118 h_errnop);3119 if (result) {3120 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));3121 if (res == 0 && *result) write_hostent(ctx, *result);3122 }3123 if (h_errnop)3124 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));3125 return res;3126}3127#define INIT_GETHOSTBYADDR_R \3128 COMMON_INTERCEPT_FUNCTION(gethostbyaddr_r);3129#else3130#define INIT_GETHOSTBYADDR_R3131#endif3132 3133#if SANITIZER_INTERCEPT_GETHOSTBYNAME2_R3134INTERCEPTOR(int, gethostbyname2_r, char *name, int af,3135 struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,3136 __sanitizer_hostent **result, int *h_errnop) {3137 void *ctx;3138 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2_r, name, af, ret, buf, buflen,3139 result, h_errnop);3140 // FIXME: under ASan the call below may write to freed memory and corrupt3141 // its metadata. See3142 // https://github.com/google/sanitizers/issues/321.3143 int res =3144 REAL(gethostbyname2_r)(name, af, ret, buf, buflen, result, h_errnop);3145 if (result) {3146 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));3147 if (res == 0 && *result) write_hostent(ctx, *result);3148 }3149 if (h_errnop)3150 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));3151 return res;3152}3153#define INIT_GETHOSTBYNAME2_R \3154 COMMON_INTERCEPT_FUNCTION(gethostbyname2_r);3155#else3156#define INIT_GETHOSTBYNAME2_R3157#endif3158 3159#if SANITIZER_INTERCEPT_GETSOCKOPT3160INTERCEPTOR(int, getsockopt, int sockfd, int level, int optname, void *optval,3161 int *optlen) {3162 void *ctx;3163 COMMON_INTERCEPTOR_ENTER(ctx, getsockopt, sockfd, level, optname, optval,3164 optlen);3165 if (optlen) COMMON_INTERCEPTOR_READ_RANGE(ctx, optlen, sizeof(*optlen));3166 // FIXME: under ASan the call below may write to freed memory and corrupt3167 // its metadata. See3168 // https://github.com/google/sanitizers/issues/321.3169 int res = REAL(getsockopt)(sockfd, level, optname, optval, optlen);3170 if (res == 0)3171 if (optval && optlen) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, optval, *optlen);3172 return res;3173}3174#define INIT_GETSOCKOPT COMMON_INTERCEPT_FUNCTION(getsockopt);3175#else3176#define INIT_GETSOCKOPT3177#endif3178 3179#if SANITIZER_INTERCEPT_ACCEPT3180INTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) {3181 void *ctx;3182 COMMON_INTERCEPTOR_ENTER(ctx, accept, fd, addr, addrlen);3183 unsigned addrlen0 = 0;3184 if (addrlen) {3185 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));3186 addrlen0 = *addrlen;3187 }3188 int fd2 = COMMON_INTERCEPTOR_BLOCK_REAL(accept)(fd, addr, addrlen);3189 if (fd2 >= 0) {3190 if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);3191 if (addr && addrlen)3192 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));3193 }3194 return fd2;3195}3196#define INIT_ACCEPT COMMON_INTERCEPT_FUNCTION(accept);3197#else3198#define INIT_ACCEPT3199#endif3200 3201#if SANITIZER_INTERCEPT_ACCEPT43202INTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) {3203 void *ctx;3204 COMMON_INTERCEPTOR_ENTER(ctx, accept4, fd, addr, addrlen, f);3205 unsigned addrlen0 = 0;3206 if (addrlen) {3207 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));3208 addrlen0 = *addrlen;3209 }3210 // FIXME: under ASan the call below may write to freed memory and corrupt3211 // its metadata. See3212 // https://github.com/google/sanitizers/issues/321.3213 int fd2 = COMMON_INTERCEPTOR_BLOCK_REAL(accept4)(fd, addr, addrlen, f);3214 if (fd2 >= 0) {3215 if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);3216 if (addr && addrlen)3217 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));3218 }3219 return fd2;3220}3221#define INIT_ACCEPT4 COMMON_INTERCEPT_FUNCTION(accept4);3222#else3223#define INIT_ACCEPT43224#endif3225 3226#if SANITIZER_INTERCEPT_PACCEPT3227INTERCEPTOR(int, paccept, int fd, void *addr, unsigned *addrlen,3228 __sanitizer_sigset_t *set, int f) {3229 void *ctx;3230 COMMON_INTERCEPTOR_ENTER(ctx, paccept, fd, addr, addrlen, set, f);3231 unsigned addrlen0 = 0;3232 if (addrlen) {3233 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));3234 addrlen0 = *addrlen;3235 }3236 if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));3237 int fd2 = COMMON_INTERCEPTOR_BLOCK_REAL(paccept)(fd, addr, addrlen, set, f);3238 if (fd2 >= 0) {3239 if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);3240 if (addr && addrlen)3241 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));3242 }3243 return fd2;3244}3245#define INIT_PACCEPT COMMON_INTERCEPT_FUNCTION(paccept);3246#else3247#define INIT_PACCEPT3248#endif3249 3250#if SANITIZER_INTERCEPT_MODF3251INTERCEPTOR(double, modf, double x, double *iptr) {3252 void *ctx;3253 COMMON_INTERCEPTOR_ENTER(ctx, modf, x, iptr);3254 // FIXME: under ASan the call below may write to freed memory and corrupt3255 // its metadata. See3256 // https://github.com/google/sanitizers/issues/321.3257 double res = REAL(modf)(x, iptr);3258 if (iptr) {3259 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));3260 }3261 return res;3262}3263INTERCEPTOR(float, modff, float x, float *iptr) {3264 void *ctx;3265 COMMON_INTERCEPTOR_ENTER(ctx, modff, x, iptr);3266 // FIXME: under ASan the call below may write to freed memory and corrupt3267 // its metadata. See3268 // https://github.com/google/sanitizers/issues/321.3269 float res = REAL(modff)(x, iptr);3270 if (iptr) {3271 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));3272 }3273 return res;3274}3275INTERCEPTOR(long double, modfl, long double x, long double *iptr) {3276 void *ctx;3277 COMMON_INTERCEPTOR_ENTER(ctx, modfl, x, iptr);3278 // FIXME: under ASan the call below may write to freed memory and corrupt3279 // its metadata. See3280 // https://github.com/google/sanitizers/issues/321.3281 long double res = REAL(modfl)(x, iptr);3282 if (iptr) {3283 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));3284 }3285 return res;3286}3287#define INIT_MODF \3288 COMMON_INTERCEPT_FUNCTION(modf); \3289 COMMON_INTERCEPT_FUNCTION(modff); \3290 COMMON_INTERCEPT_FUNCTION_LDBL(modfl);3291#else3292#define INIT_MODF3293#endif3294 3295#if SANITIZER_INTERCEPT_RECVMSG || SANITIZER_INTERCEPT_RECVMMSG3296static void write_msghdr(void *ctx, struct __sanitizer_msghdr *msg,3297 SSIZE_T maxlen) {3298 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg, sizeof(*msg));3299 if (msg->msg_name && msg->msg_namelen)3300 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_name, msg->msg_namelen);3301 if (msg->msg_iov && msg->msg_iovlen)3302 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_iov,3303 sizeof(*msg->msg_iov) * msg->msg_iovlen);3304 write_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen);3305 if (msg->msg_control && msg->msg_controllen)3306 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_control, msg->msg_controllen);3307}3308#endif3309 3310#if SANITIZER_INTERCEPT_RECVMSG3311INTERCEPTOR(SSIZE_T, recvmsg, int fd, struct __sanitizer_msghdr *msg,3312 int flags) {3313 void *ctx;3314 COMMON_INTERCEPTOR_ENTER(ctx, recvmsg, fd, msg, flags);3315 // FIXME: under ASan the call below may write to freed memory and corrupt3316 // its metadata. See3317 // https://github.com/google/sanitizers/issues/321.3318 SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(recvmsg)(fd, msg, flags);3319 if (res >= 0) {3320 if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);3321 if (msg) {3322 write_msghdr(ctx, msg, res);3323 COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg);3324 }3325 }3326 return res;3327}3328#define INIT_RECVMSG COMMON_INTERCEPT_FUNCTION(recvmsg);3329#else3330#define INIT_RECVMSG3331#endif3332 3333#if SANITIZER_INTERCEPT_RECVMMSG3334INTERCEPTOR(int, recvmmsg, int fd, struct __sanitizer_mmsghdr *msgvec,3335 unsigned int vlen, int flags, void *timeout) {3336 void *ctx;3337 COMMON_INTERCEPTOR_ENTER(ctx, recvmmsg, fd, msgvec, vlen, flags, timeout);3338 if (timeout) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout, struct_timespec_sz);3339 int res =3340 COMMON_INTERCEPTOR_BLOCK_REAL(recvmmsg)(fd, msgvec, vlen, flags, timeout);3341 if (res >= 0) {3342 if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);3343 for (int i = 0; i < res; ++i) {3344 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &msgvec[i].msg_len,3345 sizeof(msgvec[i].msg_len));3346 write_msghdr(ctx, &msgvec[i].msg_hdr, msgvec[i].msg_len);3347 COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, &msgvec[i].msg_hdr);3348 }3349 }3350 return res;3351}3352#define INIT_RECVMMSG COMMON_INTERCEPT_FUNCTION(recvmmsg);3353#else3354#define INIT_RECVMMSG3355#endif3356 3357#if SANITIZER_INTERCEPT_SENDMSG || SANITIZER_INTERCEPT_SENDMMSG3358static void read_msghdr_control(void *ctx, void *control, uptr controllen) {3359 const unsigned kCmsgDataOffset =3360 RoundUpTo(sizeof(__sanitizer_cmsghdr), sizeof(uptr));3361 3362 char *p = (char *)control;3363 char *const control_end = p + controllen;3364 while (true) {3365 if (p + sizeof(__sanitizer_cmsghdr) > control_end) break;3366 __sanitizer_cmsghdr *cmsg = (__sanitizer_cmsghdr *)p;3367 COMMON_INTERCEPTOR_READ_RANGE(ctx, &cmsg->cmsg_len, sizeof(cmsg->cmsg_len));3368 3369 if (p + RoundUpTo(cmsg->cmsg_len, sizeof(uptr)) > control_end) break;3370 3371 COMMON_INTERCEPTOR_READ_RANGE(ctx, &cmsg->cmsg_level,3372 sizeof(cmsg->cmsg_level));3373 COMMON_INTERCEPTOR_READ_RANGE(ctx, &cmsg->cmsg_type,3374 sizeof(cmsg->cmsg_type));3375 3376 if (cmsg->cmsg_len > kCmsgDataOffset) {3377 char *data = p + kCmsgDataOffset;3378 unsigned data_len = cmsg->cmsg_len - kCmsgDataOffset;3379 if (data_len > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, data, data_len);3380 }3381 3382 p += RoundUpTo(cmsg->cmsg_len, sizeof(uptr));3383 }3384}3385 3386static void read_msghdr(void *ctx, struct __sanitizer_msghdr *msg,3387 SSIZE_T maxlen) {3388#define R(f) \3389 COMMON_INTERCEPTOR_READ_RANGE(ctx, &msg->msg_##f, sizeof(msg->msg_##f))3390 R(name);3391 R(namelen);3392 R(iov);3393 R(iovlen);3394 R(control);3395 R(controllen);3396 R(flags);3397#undef R3398 if (msg->msg_name && msg->msg_namelen)3399 COMMON_INTERCEPTOR_READ_RANGE(ctx, msg->msg_name, msg->msg_namelen);3400 if (msg->msg_iov && msg->msg_iovlen)3401 COMMON_INTERCEPTOR_READ_RANGE(ctx, msg->msg_iov,3402 sizeof(*msg->msg_iov) * msg->msg_iovlen);3403 read_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen);3404 if (msg->msg_control && msg->msg_controllen)3405 read_msghdr_control(ctx, msg->msg_control, msg->msg_controllen);3406}3407#endif3408 3409#if SANITIZER_INTERCEPT_SENDMSG3410INTERCEPTOR(SSIZE_T, sendmsg, int fd, struct __sanitizer_msghdr *msg,3411 int flags) {3412 void *ctx;3413 COMMON_INTERCEPTOR_ENTER(ctx, sendmsg, fd, msg, flags);3414 if (fd >= 0) {3415 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);3416 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);3417 }3418 SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(sendmsg)(fd, msg, flags);3419 if (common_flags()->intercept_send && res >= 0 && msg)3420 read_msghdr(ctx, msg, res);3421 return res;3422}3423#define INIT_SENDMSG COMMON_INTERCEPT_FUNCTION(sendmsg);3424#else3425#define INIT_SENDMSG3426#endif3427 3428#if SANITIZER_INTERCEPT_SENDMMSG3429INTERCEPTOR(int, sendmmsg, int fd, struct __sanitizer_mmsghdr *msgvec,3430 unsigned vlen, int flags) {3431 void *ctx;3432 COMMON_INTERCEPTOR_ENTER(ctx, sendmmsg, fd, msgvec, vlen, flags);3433 if (fd >= 0) {3434 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);3435 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);3436 }3437 int res = COMMON_INTERCEPTOR_BLOCK_REAL(sendmmsg)(fd, msgvec, vlen, flags);3438 if (res >= 0 && msgvec) {3439 for (int i = 0; i < res; ++i) {3440 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &msgvec[i].msg_len,3441 sizeof(msgvec[i].msg_len));3442 if (common_flags()->intercept_send)3443 read_msghdr(ctx, &msgvec[i].msg_hdr, msgvec[i].msg_len);3444 }3445 }3446 return res;3447}3448#define INIT_SENDMMSG COMMON_INTERCEPT_FUNCTION(sendmmsg);3449#else3450#define INIT_SENDMMSG3451#endif3452 3453#if SANITIZER_INTERCEPT_SYSMSG3454INTERCEPTOR(int, msgsnd, int msqid, const void *msgp, SIZE_T msgsz,3455 int msgflg) {3456 void *ctx;3457 COMMON_INTERCEPTOR_ENTER(ctx, msgsnd, msqid, msgp, msgsz, msgflg);3458 if (msgp)3459 COMMON_INTERCEPTOR_READ_RANGE(ctx, msgp, sizeof(long) + msgsz);3460 int res = COMMON_INTERCEPTOR_BLOCK_REAL(msgsnd)(msqid, msgp, msgsz, msgflg);3461 return res;3462}3463 3464INTERCEPTOR(SSIZE_T, msgrcv, int msqid, void *msgp, SIZE_T msgsz,3465 long msgtyp, int msgflg) {3466 void *ctx;3467 COMMON_INTERCEPTOR_ENTER(ctx, msgrcv, msqid, msgp, msgsz, msgtyp, msgflg);3468 SSIZE_T len =3469 COMMON_INTERCEPTOR_BLOCK_REAL(msgrcv)(msqid, msgp, msgsz, msgtyp, msgflg);3470 if (len != -1)3471 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msgp, sizeof(long) + len);3472 return len;3473}3474 3475#define INIT_SYSMSG \3476 COMMON_INTERCEPT_FUNCTION(msgsnd); \3477 COMMON_INTERCEPT_FUNCTION(msgrcv);3478#else3479#define INIT_SYSMSG3480#endif3481 3482#if SANITIZER_INTERCEPT_GETPEERNAME3483INTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) {3484 void *ctx;3485 COMMON_INTERCEPTOR_ENTER(ctx, getpeername, sockfd, addr, addrlen);3486 unsigned addr_sz;3487 if (addrlen) {3488 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));3489 addr_sz = *addrlen;3490 }3491 // FIXME: under ASan the call below may write to freed memory and corrupt3492 // its metadata. See3493 // https://github.com/google/sanitizers/issues/321.3494 int res = REAL(getpeername)(sockfd, addr, addrlen);3495 if (!res && addr && addrlen) {3496 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen));3497 }3498 return res;3499}3500#define INIT_GETPEERNAME COMMON_INTERCEPT_FUNCTION(getpeername);3501#else3502#define INIT_GETPEERNAME3503#endif3504 3505#if SANITIZER_INTERCEPT_SYSINFO3506INTERCEPTOR(int, sysinfo, void *info) {3507 void *ctx;3508 // FIXME: under ASan the call below may write to freed memory and corrupt3509 // its metadata. See3510 // https://github.com/google/sanitizers/issues/321.3511 COMMON_INTERCEPTOR_ENTER(ctx, sysinfo, info);3512 int res = REAL(sysinfo)(info);3513 if (!res && info)3514 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, struct_sysinfo_sz);3515 return res;3516}3517#define INIT_SYSINFO COMMON_INTERCEPT_FUNCTION(sysinfo);3518#else3519#define INIT_SYSINFO3520#endif3521 3522#if SANITIZER_INTERCEPT_READDIR3523INTERCEPTOR(__sanitizer_dirent *, opendir, const char *path) {3524 void *ctx;3525 COMMON_INTERCEPTOR_ENTER(ctx, opendir, path);3526 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);3527 __sanitizer_dirent *res = REAL(opendir)(path);3528 if (res)3529 COMMON_INTERCEPTOR_DIR_ACQUIRE(ctx, path);3530 return res;3531}3532 3533INTERCEPTOR(__sanitizer_dirent *, readdir, void *dirp) {3534 void *ctx;3535 COMMON_INTERCEPTOR_ENTER(ctx, readdir, dirp);3536 // FIXME: under ASan the call below may write to freed memory and corrupt3537 // its metadata. See3538 // https://github.com/google/sanitizers/issues/321.3539 __sanitizer_dirent *res = REAL(readdir)(dirp);3540 if (res)3541 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, __sanitizer_dirsiz(res));3542 return res;3543}3544 3545INTERCEPTOR(int, readdir_r, void *dirp, __sanitizer_dirent *entry,3546 __sanitizer_dirent **result) {3547 void *ctx;3548 COMMON_INTERCEPTOR_ENTER(ctx, readdir_r, dirp, entry, result);3549 // FIXME: under ASan the call below may write to freed memory and corrupt3550 // its metadata. See3551 // https://github.com/google/sanitizers/issues/321.3552 int res = REAL(readdir_r)(dirp, entry, result);3553 if (!res) {3554 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));3555 if (*result)3556 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, __sanitizer_dirsiz(*result));3557 }3558 return res;3559}3560 3561#define INIT_READDIR \3562 COMMON_INTERCEPT_FUNCTION(opendir); \3563 COMMON_INTERCEPT_FUNCTION(readdir); \3564 COMMON_INTERCEPT_FUNCTION(readdir_r);3565#else3566#define INIT_READDIR3567#endif3568 3569#if SANITIZER_INTERCEPT_READDIR643570INTERCEPTOR(__sanitizer_dirent64 *, readdir64, void *dirp) {3571 void *ctx;3572 COMMON_INTERCEPTOR_ENTER(ctx, readdir64, dirp);3573 // FIXME: under ASan the call below may write to freed memory and corrupt3574 // its metadata. See3575 // https://github.com/google/sanitizers/issues/321.3576 __sanitizer_dirent64 *res = REAL(readdir64)(dirp);3577 if (res)3578 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, __sanitizer_dirsiz(res));3579 return res;3580}3581 3582INTERCEPTOR(int, readdir64_r, void *dirp, __sanitizer_dirent64 *entry,3583 __sanitizer_dirent64 **result) {3584 void *ctx;3585 COMMON_INTERCEPTOR_ENTER(ctx, readdir64_r, dirp, entry, result);3586 // FIXME: under ASan the call below may write to freed memory and corrupt3587 // its metadata. See3588 // https://github.com/google/sanitizers/issues/321.3589 int res = REAL(readdir64_r)(dirp, entry, result);3590 if (!res) {3591 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));3592 if (*result)3593 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, __sanitizer_dirsiz(*result));3594 }3595 return res;3596}3597#define INIT_READDIR64 \3598 COMMON_INTERCEPT_FUNCTION(readdir64); \3599 COMMON_INTERCEPT_FUNCTION(readdir64_r);3600#else3601#define INIT_READDIR643602#endif3603 3604#if SANITIZER_INTERCEPT_PTRACE3605INTERCEPTOR(uptr, ptrace, int request, int pid, void *addr, void *data) {3606 void *ctx;3607 COMMON_INTERCEPTOR_ENTER(ctx, ptrace, request, pid, addr, data);3608 __sanitizer_iovec local_iovec;3609 3610 void *data_arg = ptrace_data_arg(request, addr, data);3611 if (data_arg) {3612 if (request == ptrace_setregs) {3613 COMMON_INTERCEPTOR_READ_RANGE(ctx, data_arg, struct_user_regs_struct_sz);3614 } else if (request == ptrace_setfpregs) {3615 COMMON_INTERCEPTOR_READ_RANGE(ctx, data_arg,3616 struct_user_fpregs_struct_sz);3617 } else if (request == ptrace_setfpxregs) {3618 COMMON_INTERCEPTOR_READ_RANGE(ctx, data_arg,3619 struct_user_fpxregs_struct_sz);3620 } else if (request == ptrace_setvfpregs) {3621 COMMON_INTERCEPTOR_READ_RANGE(ctx, data_arg,3622 struct_user_vfpregs_struct_sz);3623 } else if (request == ptrace_setsiginfo) {3624 COMMON_INTERCEPTOR_READ_RANGE(ctx, data_arg, siginfo_t_sz);3625 3626 // Some kernel might zero the iovec::iov_base in case of invalid3627 // write access. In this case copy the invalid address for further3628 // inspection.3629 } else if (request == ptrace_setregset || request == ptrace_getregset) {3630 __sanitizer_iovec *iovec = (__sanitizer_iovec *)data_arg;3631 COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec));3632 local_iovec = *iovec;3633 if (request == ptrace_setregset)3634 COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec->iov_base, iovec->iov_len);3635 }3636 }3637 3638 // FIXME: under ASan the call below may write to freed memory and corrupt3639 // its metadata. See3640 // https://github.com/google/sanitizers/issues/321.3641 uptr res = REAL(ptrace)(request, pid, addr, data);3642 3643 if (!res && data_arg) {3644 // Note that PEEK* requests assign different meaning to the return value.3645 // This function does not handle them (nor does it need to).3646 if (request == ptrace_getregs) {3647 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data_arg, struct_user_regs_struct_sz);3648 } else if (request == ptrace_getfpregs) {3649 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data_arg,3650 struct_user_fpregs_struct_sz);3651 } else if (request == ptrace_getfpxregs) {3652 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data_arg,3653 struct_user_fpxregs_struct_sz);3654 } else if (request == ptrace_getvfpregs) {3655 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data_arg,3656 struct_user_vfpregs_struct_sz);3657 } else if (request == ptrace_getsiginfo) {3658 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data_arg, siginfo_t_sz);3659 } else if (request == ptrace_geteventmsg) {3660 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data_arg, sizeof(unsigned long));3661 } else if (request == ptrace_getregset) {3662 __sanitizer_iovec *iovec = (__sanitizer_iovec *)data_arg;3663 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec, sizeof(*iovec));3664 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, local_iovec.iov_base,3665 local_iovec.iov_len);3666 }3667 }3668 return res;3669}3670 3671#define INIT_PTRACE COMMON_INTERCEPT_FUNCTION(ptrace);3672#else3673#define INIT_PTRACE3674#endif3675 3676#if SANITIZER_INTERCEPT_SETLOCALE3677static void unpoison_ctype_arrays(void *ctx) {3678#if SANITIZER_NETBSD3679 // These arrays contain 256 regular elements in unsigned char range + 1 EOF3680 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, _ctype_tab_, 257 * sizeof(short));3681 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, _toupper_tab_, 257 * sizeof(short));3682 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, _tolower_tab_, 257 * sizeof(short));3683#endif3684}3685 3686INTERCEPTOR(char *, setlocale, int category, char *locale) {3687 void *ctx;3688 COMMON_INTERCEPTOR_ENTER(ctx, setlocale, category, locale);3689 if (locale)3690 COMMON_INTERCEPTOR_READ_RANGE(ctx, locale, internal_strlen(locale) + 1);3691 char *res = REAL(setlocale)(category, locale);3692 if (res) {3693 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);3694 unpoison_ctype_arrays(ctx);3695 }3696 return res;3697}3698 3699#define INIT_SETLOCALE COMMON_INTERCEPT_FUNCTION(setlocale);3700#else3701#define INIT_SETLOCALE3702#endif3703 3704#if SANITIZER_INTERCEPT_GETCWD3705INTERCEPTOR(char *, getcwd, char *buf, SIZE_T size) {3706 void *ctx;3707 COMMON_INTERCEPTOR_ENTER(ctx, getcwd, buf, size);3708 // FIXME: under ASan the call below may write to freed memory and corrupt3709 // its metadata. See3710 // https://github.com/google/sanitizers/issues/321.3711 char *res = REAL(getcwd)(buf, size);3712 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);3713 return res;3714}3715#define INIT_GETCWD COMMON_INTERCEPT_FUNCTION(getcwd);3716#else3717#define INIT_GETCWD3718#endif3719 3720#if SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME3721INTERCEPTOR(char *, get_current_dir_name, int fake) {3722 void *ctx;3723 COMMON_INTERCEPTOR_ENTER(ctx, get_current_dir_name, fake);3724 // FIXME: under ASan the call below may write to freed memory and corrupt3725 // its metadata. See3726 // https://github.com/google/sanitizers/issues/321.3727 char *res = REAL(get_current_dir_name)(fake);3728 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);3729 return res;3730}3731 3732#define INIT_GET_CURRENT_DIR_NAME \3733 COMMON_INTERCEPT_FUNCTION(get_current_dir_name);3734#else3735#define INIT_GET_CURRENT_DIR_NAME3736#endif3737 3738UNUSED static inline void FixRealStrtolEndptr(const char *nptr, char **endptr) {3739 CHECK(endptr);3740 if (nptr == *endptr) {3741 // No digits were found at strtol call, we need to find out the last3742 // symbol accessed by strtoll on our own.3743 // We get this symbol by skipping leading blanks and optional +/- sign.3744 while (IsSpace(*nptr)) nptr++;3745 if (*nptr == '+' || *nptr == '-') nptr++;3746 *endptr = const_cast<char *>(nptr);3747 }3748 CHECK(*endptr >= nptr);3749}3750 3751UNUSED static inline void StrtolFixAndCheck(void *ctx, const char *nptr,3752 char **endptr, char *real_endptr, int base) {3753 if (endptr) {3754 *endptr = real_endptr;3755 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr));3756 }3757 // If base has unsupported value, strtol can exit with EINVAL3758 // without reading any characters. So do additional checks only3759 // if base is valid.3760 bool is_valid_base = (base == 0) || (2 <= base && base <= 36);3761 if (is_valid_base) {3762 FixRealStrtolEndptr(nptr, &real_endptr);3763 }3764 COMMON_INTERCEPTOR_READ_STRING(ctx, nptr, is_valid_base ?3765 (real_endptr - nptr) + 1 : 0);3766}3767 3768#if SANITIZER_INTERCEPT_STRTOIMAX3769template <typename Fn>3770static ALWAYS_INLINE auto StrtoimaxImpl(void *ctx, Fn real, const char *nptr,3771 char **endptr, int base)3772 -> decltype(real(nullptr, nullptr, 0)) {3773 char *real_endptr;3774 auto res = real(nptr, &real_endptr, base);3775 StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);3776 return res;3777}3778 3779INTERCEPTOR(INTMAX_T, strtoimax, const char *nptr, char **endptr, int base) {3780 void *ctx;3781 COMMON_INTERCEPTOR_ENTER(ctx, strtoimax, nptr, endptr, base);3782 return StrtoimaxImpl(ctx, REAL(strtoimax), nptr, endptr, base);3783}3784INTERCEPTOR(UINTMAX_T, strtoumax, const char *nptr, char **endptr, int base) {3785 void *ctx;3786 COMMON_INTERCEPTOR_ENTER(ctx, strtoumax, nptr, endptr, base);3787 return StrtoimaxImpl(ctx, REAL(strtoumax), nptr, endptr, base);3788}3789 3790#define INIT_STRTOIMAX \3791 COMMON_INTERCEPT_FUNCTION(strtoimax); \3792 COMMON_INTERCEPT_FUNCTION(strtoumax);3793#else3794#define INIT_STRTOIMAX3795#endif3796 3797#if SANITIZER_INTERCEPT_STRTOIMAX && SANITIZER_GLIBC3798INTERCEPTOR(INTMAX_T, __isoc23_strtoimax, const char *nptr, char **endptr, int base) {3799 void *ctx;3800 COMMON_INTERCEPTOR_ENTER(ctx, __isoc23_strtoimax, nptr, endptr, base);3801 return StrtoimaxImpl(ctx, REAL(__isoc23_strtoimax), nptr, endptr, base);3802}3803INTERCEPTOR(UINTMAX_T, __isoc23_strtoumax, const char *nptr, char **endptr, int base) {3804 void *ctx;3805 COMMON_INTERCEPTOR_ENTER(ctx, __isoc23_strtoumax, nptr, endptr, base);3806 return StrtoimaxImpl(ctx, REAL(__isoc23_strtoumax), nptr, endptr, base);3807}3808 3809# define INIT_STRTOIMAX_C23 \3810 COMMON_INTERCEPT_FUNCTION(__isoc23_strtoimax); \3811 COMMON_INTERCEPT_FUNCTION(__isoc23_strtoumax);3812#else3813# define INIT_STRTOIMAX_C233814#endif3815 3816#if SANITIZER_INTERCEPT_MBSTOWCS3817INTERCEPTOR(SIZE_T, mbstowcs, wchar_t *dest, const char *src, SIZE_T len) {3818 void *ctx;3819 COMMON_INTERCEPTOR_ENTER(ctx, mbstowcs, dest, src, len);3820 // FIXME: under ASan the call below may write to freed memory and corrupt3821 // its metadata. See3822 // https://github.com/google/sanitizers/issues/321.3823 SIZE_T res = REAL(mbstowcs)(dest, src, len);3824 if (res != (SIZE_T) - 1 && dest) {3825 SIZE_T write_cnt = res + (res < len);3826 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));3827 }3828 return res;3829}3830 3831INTERCEPTOR(SIZE_T, mbsrtowcs, wchar_t *dest, const char **src, SIZE_T len,3832 void *ps) {3833 void *ctx;3834 COMMON_INTERCEPTOR_ENTER(ctx, mbsrtowcs, dest, src, len, ps);3835 if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));3836 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);3837 // FIXME: under ASan the call below may write to freed memory and corrupt3838 // its metadata. See3839 // https://github.com/google/sanitizers/issues/321.3840 SIZE_T res = REAL(mbsrtowcs)(dest, src, len, ps);3841 if (res != (SIZE_T)(-1) && dest && src) {3842 // This function, and several others, may or may not write the terminating3843 // \0 character. They write it iff they clear *src.3844 SIZE_T write_cnt = res + !*src;3845 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));3846 }3847 return res;3848}3849 3850#define INIT_MBSTOWCS \3851 COMMON_INTERCEPT_FUNCTION(mbstowcs); \3852 COMMON_INTERCEPT_FUNCTION(mbsrtowcs);3853#else3854#define INIT_MBSTOWCS3855#endif3856 3857#if SANITIZER_INTERCEPT_MBSNRTOWCS3858INTERCEPTOR(SIZE_T, mbsnrtowcs, wchar_t *dest, const char **src, SIZE_T nms,3859 SIZE_T len, void *ps) {3860 void *ctx;3861 COMMON_INTERCEPTOR_ENTER(ctx, mbsnrtowcs, dest, src, nms, len, ps);3862 if (src) {3863 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));3864 if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);3865 }3866 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);3867 // FIXME: under ASan the call below may write to freed memory and corrupt3868 // its metadata. See3869 // https://github.com/google/sanitizers/issues/321.3870 SIZE_T res = REAL(mbsnrtowcs)(dest, src, nms, len, ps);3871 if (res != (SIZE_T)(-1) && dest && src) {3872 SIZE_T write_cnt = res + !*src;3873 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));3874 }3875 return res;3876}3877 3878#define INIT_MBSNRTOWCS COMMON_INTERCEPT_FUNCTION(mbsnrtowcs);3879#else3880#define INIT_MBSNRTOWCS3881#endif3882 3883#if SANITIZER_INTERCEPT_WCSTOMBS3884INTERCEPTOR(SIZE_T, wcstombs, char *dest, const wchar_t *src, SIZE_T len) {3885 void *ctx;3886 COMMON_INTERCEPTOR_ENTER(ctx, wcstombs, dest, src, len);3887 // FIXME: under ASan the call below may write to freed memory and corrupt3888 // its metadata. See3889 // https://github.com/google/sanitizers/issues/321.3890 SIZE_T res = REAL(wcstombs)(dest, src, len);3891 if (res != (SIZE_T) - 1 && dest) {3892 SIZE_T write_cnt = res + (res < len);3893 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);3894 }3895 return res;3896}3897 3898INTERCEPTOR(SIZE_T, wcsrtombs, char *dest, const wchar_t **src, SIZE_T len,3899 void *ps) {3900 void *ctx;3901 COMMON_INTERCEPTOR_ENTER(ctx, wcsrtombs, dest, src, len, ps);3902 if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));3903 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);3904 // FIXME: under ASan the call below may write to freed memory and corrupt3905 // its metadata. See3906 // https://github.com/google/sanitizers/issues/321.3907 SIZE_T res = REAL(wcsrtombs)(dest, src, len, ps);3908 if (res != (SIZE_T) - 1 && dest && src) {3909 SIZE_T write_cnt = res + !*src;3910 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);3911 }3912 return res;3913}3914 3915#define INIT_WCSTOMBS \3916 COMMON_INTERCEPT_FUNCTION(wcstombs); \3917 COMMON_INTERCEPT_FUNCTION(wcsrtombs);3918#else3919#define INIT_WCSTOMBS3920#endif3921 3922#if SANITIZER_INTERCEPT_WCSNRTOMBS3923INTERCEPTOR(SIZE_T, wcsnrtombs, char *dest, const wchar_t **src, SIZE_T nms,3924 SIZE_T len, void *ps) {3925 void *ctx;3926 COMMON_INTERCEPTOR_ENTER(ctx, wcsnrtombs, dest, src, nms, len, ps);3927 if (src) {3928 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));3929 if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);3930 }3931 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);3932 // FIXME: under ASan the call below may write to freed memory and corrupt3933 // its metadata. See3934 // https://github.com/google/sanitizers/issues/321.3935 SIZE_T res = REAL(wcsnrtombs)(dest, src, nms, len, ps);3936 if (res != ((SIZE_T)-1) && dest && src) {3937 SIZE_T write_cnt = res + !*src;3938 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);3939 }3940 return res;3941}3942 3943#define INIT_WCSNRTOMBS COMMON_INTERCEPT_FUNCTION(wcsnrtombs);3944#else3945#define INIT_WCSNRTOMBS3946#endif3947 3948 3949#if SANITIZER_INTERCEPT_WCRTOMB3950INTERCEPTOR(SIZE_T, wcrtomb, char *dest, wchar_t src, void *ps) {3951 void *ctx;3952 COMMON_INTERCEPTOR_ENTER(ctx, wcrtomb, dest, src, ps);3953 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);3954 3955 if (!dest)3956 return REAL(wcrtomb)(dest, src, ps);3957 3958 char local_dest[32];3959 SIZE_T res = REAL(wcrtomb)(local_dest, src, ps);3960 if (res != ((SIZE_T)-1)) {3961 CHECK_LE(res, sizeof(local_dest));3962 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res);3963 internal_memcpy(dest, local_dest, res);3964 }3965 return res;3966}3967 3968#define INIT_WCRTOMB COMMON_INTERCEPT_FUNCTION(wcrtomb);3969#else3970#define INIT_WCRTOMB3971#endif3972 3973#if SANITIZER_INTERCEPT_WCTOMB3974INTERCEPTOR(int, wctomb, char *dest, wchar_t src) {3975 void *ctx;3976 COMMON_INTERCEPTOR_ENTER(ctx, wctomb, dest, src);3977 if (!dest)3978 return REAL(wctomb)(dest, src);3979 3980 char local_dest[32];3981 int res = REAL(wctomb)(local_dest, src);3982 if (res != -1) {3983 CHECK_LE(res, sizeof(local_dest));3984 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res);3985 internal_memcpy(dest, local_dest, res);3986 }3987 return res;3988}3989 3990#define INIT_WCTOMB COMMON_INTERCEPT_FUNCTION(wctomb);3991#else3992#define INIT_WCTOMB3993#endif3994 3995#if SANITIZER_INTERCEPT_TCGETATTR3996INTERCEPTOR(int, tcgetattr, int fd, void *termios_p) {3997 void *ctx;3998 COMMON_INTERCEPTOR_ENTER(ctx, tcgetattr, fd, termios_p);3999 // FIXME: under ASan the call below may write to freed memory and corrupt4000 // its metadata. See4001 // https://github.com/google/sanitizers/issues/321.4002 int res = REAL(tcgetattr)(fd, termios_p);4003 if (!res && termios_p)4004 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, termios_p, struct_termios_sz);4005 return res;4006}4007 4008#define INIT_TCGETATTR COMMON_INTERCEPT_FUNCTION(tcgetattr);4009#else4010#define INIT_TCGETATTR4011#endif4012 4013#if SANITIZER_INTERCEPT_REALPATH4014INTERCEPTOR(char *, realpath, const char *path, char *resolved_path) {4015 void *ctx;4016 COMMON_INTERCEPTOR_ENTER(ctx, realpath, path, resolved_path);4017 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);4018 4019 // Workaround a bug in glibc where dlsym(RTLD_NEXT, ...) returns the oldest4020 // version of a versioned symbol. For realpath(), this gives us something4021 // (called __old_realpath) that does not handle NULL in the second argument.4022 // Handle it as part of the interceptor.4023 char *allocated_path = nullptr;4024 if (!resolved_path)4025 allocated_path = resolved_path = (char *)WRAP(malloc)(path_max + 1);4026 4027 char *res = REAL(realpath)(path, resolved_path);4028 if (allocated_path && !res)4029 WRAP(free)(allocated_path);4030 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);4031 return res;4032}4033# define INIT_REALPATH COMMON_INTERCEPT_FUNCTION(realpath);4034#else4035#define INIT_REALPATH4036#endif4037 4038#if SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME4039INTERCEPTOR(char *, canonicalize_file_name, const char *path) {4040 void *ctx;4041 COMMON_INTERCEPTOR_ENTER(ctx, canonicalize_file_name, path);4042 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);4043 char *res = REAL(canonicalize_file_name)(path);4044 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);4045 return res;4046}4047#define INIT_CANONICALIZE_FILE_NAME \4048 COMMON_INTERCEPT_FUNCTION(canonicalize_file_name);4049#else4050#define INIT_CANONICALIZE_FILE_NAME4051#endif4052 4053#if SANITIZER_INTERCEPT_CONFSTR4054INTERCEPTOR(SIZE_T, confstr, int name, char *buf, SIZE_T len) {4055 void *ctx;4056 COMMON_INTERCEPTOR_ENTER(ctx, confstr, name, buf, len);4057 // FIXME: under ASan the call below may write to freed memory and corrupt4058 // its metadata. See4059 // https://github.com/google/sanitizers/issues/321.4060 SIZE_T res = REAL(confstr)(name, buf, len);4061 if (buf && res)4062 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res < len ? res : len);4063 return res;4064}4065#define INIT_CONFSTR COMMON_INTERCEPT_FUNCTION(confstr);4066#else4067#define INIT_CONFSTR4068#endif4069 4070#if SANITIZER_INTERCEPT_SCHED_GETAFFINITY4071INTERCEPTOR(int, sched_getaffinity, int pid, SIZE_T cpusetsize, void *mask) {4072 void *ctx;4073 COMMON_INTERCEPTOR_ENTER(ctx, sched_getaffinity, pid, cpusetsize, mask);4074 // FIXME: under ASan the call below may write to freed memory and corrupt4075 // its metadata. See4076 // https://github.com/google/sanitizers/issues/321.4077 int res = REAL(sched_getaffinity)(pid, cpusetsize, mask);4078 if (mask && !res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mask, cpusetsize);4079 return res;4080}4081#define INIT_SCHED_GETAFFINITY COMMON_INTERCEPT_FUNCTION(sched_getaffinity);4082#else4083#define INIT_SCHED_GETAFFINITY4084#endif4085 4086#if SANITIZER_INTERCEPT_SCHED_GETPARAM4087INTERCEPTOR(int, sched_getparam, int pid, void *param) {4088 void *ctx;4089 COMMON_INTERCEPTOR_ENTER(ctx, sched_getparam, pid, param);4090 int res = REAL(sched_getparam)(pid, param);4091 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, struct_sched_param_sz);4092 return res;4093}4094#define INIT_SCHED_GETPARAM COMMON_INTERCEPT_FUNCTION(sched_getparam);4095#else4096#define INIT_SCHED_GETPARAM4097#endif4098 4099#if SANITIZER_INTERCEPT_STRERROR4100INTERCEPTOR(char *, strerror, int errnum) {4101 void *ctx;4102 COMMON_INTERCEPTOR_ENTER(ctx, strerror, errnum);4103 COMMON_INTERCEPTOR_STRERROR();4104 char *res = REAL(strerror)(errnum);4105 if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);4106 return res;4107}4108#define INIT_STRERROR COMMON_INTERCEPT_FUNCTION(strerror);4109#else4110#define INIT_STRERROR4111#endif4112 4113#if SANITIZER_INTERCEPT_STRERROR_R4114// There are 2 versions of strerror_r:4115// * POSIX version returns 0 on success, negative error code on failure,4116// writes message to buf.4117// * GNU version returns message pointer, which points to either buf or some4118// static storage.4119#if ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE) || \4120 SANITIZER_APPLE || SANITIZER_ANDROID || SANITIZER_NETBSD || \4121 SANITIZER_FREEBSD4122// POSIX version. Spec is not clear on whether buf is NULL-terminated.4123// At least on OSX, buf contents are valid even when the call fails.4124INTERCEPTOR(int, strerror_r, int errnum, char *buf, SIZE_T buflen) {4125 void *ctx;4126 COMMON_INTERCEPTOR_ENTER(ctx, strerror_r, errnum, buf, buflen);4127 // FIXME: under ASan the call below may write to freed memory and corrupt4128 // its metadata. See4129 // https://github.com/google/sanitizers/issues/321.4130 int res = REAL(strerror_r)(errnum, buf, buflen);4131 4132 SIZE_T sz = internal_strnlen(buf, buflen);4133 if (sz < buflen) ++sz;4134 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz);4135 return res;4136}4137#else4138// GNU version.4139INTERCEPTOR(char *, strerror_r, int errnum, char *buf, SIZE_T buflen) {4140 void *ctx;4141 COMMON_INTERCEPTOR_ENTER(ctx, strerror_r, errnum, buf, buflen);4142 // FIXME: under ASan the call below may write to freed memory and corrupt4143 // its metadata. See4144 // https://github.com/google/sanitizers/issues/321.4145 char *res = REAL(strerror_r)(errnum, buf, buflen);4146 if (res == buf)4147 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);4148 else4149 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);4150 return res;4151}4152#endif //(_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE ||4153 //SANITIZER_APPLE4154#define INIT_STRERROR_R COMMON_INTERCEPT_FUNCTION(strerror_r);4155#else4156#define INIT_STRERROR_R4157#endif4158 4159#if SANITIZER_INTERCEPT_XPG_STRERROR_R4160INTERCEPTOR(int, __xpg_strerror_r, int errnum, char *buf, SIZE_T buflen) {4161 void *ctx;4162 COMMON_INTERCEPTOR_ENTER(ctx, __xpg_strerror_r, errnum, buf, buflen);4163 // FIXME: under ASan the call below may write to freed memory and corrupt4164 // its metadata. See4165 // https://github.com/google/sanitizers/issues/321.4166 int res = REAL(__xpg_strerror_r)(errnum, buf, buflen);4167 // This version always returns a null-terminated string.4168 if (buf && buflen)4169 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, internal_strlen(buf) + 1);4170 return res;4171}4172#define INIT_XPG_STRERROR_R COMMON_INTERCEPT_FUNCTION(__xpg_strerror_r);4173#else4174#define INIT_XPG_STRERROR_R4175#endif4176 4177#if SANITIZER_INTERCEPT_SCANDIR4178typedef int (*scandir_filter_f)(const struct __sanitizer_dirent *);4179typedef int (*scandir_compar_f)(const struct __sanitizer_dirent **,4180 const struct __sanitizer_dirent **);4181 4182static THREADLOCAL scandir_filter_f scandir_filter;4183static THREADLOCAL scandir_compar_f scandir_compar;4184 4185static int wrapped_scandir_filter(const struct __sanitizer_dirent *dir) {4186 COMMON_INTERCEPTOR_UNPOISON_PARAM(1);4187 COMMON_INTERCEPTOR_INITIALIZE_RANGE(dir, __sanitizer_dirsiz(dir));4188 return scandir_filter(dir);4189}4190 4191static int wrapped_scandir_compar(const struct __sanitizer_dirent **a,4192 const struct __sanitizer_dirent **b) {4193 COMMON_INTERCEPTOR_UNPOISON_PARAM(2);4194 COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, sizeof(*a));4195 COMMON_INTERCEPTOR_INITIALIZE_RANGE(*a, __sanitizer_dirsiz(*a));4196 COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, sizeof(*b));4197 COMMON_INTERCEPTOR_INITIALIZE_RANGE(*b, __sanitizer_dirsiz(*b));4198 return scandir_compar(a, b);4199}4200 4201INTERCEPTOR(int, scandir, char *dirp, __sanitizer_dirent ***namelist,4202 scandir_filter_f filter, scandir_compar_f compar) {4203 void *ctx;4204 COMMON_INTERCEPTOR_ENTER(ctx, scandir, dirp, namelist, filter, compar);4205 if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, internal_strlen(dirp) + 1);4206 scandir_filter = filter;4207 scandir_compar = compar;4208 // FIXME: under ASan the call below may write to freed memory and corrupt4209 // its metadata. See4210 // https://github.com/google/sanitizers/issues/321.4211 int res = REAL(scandir)(dirp, namelist,4212 filter ? wrapped_scandir_filter : nullptr,4213 compar ? wrapped_scandir_compar : nullptr);4214 scandir_filter = nullptr;4215 scandir_compar = nullptr;4216 if (namelist && res > 0) {4217 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist));4218 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res);4219 for (int i = 0; i < res; ++i)4220 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i],4221 __sanitizer_dirsiz((*namelist)[i]));4222 }4223 return res;4224}4225#define INIT_SCANDIR COMMON_INTERCEPT_FUNCTION(scandir);4226#else4227#define INIT_SCANDIR4228#endif4229 4230#if SANITIZER_INTERCEPT_SCANDIR644231typedef int (*scandir64_filter_f)(const struct __sanitizer_dirent64 *);4232typedef int (*scandir64_compar_f)(const struct __sanitizer_dirent64 **,4233 const struct __sanitizer_dirent64 **);4234 4235static THREADLOCAL scandir64_filter_f scandir64_filter;4236static THREADLOCAL scandir64_compar_f scandir64_compar;4237 4238static int wrapped_scandir64_filter(const struct __sanitizer_dirent64 *dir) {4239 COMMON_INTERCEPTOR_UNPOISON_PARAM(1);4240 COMMON_INTERCEPTOR_INITIALIZE_RANGE(dir, __sanitizer_dirsiz(dir));4241 return scandir64_filter(dir);4242}4243 4244static int wrapped_scandir64_compar(const struct __sanitizer_dirent64 **a,4245 const struct __sanitizer_dirent64 **b) {4246 COMMON_INTERCEPTOR_UNPOISON_PARAM(2);4247 COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, sizeof(*a));4248 COMMON_INTERCEPTOR_INITIALIZE_RANGE(*a, __sanitizer_dirsiz(*a));4249 COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, sizeof(*b));4250 COMMON_INTERCEPTOR_INITIALIZE_RANGE(*b, __sanitizer_dirsiz(*b));4251 return scandir64_compar(a, b);4252}4253 4254INTERCEPTOR(int, scandir64, char *dirp, __sanitizer_dirent64 ***namelist,4255 scandir64_filter_f filter, scandir64_compar_f compar) {4256 void *ctx;4257 COMMON_INTERCEPTOR_ENTER(ctx, scandir64, dirp, namelist, filter, compar);4258 if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, internal_strlen(dirp) + 1);4259 scandir64_filter = filter;4260 scandir64_compar = compar;4261 // FIXME: under ASan the call below may write to freed memory and corrupt4262 // its metadata. See4263 // https://github.com/google/sanitizers/issues/321.4264 int res =4265 REAL(scandir64)(dirp, namelist,4266 filter ? wrapped_scandir64_filter : nullptr,4267 compar ? wrapped_scandir64_compar : nullptr);4268 scandir64_filter = nullptr;4269 scandir64_compar = nullptr;4270 if (namelist && res > 0) {4271 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist));4272 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res);4273 for (int i = 0; i < res; ++i)4274 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i],4275 __sanitizer_dirsiz((*namelist)[i]));4276 }4277 return res;4278}4279#define INIT_SCANDIR64 COMMON_INTERCEPT_FUNCTION(scandir64);4280#else4281#define INIT_SCANDIR644282#endif4283 4284#if SANITIZER_INTERCEPT_GETGROUPS4285INTERCEPTOR(int, getgroups, int size, u32 *lst) {4286 void *ctx;4287 COMMON_INTERCEPTOR_ENTER(ctx, getgroups, size, lst);4288 // FIXME: under ASan the call below may write to freed memory and corrupt4289 // its metadata. See4290 // https://github.com/google/sanitizers/issues/321.4291 int res = REAL(getgroups)(size, lst);4292 if (res >= 0 && lst && size > 0)4293 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lst, res * sizeof(*lst));4294 return res;4295}4296#define INIT_GETGROUPS COMMON_INTERCEPT_FUNCTION(getgroups);4297#else4298#define INIT_GETGROUPS4299#endif4300 4301#if SANITIZER_INTERCEPT_POLL4302static void read_pollfd(void *ctx, __sanitizer_pollfd *fds,4303 __sanitizer_nfds_t nfds) {4304 for (unsigned i = 0; i < nfds; ++i) {4305 COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].fd, sizeof(fds[i].fd));4306 COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].events, sizeof(fds[i].events));4307 }4308}4309 4310static void write_pollfd(void *ctx, __sanitizer_pollfd *fds,4311 __sanitizer_nfds_t nfds) {4312 for (unsigned i = 0; i < nfds; ++i)4313 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &fds[i].revents,4314 sizeof(fds[i].revents));4315}4316 4317INTERCEPTOR(int, poll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds,4318 int timeout) {4319 void *ctx;4320 COMMON_INTERCEPTOR_ENTER(ctx, poll, fds, nfds, timeout);4321 if (fds && nfds) read_pollfd(ctx, fds, nfds);4322 int res = COMMON_INTERCEPTOR_BLOCK_REAL(poll)(fds, nfds, timeout);4323 if (fds && nfds) write_pollfd(ctx, fds, nfds);4324 return res;4325}4326#define INIT_POLL COMMON_INTERCEPT_FUNCTION(poll);4327#else4328#define INIT_POLL4329#endif4330 4331#if SANITIZER_INTERCEPT_PPOLL4332INTERCEPTOR(int, ppoll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds,4333 void *timeout_ts, __sanitizer_sigset_t *sigmask) {4334 void *ctx;4335 COMMON_INTERCEPTOR_ENTER(ctx, ppoll, fds, nfds, timeout_ts, sigmask);4336 if (fds && nfds) read_pollfd(ctx, fds, nfds);4337 if (timeout_ts)4338 COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout_ts, struct_timespec_sz);4339 if (sigmask) COMMON_INTERCEPTOR_READ_RANGE(ctx, sigmask, sizeof(*sigmask));4340 int res =4341 COMMON_INTERCEPTOR_BLOCK_REAL(ppoll)(fds, nfds, timeout_ts, sigmask);4342 if (fds && nfds) write_pollfd(ctx, fds, nfds);4343 return res;4344}4345#define INIT_PPOLL COMMON_INTERCEPT_FUNCTION(ppoll);4346#else4347#define INIT_PPOLL4348#endif4349 4350#if SANITIZER_INTERCEPT_WORDEXP4351INTERCEPTOR(int, wordexp, char *s, __sanitizer_wordexp_t *p, int flags) {4352 void *ctx;4353 COMMON_INTERCEPTOR_ENTER(ctx, wordexp, s, p, flags);4354 if (s) COMMON_INTERCEPTOR_READ_RANGE(ctx, s, internal_strlen(s) + 1);4355 // FIXME: under ASan the call below may write to freed memory and corrupt4356 // its metadata. See4357 // https://github.com/google/sanitizers/issues/321.4358 int res = REAL(wordexp)(s, p, flags);4359 if (!res && p) {4360 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));4361 uptr we_wordc =4362 ((flags & wordexp_wrde_dooffs) ? p->we_offs : 0) + p->we_wordc;4363 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->we_wordv,4364 sizeof(*p->we_wordv) * (we_wordc + 1));4365 for (uptr i = 0; i < we_wordc; ++i) {4366 char *w = p->we_wordv[i];4367 if (w) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, w, internal_strlen(w) + 1);4368 }4369 }4370 return res;4371}4372#define INIT_WORDEXP COMMON_INTERCEPT_FUNCTION(wordexp);4373#else4374#define INIT_WORDEXP4375#endif4376 4377#if SANITIZER_INTERCEPT_SIGWAIT4378INTERCEPTOR(int, sigwait, __sanitizer_sigset_t *set, int *sig) {4379 void *ctx;4380 COMMON_INTERCEPTOR_ENTER(ctx, sigwait, set, sig);4381 if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));4382 // FIXME: under ASan the call below may write to freed memory and corrupt4383 // its metadata. See4384 // https://github.com/google/sanitizers/issues/321.4385 int res = COMMON_INTERCEPTOR_BLOCK_REAL(sigwait)(set, sig);4386 if (!res && sig) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sig, sizeof(*sig));4387 return res;4388}4389#define INIT_SIGWAIT COMMON_INTERCEPT_FUNCTION(sigwait);4390#else4391#define INIT_SIGWAIT4392#endif4393 4394#if SANITIZER_INTERCEPT_SIGWAITINFO4395INTERCEPTOR(int, sigwaitinfo, __sanitizer_sigset_t *set, void *info) {4396 void *ctx;4397 COMMON_INTERCEPTOR_ENTER(ctx, sigwaitinfo, set, info);4398 if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));4399 // FIXME: under ASan the call below may write to freed memory and corrupt4400 // its metadata. See4401 // https://github.com/google/sanitizers/issues/321.4402 int res = COMMON_INTERCEPTOR_BLOCK_REAL(sigwaitinfo)(set, info);4403 if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz);4404 return res;4405}4406#define INIT_SIGWAITINFO COMMON_INTERCEPT_FUNCTION(sigwaitinfo);4407#else4408#define INIT_SIGWAITINFO4409#endif4410 4411#if SANITIZER_INTERCEPT_SIGTIMEDWAIT4412INTERCEPTOR(int, sigtimedwait, __sanitizer_sigset_t *set, void *info,4413 void *timeout) {4414 void *ctx;4415 COMMON_INTERCEPTOR_ENTER(ctx, sigtimedwait, set, info, timeout);4416 if (timeout) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout, struct_timespec_sz);4417 if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));4418 // FIXME: under ASan the call below may write to freed memory and corrupt4419 // its metadata. See4420 // https://github.com/google/sanitizers/issues/321.4421 int res = COMMON_INTERCEPTOR_BLOCK_REAL(sigtimedwait)(set, info, timeout);4422 if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz);4423 return res;4424}4425#define INIT_SIGTIMEDWAIT COMMON_INTERCEPT_FUNCTION(sigtimedwait);4426#else4427#define INIT_SIGTIMEDWAIT4428#endif4429 4430#if SANITIZER_INTERCEPT_SIGSETOPS4431INTERCEPTOR(int, sigemptyset, __sanitizer_sigset_t *set) {4432 void *ctx;4433 COMMON_INTERCEPTOR_ENTER(ctx, sigemptyset, set);4434 // FIXME: under ASan the call below may write to freed memory and corrupt4435 // its metadata. See4436 // https://github.com/google/sanitizers/issues/321.4437 int res = REAL(sigemptyset)(set);4438 if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));4439 return res;4440}4441 4442INTERCEPTOR(int, sigfillset, __sanitizer_sigset_t *set) {4443 void *ctx;4444 COMMON_INTERCEPTOR_ENTER(ctx, sigfillset, set);4445 // FIXME: under ASan the call below may write to freed memory and corrupt4446 // its metadata. See4447 // https://github.com/google/sanitizers/issues/321.4448 int res = REAL(sigfillset)(set);4449 if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));4450 return res;4451}4452#define INIT_SIGSETOPS \4453 COMMON_INTERCEPT_FUNCTION(sigemptyset); \4454 COMMON_INTERCEPT_FUNCTION(sigfillset);4455#else4456#define INIT_SIGSETOPS4457#endif4458 4459#if SANITIZER_INTERCEPT_SIGSET_LOGICOPS4460INTERCEPTOR(int, sigandset, __sanitizer_sigset_t *dst,4461 __sanitizer_sigset_t *src1, __sanitizer_sigset_t *src2) {4462 void *ctx;4463 COMMON_INTERCEPTOR_ENTER(ctx, sigandset, dst, src1, src2);4464 if (src1)4465 COMMON_INTERCEPTOR_READ_RANGE(ctx, src1, sizeof(*src1));4466 if (src2)4467 COMMON_INTERCEPTOR_READ_RANGE(ctx, src2, sizeof(*src2));4468 int res = REAL(sigandset)(dst, src1, src2);4469 if (!res && dst)4470 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(*dst));4471 return res;4472}4473 4474INTERCEPTOR(int, sigorset, __sanitizer_sigset_t *dst,4475 __sanitizer_sigset_t *src1, __sanitizer_sigset_t *src2) {4476 void *ctx;4477 COMMON_INTERCEPTOR_ENTER(ctx, sigorset, dst, src1, src2);4478 if (src1)4479 COMMON_INTERCEPTOR_READ_RANGE(ctx, src1, sizeof(*src1));4480 if (src2)4481 COMMON_INTERCEPTOR_READ_RANGE(ctx, src2, sizeof(*src2));4482 int res = REAL(sigorset)(dst, src1, src2);4483 if (!res && dst)4484 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(*dst));4485 return res;4486}4487#define INIT_SIGSET_LOGICOPS \4488 COMMON_INTERCEPT_FUNCTION(sigandset); \4489 COMMON_INTERCEPT_FUNCTION(sigorset);4490#else4491#define INIT_SIGSET_LOGICOPS4492#endif4493 4494#if SANITIZER_INTERCEPT_SIGPENDING4495INTERCEPTOR(int, sigpending, __sanitizer_sigset_t *set) {4496 void *ctx;4497 COMMON_INTERCEPTOR_ENTER(ctx, sigpending, set);4498 // FIXME: under ASan the call below may write to freed memory and corrupt4499 // its metadata. See4500 // https://github.com/google/sanitizers/issues/321.4501 int res = REAL(sigpending)(set);4502 if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));4503 return res;4504}4505#define INIT_SIGPENDING COMMON_INTERCEPT_FUNCTION(sigpending);4506#else4507#define INIT_SIGPENDING4508#endif4509 4510#if SANITIZER_INTERCEPT_SIGPROCMASK4511INTERCEPTOR(int, sigprocmask, int how, __sanitizer_sigset_t *set,4512 __sanitizer_sigset_t *oldset) {4513 void *ctx;4514 COMMON_INTERCEPTOR_ENTER(ctx, sigprocmask, how, set, oldset);4515 if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));4516 // FIXME: under ASan the call below may write to freed memory and corrupt4517 // its metadata. See4518 // https://github.com/google/sanitizers/issues/321.4519 int res = REAL(sigprocmask)(how, set, oldset);4520 if (!res && oldset)4521 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset));4522 return res;4523}4524#define INIT_SIGPROCMASK COMMON_INTERCEPT_FUNCTION(sigprocmask);4525#else4526#define INIT_SIGPROCMASK4527#endif4528 4529#if SANITIZER_INTERCEPT_PTHREAD_SIGMASK4530INTERCEPTOR(int, pthread_sigmask, int how, __sanitizer_sigset_t *set,4531 __sanitizer_sigset_t *oldset) {4532 void *ctx;4533 COMMON_INTERCEPTOR_ENTER(ctx, pthread_sigmask, how, set, oldset);4534 if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));4535 // FIXME: under ASan the call below may write to freed memory and corrupt4536 // its metadata. See4537 // https://github.com/google/sanitizers/issues/321.4538 int res = REAL(pthread_sigmask)(how, set, oldset);4539 if (!res && oldset)4540 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset));4541 return res;4542}4543#define INIT_PTHREAD_SIGMASK COMMON_INTERCEPT_FUNCTION(pthread_sigmask);4544#else4545#define INIT_PTHREAD_SIGMASK4546#endif4547 4548#if SANITIZER_INTERCEPT_BACKTRACE4549INTERCEPTOR(int, backtrace, void **buffer, int size) {4550 void *ctx;4551 COMMON_INTERCEPTOR_ENTER(ctx, backtrace, buffer, size);4552 // 'buffer' might be freed memory, hence it is unsafe to directly call4553 // REAL(backtrace)(buffer, size). Instead, we use our own known-good4554 // scratch buffer.4555 void **scratch = (void**)InternalAlloc(sizeof(void*) * size);4556 int res = REAL(backtrace)(scratch, size);4557 if (res && buffer) {4558 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buffer, res * sizeof(*buffer));4559 internal_memcpy(buffer, scratch, res * sizeof(*buffer));4560 }4561 InternalFree(scratch);4562 return res;4563}4564 4565INTERCEPTOR(char **, backtrace_symbols, void **buffer, int size) {4566 void *ctx;4567 COMMON_INTERCEPTOR_ENTER(ctx, backtrace_symbols, buffer, size);4568 if (buffer && size)4569 COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, size * sizeof(*buffer));4570 // The COMMON_INTERCEPTOR_READ_RANGE above ensures that 'buffer' is4571 // valid for reading.4572 char **res = REAL(backtrace_symbols)(buffer, size);4573 if (res && size) {4574 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, size * sizeof(*res));4575 for (int i = 0; i < size; ++i)4576 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res[i], internal_strlen(res[i]) + 1);4577 }4578 return res;4579}4580#define INIT_BACKTRACE \4581 COMMON_INTERCEPT_FUNCTION(backtrace); \4582 COMMON_INTERCEPT_FUNCTION(backtrace_symbols);4583#else4584#define INIT_BACKTRACE4585#endif4586 4587#if SANITIZER_INTERCEPT__EXIT4588INTERCEPTOR(void, _exit, int status) {4589 void *ctx;4590 COMMON_INTERCEPTOR_ENTER(ctx, _exit, status);4591 COMMON_INTERCEPTOR_USER_CALLBACK_START();4592 int status1 = COMMON_INTERCEPTOR_ON_EXIT(ctx);4593 COMMON_INTERCEPTOR_USER_CALLBACK_END();4594 if (status == 0) status = status1;4595 REAL(_exit)(status);4596}4597#define INIT__EXIT COMMON_INTERCEPT_FUNCTION(_exit);4598#else4599#define INIT__EXIT4600#endif4601 4602#if SANITIZER_INTERCEPT___LIBC_MUTEX4603INTERCEPTOR(int, __libc_thr_setcancelstate, int state, int *oldstate)4604ALIAS(WRAP(pthread_setcancelstate));4605 4606#define INIT___LIBC_THR_SETCANCELSTATE \4607 COMMON_INTERCEPT_FUNCTION(__libc_thr_setcancelstate)4608#else4609#define INIT___LIBC_THR_SETCANCELSTATE4610#endif4611 4612#if SANITIZER_INTERCEPT_GETMNTENT || SANITIZER_INTERCEPT_GETMNTENT_R4613static void write_mntent(void *ctx, __sanitizer_mntent *mnt) {4614 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt, sizeof(*mnt));4615 if (mnt->mnt_fsname)4616 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_fsname,4617 internal_strlen(mnt->mnt_fsname) + 1);4618 if (mnt->mnt_dir)4619 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_dir,4620 internal_strlen(mnt->mnt_dir) + 1);4621 if (mnt->mnt_type)4622 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_type,4623 internal_strlen(mnt->mnt_type) + 1);4624 if (mnt->mnt_opts)4625 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_opts,4626 internal_strlen(mnt->mnt_opts) + 1);4627}4628#endif4629 4630#if SANITIZER_INTERCEPT_GETMNTENT4631INTERCEPTOR(__sanitizer_mntent *, getmntent, void *fp) {4632 void *ctx;4633 COMMON_INTERCEPTOR_ENTER(ctx, getmntent, fp);4634 __sanitizer_mntent *res = REAL(getmntent)(fp);4635 if (res) write_mntent(ctx, res);4636 return res;4637}4638#define INIT_GETMNTENT COMMON_INTERCEPT_FUNCTION(getmntent);4639#else4640#define INIT_GETMNTENT4641#endif4642 4643#if SANITIZER_INTERCEPT_GETMNTENT_R4644INTERCEPTOR(__sanitizer_mntent *, getmntent_r, void *fp,4645 __sanitizer_mntent *mntbuf, char *buf, int buflen) {4646 void *ctx;4647 COMMON_INTERCEPTOR_ENTER(ctx, getmntent_r, fp, mntbuf, buf, buflen);4648 __sanitizer_mntent *res = REAL(getmntent_r)(fp, mntbuf, buf, buflen);4649 if (res) write_mntent(ctx, res);4650 return res;4651}4652#define INIT_GETMNTENT_R COMMON_INTERCEPT_FUNCTION(getmntent_r);4653#else4654#define INIT_GETMNTENT_R4655#endif4656 4657#if SANITIZER_INTERCEPT_STATFS4658INTERCEPTOR(int, statfs, char *path, void *buf) {4659 void *ctx;4660 COMMON_INTERCEPTOR_ENTER(ctx, statfs, path, buf);4661 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);4662 // FIXME: under ASan the call below may write to freed memory and corrupt4663 // its metadata. See4664 // https://github.com/google/sanitizers/issues/321.4665 int res = REAL(statfs)(path, buf);4666 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz);4667 return res;4668}4669INTERCEPTOR(int, fstatfs, int fd, void *buf) {4670 void *ctx;4671 COMMON_INTERCEPTOR_ENTER(ctx, fstatfs, fd, buf);4672 // FIXME: under ASan the call below may write to freed memory and corrupt4673 // its metadata. See4674 // https://github.com/google/sanitizers/issues/321.4675 int res = REAL(fstatfs)(fd, buf);4676 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz);4677 return res;4678}4679#define INIT_STATFS \4680 COMMON_INTERCEPT_FUNCTION(statfs); \4681 COMMON_INTERCEPT_FUNCTION(fstatfs);4682#else4683#define INIT_STATFS4684#endif4685 4686#if SANITIZER_INTERCEPT_STATFS644687INTERCEPTOR(int, statfs64, char *path, void *buf) {4688 void *ctx;4689 COMMON_INTERCEPTOR_ENTER(ctx, statfs64, path, buf);4690 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);4691 // FIXME: under ASan the call below may write to freed memory and corrupt4692 // its metadata. See4693 // https://github.com/google/sanitizers/issues/321.4694 int res = REAL(statfs64)(path, buf);4695 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz);4696 return res;4697}4698INTERCEPTOR(int, fstatfs64, int fd, void *buf) {4699 void *ctx;4700 COMMON_INTERCEPTOR_ENTER(ctx, fstatfs64, fd, buf);4701 // FIXME: under ASan the call below may write to freed memory and corrupt4702 // its metadata. See4703 // https://github.com/google/sanitizers/issues/321.4704 int res = REAL(fstatfs64)(fd, buf);4705 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz);4706 return res;4707}4708#define INIT_STATFS64 \4709 COMMON_INTERCEPT_FUNCTION(statfs64); \4710 COMMON_INTERCEPT_FUNCTION(fstatfs64);4711#else4712#define INIT_STATFS644713#endif4714 4715#if SANITIZER_INTERCEPT_STATVFS4716INTERCEPTOR(int, statvfs, char *path, void *buf) {4717 void *ctx;4718 COMMON_INTERCEPTOR_ENTER(ctx, statvfs, path, buf);4719 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);4720 // FIXME: under ASan the call below may write to freed memory and corrupt4721 // its metadata. See4722 // https://github.com/google/sanitizers/issues/321.4723 int res = REAL(statvfs)(path, buf);4724 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);4725 return res;4726}4727INTERCEPTOR(int, fstatvfs, int fd, void *buf) {4728 void *ctx;4729 COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs, fd, buf);4730 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);4731 // FIXME: under ASan the call below may write to freed memory and corrupt4732 // its metadata. See4733 // https://github.com/google/sanitizers/issues/321.4734 int res = REAL(fstatvfs)(fd, buf);4735 if (!res) {4736 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);4737 if (fd >= 0)4738 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);4739 }4740 return res;4741}4742#define INIT_STATVFS \4743 COMMON_INTERCEPT_FUNCTION(statvfs); \4744 COMMON_INTERCEPT_FUNCTION(fstatvfs);4745#else4746#define INIT_STATVFS4747#endif4748 4749#if SANITIZER_INTERCEPT_STATVFS644750INTERCEPTOR(int, statvfs64, char *path, void *buf) {4751 void *ctx;4752 COMMON_INTERCEPTOR_ENTER(ctx, statvfs64, path, buf);4753 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);4754 // FIXME: under ASan the call below may write to freed memory and corrupt4755 // its metadata. See4756 // https://github.com/google/sanitizers/issues/321.4757 int res = REAL(statvfs64)(path, buf);4758 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz);4759 return res;4760}4761INTERCEPTOR(int, fstatvfs64, int fd, void *buf) {4762 void *ctx;4763 COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs64, fd, buf);4764 // FIXME: under ASan the call below may write to freed memory and corrupt4765 // its metadata. See4766 // https://github.com/google/sanitizers/issues/321.4767 int res = REAL(fstatvfs64)(fd, buf);4768 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz);4769 return res;4770}4771#define INIT_STATVFS64 \4772 COMMON_INTERCEPT_FUNCTION(statvfs64); \4773 COMMON_INTERCEPT_FUNCTION(fstatvfs64);4774#else4775#define INIT_STATVFS644776#endif4777 4778#if SANITIZER_INTERCEPT_INITGROUPS4779INTERCEPTOR(int, initgroups, char *user, u32 group) {4780 void *ctx;4781 COMMON_INTERCEPTOR_ENTER(ctx, initgroups, user, group);4782 if (user) COMMON_INTERCEPTOR_READ_RANGE(ctx, user, internal_strlen(user) + 1);4783 int res = REAL(initgroups)(user, group);4784 return res;4785}4786#define INIT_INITGROUPS COMMON_INTERCEPT_FUNCTION(initgroups);4787#else4788#define INIT_INITGROUPS4789#endif4790 4791#if SANITIZER_INTERCEPT_ETHER_NTOA_ATON4792INTERCEPTOR(char *, ether_ntoa, __sanitizer_ether_addr *addr) {4793 void *ctx;4794 COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa, addr);4795 if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));4796 char *res = REAL(ether_ntoa)(addr);4797 if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);4798 return res;4799}4800INTERCEPTOR(__sanitizer_ether_addr *, ether_aton, char *buf) {4801 void *ctx;4802 COMMON_INTERCEPTOR_ENTER(ctx, ether_aton, buf);4803 if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, internal_strlen(buf) + 1);4804 __sanitizer_ether_addr *res = REAL(ether_aton)(buf);4805 if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, sizeof(*res));4806 return res;4807}4808#define INIT_ETHER_NTOA_ATON \4809 COMMON_INTERCEPT_FUNCTION(ether_ntoa); \4810 COMMON_INTERCEPT_FUNCTION(ether_aton);4811#else4812#define INIT_ETHER_NTOA_ATON4813#endif4814 4815#if SANITIZER_INTERCEPT_ETHER_HOST4816INTERCEPTOR(int, ether_ntohost, char *hostname, __sanitizer_ether_addr *addr) {4817 void *ctx;4818 COMMON_INTERCEPTOR_ENTER(ctx, ether_ntohost, hostname, addr);4819 if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));4820 // FIXME: under ASan the call below may write to freed memory and corrupt4821 // its metadata. See4822 // https://github.com/google/sanitizers/issues/321.4823 int res = REAL(ether_ntohost)(hostname, addr);4824 if (!res && hostname)4825 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, internal_strlen(hostname) + 1);4826 return res;4827}4828INTERCEPTOR(int, ether_hostton, char *hostname, __sanitizer_ether_addr *addr) {4829 void *ctx;4830 COMMON_INTERCEPTOR_ENTER(ctx, ether_hostton, hostname, addr);4831 if (hostname)4832 COMMON_INTERCEPTOR_READ_RANGE(ctx, hostname, internal_strlen(hostname) + 1);4833 // FIXME: under ASan the call below may write to freed memory and corrupt4834 // its metadata. See4835 // https://github.com/google/sanitizers/issues/321.4836 int res = REAL(ether_hostton)(hostname, addr);4837 if (!res && addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));4838 return res;4839}4840INTERCEPTOR(int, ether_line, char *line, __sanitizer_ether_addr *addr,4841 char *hostname) {4842 void *ctx;4843 COMMON_INTERCEPTOR_ENTER(ctx, ether_line, line, addr, hostname);4844 if (line) COMMON_INTERCEPTOR_READ_RANGE(ctx, line, internal_strlen(line) + 1);4845 // FIXME: under ASan the call below may write to freed memory and corrupt4846 // its metadata. See4847 // https://github.com/google/sanitizers/issues/321.4848 int res = REAL(ether_line)(line, addr, hostname);4849 if (!res) {4850 if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));4851 if (hostname)4852 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, internal_strlen(hostname) + 1);4853 }4854 return res;4855}4856#define INIT_ETHER_HOST \4857 COMMON_INTERCEPT_FUNCTION(ether_ntohost); \4858 COMMON_INTERCEPT_FUNCTION(ether_hostton); \4859 COMMON_INTERCEPT_FUNCTION(ether_line);4860#else4861#define INIT_ETHER_HOST4862#endif4863 4864#if SANITIZER_INTERCEPT_ETHER_R4865INTERCEPTOR(char *, ether_ntoa_r, __sanitizer_ether_addr *addr, char *buf) {4866 void *ctx;4867 COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa_r, addr, buf);4868 if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));4869 // FIXME: under ASan the call below may write to freed memory and corrupt4870 // its metadata. See4871 // https://github.com/google/sanitizers/issues/321.4872 char *res = REAL(ether_ntoa_r)(addr, buf);4873 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);4874 return res;4875}4876INTERCEPTOR(__sanitizer_ether_addr *, ether_aton_r, char *buf,4877 __sanitizer_ether_addr *addr) {4878 void *ctx;4879 COMMON_INTERCEPTOR_ENTER(ctx, ether_aton_r, buf, addr);4880 if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, internal_strlen(buf) + 1);4881 // FIXME: under ASan the call below may write to freed memory and corrupt4882 // its metadata. See4883 // https://github.com/google/sanitizers/issues/321.4884 __sanitizer_ether_addr *res = REAL(ether_aton_r)(buf, addr);4885 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(*res));4886 return res;4887}4888#define INIT_ETHER_R \4889 COMMON_INTERCEPT_FUNCTION(ether_ntoa_r); \4890 COMMON_INTERCEPT_FUNCTION(ether_aton_r);4891#else4892#define INIT_ETHER_R4893#endif4894 4895#if SANITIZER_INTERCEPT_SHMCTL4896INTERCEPTOR(int, shmctl, int shmid, int cmd, void *buf) {4897 void *ctx;4898 COMMON_INTERCEPTOR_ENTER(ctx, shmctl, shmid, cmd, buf);4899 // FIXME: under ASan the call below may write to freed memory and corrupt4900 // its metadata. See4901 // https://github.com/google/sanitizers/issues/321.4902 int res = REAL(shmctl)(shmid, cmd, buf);4903 if (res >= 0) {4904 unsigned sz = 0;4905 if (cmd == shmctl_ipc_stat || cmd == shmctl_shm_stat)4906 sz = sizeof(__sanitizer_shmid_ds);4907 else if (cmd == shmctl_ipc_info)4908 sz = struct_shminfo_sz;4909 else if (cmd == shmctl_shm_info)4910 sz = struct_shm_info_sz;4911 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz);4912 }4913 return res;4914}4915#define INIT_SHMCTL COMMON_INTERCEPT_FUNCTION(shmctl);4916#else4917#define INIT_SHMCTL4918#endif4919 4920#if SANITIZER_INTERCEPT_RANDOM_R4921INTERCEPTOR(int, random_r, void *buf, u32 *result) {4922 void *ctx;4923 COMMON_INTERCEPTOR_ENTER(ctx, random_r, buf, result);4924 // FIXME: under ASan the call below may write to freed memory and corrupt4925 // its metadata. See4926 // https://github.com/google/sanitizers/issues/321.4927 int res = REAL(random_r)(buf, result);4928 if (!res && result)4929 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));4930 return res;4931}4932#define INIT_RANDOM_R COMMON_INTERCEPT_FUNCTION(random_r);4933#else4934#define INIT_RANDOM_R4935#endif4936 4937// FIXME: under ASan the REAL() call below may write to freed memory and corrupt4938// its metadata. See4939// https://github.com/google/sanitizers/issues/321.4940#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET || \4941 SANITIZER_INTERCEPT_PTHREAD_ATTR_GET_SCHED || \4942 SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSSCHED || \4943 SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GET || \4944 SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GET || \4945 SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GET || \4946 SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GET4947#define INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(fn, sz) \4948 INTERCEPTOR(int, fn, void *attr, void *r) { \4949 void *ctx; \4950 COMMON_INTERCEPTOR_ENTER(ctx, fn, attr, r); \4951 int res = REAL(fn)(attr, r); \4952 if (!res && r) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, r, sz); \4953 return res; \4954 }4955#define INTERCEPTOR_PTHREAD_ATTR_GET(what, sz) \4956 INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_attr_get##what, sz)4957#define INTERCEPTOR_PTHREAD_MUTEXATTR_GET(what, sz) \4958 INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_mutexattr_get##what, sz)4959#define INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(what, sz) \4960 INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_rwlockattr_get##what, sz)4961#define INTERCEPTOR_PTHREAD_CONDATTR_GET(what, sz) \4962 INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_condattr_get##what, sz)4963#define INTERCEPTOR_PTHREAD_BARRIERATTR_GET(what, sz) \4964 INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_barrierattr_get##what, sz)4965#endif4966 4967#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET4968INTERCEPTOR_PTHREAD_ATTR_GET(detachstate, sizeof(int))4969INTERCEPTOR_PTHREAD_ATTR_GET(guardsize, sizeof(SIZE_T))4970INTERCEPTOR_PTHREAD_ATTR_GET(scope, sizeof(int))4971INTERCEPTOR_PTHREAD_ATTR_GET(stacksize, sizeof(SIZE_T))4972INTERCEPTOR(int, pthread_attr_getstack, void *attr, void **addr, SIZE_T *size) {4973 void *ctx;4974 COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getstack, attr, addr, size);4975 // FIXME: under ASan the call below may write to freed memory and corrupt4976 // its metadata. See4977 // https://github.com/google/sanitizers/issues/321.4978 int res = REAL(pthread_attr_getstack)(attr, addr, size);4979 if (!res) {4980 if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));4981 if (size) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, size, sizeof(*size));4982 }4983 return res;4984}4985 4986// We may need to call the real pthread_attr_getstack from the run-time4987// in sanitizer_common, but we don't want to include the interception headers4988// there. So, just define this function here.4989namespace __sanitizer {4990extern "C" {4991int real_pthread_attr_getstack(void *attr, void **addr, SIZE_T *size) {4992 return REAL(pthread_attr_getstack)(attr, addr, size);4993}4994} // extern "C"4995} // namespace __sanitizer4996 4997#define INIT_PTHREAD_ATTR_GET \4998 COMMON_INTERCEPT_FUNCTION(pthread_attr_getdetachstate); \4999 COMMON_INTERCEPT_FUNCTION(pthread_attr_getguardsize); \5000 COMMON_INTERCEPT_FUNCTION(pthread_attr_getscope); \5001 COMMON_INTERCEPT_FUNCTION(pthread_attr_getstacksize); \5002 COMMON_INTERCEPT_FUNCTION(pthread_attr_getstack);5003#else5004#define INIT_PTHREAD_ATTR_GET5005#endif5006 5007#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET_SCHED5008INTERCEPTOR_PTHREAD_ATTR_GET(schedparam, struct_sched_param_sz)5009INTERCEPTOR_PTHREAD_ATTR_GET(schedpolicy, sizeof(int))5010 5011#define INIT_PTHREAD_ATTR_GET_SCHED \5012 COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedparam); \5013 COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedpolicy);5014#else5015#define INIT_PTHREAD_ATTR_GET_SCHED5016#endif5017 5018#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSCHED5019INTERCEPTOR_PTHREAD_ATTR_GET(inheritsched, sizeof(int))5020 5021#define INIT_PTHREAD_ATTR_GETINHERITSCHED \5022 COMMON_INTERCEPT_FUNCTION(pthread_attr_getinheritsched);5023#else5024#define INIT_PTHREAD_ATTR_GETINHERITSCHED5025#endif5026 5027#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETAFFINITY_NP5028INTERCEPTOR(int, pthread_attr_getaffinity_np, void *attr, SIZE_T cpusetsize,5029 void *cpuset) {5030 void *ctx;5031 COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getaffinity_np, attr, cpusetsize,5032 cpuset);5033 // FIXME: under ASan the call below may write to freed memory and corrupt5034 // its metadata. See5035 // https://github.com/google/sanitizers/issues/321.5036 int res = REAL(pthread_attr_getaffinity_np)(attr, cpusetsize, cpuset);5037 if (!res && cpusetsize && cpuset)5038 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cpuset, cpusetsize);5039 return res;5040}5041 5042#define INIT_PTHREAD_ATTR_GETAFFINITY_NP \5043 COMMON_INTERCEPT_FUNCTION(pthread_attr_getaffinity_np);5044#else5045#define INIT_PTHREAD_ATTR_GETAFFINITY_NP5046#endif5047 5048#if SANITIZER_INTERCEPT_PTHREAD_GETAFFINITY_NP5049INTERCEPTOR(int, pthread_getaffinity_np, void *attr, SIZE_T cpusetsize,5050 void *cpuset) {5051 void *ctx;5052 COMMON_INTERCEPTOR_ENTER(ctx, pthread_getaffinity_np, attr, cpusetsize,5053 cpuset);5054 // FIXME: under ASan the call below may write to freed memory and corrupt5055 // its metadata. See5056 // https://github.com/google/sanitizers/issues/321.5057 int res = REAL(pthread_getaffinity_np)(attr, cpusetsize, cpuset);5058 if (!res && cpusetsize && cpuset)5059 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cpuset, cpusetsize);5060 return res;5061}5062 5063#define INIT_PTHREAD_GETAFFINITY_NP \5064 COMMON_INTERCEPT_FUNCTION(pthread_getaffinity_np);5065#else5066#define INIT_PTHREAD_GETAFFINITY_NP5067#endif5068 5069#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPSHARED5070INTERCEPTOR_PTHREAD_MUTEXATTR_GET(pshared, sizeof(int))5071#define INIT_PTHREAD_MUTEXATTR_GETPSHARED \5072 COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getpshared);5073#else5074#define INIT_PTHREAD_MUTEXATTR_GETPSHARED5075#endif5076 5077#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETTYPE5078INTERCEPTOR_PTHREAD_MUTEXATTR_GET(type, sizeof(int))5079#define INIT_PTHREAD_MUTEXATTR_GETTYPE \5080 COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_gettype);5081#else5082#define INIT_PTHREAD_MUTEXATTR_GETTYPE5083#endif5084 5085#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPROTOCOL5086INTERCEPTOR_PTHREAD_MUTEXATTR_GET(protocol, sizeof(int))5087#define INIT_PTHREAD_MUTEXATTR_GETPROTOCOL \5088 COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getprotocol);5089#else5090#define INIT_PTHREAD_MUTEXATTR_GETPROTOCOL5091#endif5092 5093#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPRIOCEILING5094INTERCEPTOR_PTHREAD_MUTEXATTR_GET(prioceiling, sizeof(int))5095#define INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING \5096 COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getprioceiling);5097#else5098#define INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING5099#endif5100 5101#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST5102INTERCEPTOR_PTHREAD_MUTEXATTR_GET(robust, sizeof(int))5103#define INIT_PTHREAD_MUTEXATTR_GETROBUST \5104 COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getrobust);5105#else5106#define INIT_PTHREAD_MUTEXATTR_GETROBUST5107#endif5108 5109#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST_NP5110INTERCEPTOR_PTHREAD_MUTEXATTR_GET(robust_np, sizeof(int))5111#define INIT_PTHREAD_MUTEXATTR_GETROBUST_NP \5112 COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getrobust_np);5113#else5114#define INIT_PTHREAD_MUTEXATTR_GETROBUST_NP5115#endif5116 5117#if SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETPSHARED5118INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(pshared, sizeof(int))5119#define INIT_PTHREAD_RWLOCKATTR_GETPSHARED \5120 COMMON_INTERCEPT_FUNCTION(pthread_rwlockattr_getpshared);5121#else5122#define INIT_PTHREAD_RWLOCKATTR_GETPSHARED5123#endif5124 5125#if SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETKIND_NP5126INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(kind_np, sizeof(int))5127#define INIT_PTHREAD_RWLOCKATTR_GETKIND_NP \5128 COMMON_INTERCEPT_FUNCTION(pthread_rwlockattr_getkind_np);5129#else5130#define INIT_PTHREAD_RWLOCKATTR_GETKIND_NP5131#endif5132 5133#if SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETPSHARED5134INTERCEPTOR_PTHREAD_CONDATTR_GET(pshared, sizeof(int))5135#define INIT_PTHREAD_CONDATTR_GETPSHARED \5136 COMMON_INTERCEPT_FUNCTION(pthread_condattr_getpshared);5137#else5138#define INIT_PTHREAD_CONDATTR_GETPSHARED5139#endif5140 5141#if SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETCLOCK5142INTERCEPTOR_PTHREAD_CONDATTR_GET(clock, sizeof(int))5143#define INIT_PTHREAD_CONDATTR_GETCLOCK \5144 COMMON_INTERCEPT_FUNCTION(pthread_condattr_getclock);5145#else5146#define INIT_PTHREAD_CONDATTR_GETCLOCK5147#endif5148 5149#if SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GETPSHARED5150INTERCEPTOR_PTHREAD_BARRIERATTR_GET(pshared, sizeof(int)) // !mac !android5151#define INIT_PTHREAD_BARRIERATTR_GETPSHARED \5152 COMMON_INTERCEPT_FUNCTION(pthread_barrierattr_getpshared);5153#else5154#define INIT_PTHREAD_BARRIERATTR_GETPSHARED5155#endif5156 5157#if SANITIZER_INTERCEPT_TMPNAM5158INTERCEPTOR(char *, tmpnam, char *s) {5159 void *ctx;5160 COMMON_INTERCEPTOR_ENTER(ctx, tmpnam, s);5161 char *res = REAL(tmpnam)(s);5162 if (res) {5163 if (s)5164 // FIXME: under ASan the call below may write to freed memory and corrupt5165 // its metadata. See5166 // https://github.com/google/sanitizers/issues/321.5167 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, internal_strlen(s) + 1);5168 else5169 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);5170 }5171 return res;5172}5173#define INIT_TMPNAM COMMON_INTERCEPT_FUNCTION(tmpnam);5174#else5175#define INIT_TMPNAM5176#endif5177 5178#if SANITIZER_INTERCEPT_TMPNAM_R5179INTERCEPTOR(char *, tmpnam_r, char *s) {5180 void *ctx;5181 COMMON_INTERCEPTOR_ENTER(ctx, tmpnam_r, s);5182 // FIXME: under ASan the call below may write to freed memory and corrupt5183 // its metadata. See5184 // https://github.com/google/sanitizers/issues/321.5185 char *res = REAL(tmpnam_r)(s);5186 if (res && s) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, internal_strlen(s) + 1);5187 return res;5188}5189#define INIT_TMPNAM_R COMMON_INTERCEPT_FUNCTION(tmpnam_r);5190#else5191#define INIT_TMPNAM_R5192#endif5193 5194#if SANITIZER_INTERCEPT_PTSNAME5195INTERCEPTOR(char *, ptsname, int fd) {5196 void *ctx;5197 COMMON_INTERCEPTOR_ENTER(ctx, ptsname, fd);5198 char *res = REAL(ptsname)(fd);5199 if (res != nullptr)5200 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);5201 return res;5202}5203#define INIT_PTSNAME COMMON_INTERCEPT_FUNCTION(ptsname);5204#else5205#define INIT_PTSNAME5206#endif5207 5208#if SANITIZER_INTERCEPT_PTSNAME_R5209INTERCEPTOR(int, ptsname_r, int fd, char *name, SIZE_T namesize) {5210 void *ctx;5211 COMMON_INTERCEPTOR_ENTER(ctx, ptsname_r, fd, name, namesize);5212 int res = REAL(ptsname_r)(fd, name, namesize);5213 if (res == 0)5214 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, internal_strlen(name) + 1);5215 return res;5216}5217#define INIT_PTSNAME_R COMMON_INTERCEPT_FUNCTION(ptsname_r);5218#else5219#define INIT_PTSNAME_R5220#endif5221 5222#if SANITIZER_INTERCEPT_TTYNAME5223INTERCEPTOR(char *, ttyname, int fd) {5224 void *ctx;5225 COMMON_INTERCEPTOR_ENTER(ctx, ttyname, fd);5226 char *res = REAL(ttyname)(fd);5227 if (res != nullptr)5228 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);5229 return res;5230}5231#define INIT_TTYNAME COMMON_INTERCEPT_FUNCTION(ttyname);5232#else5233#define INIT_TTYNAME5234#endif5235 5236#if SANITIZER_INTERCEPT_TTYNAME_R5237INTERCEPTOR(int, ttyname_r, int fd, char *name, SIZE_T namesize) {5238 void *ctx;5239 COMMON_INTERCEPTOR_ENTER(ctx, ttyname_r, fd, name, namesize);5240 int res = REAL(ttyname_r)(fd, name, namesize);5241 if (res == 0)5242 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, internal_strlen(name) + 1);5243 return res;5244}5245#define INIT_TTYNAME_R COMMON_INTERCEPT_FUNCTION(ttyname_r);5246#else5247#define INIT_TTYNAME_R5248#endif5249 5250#if SANITIZER_INTERCEPT_TEMPNAM5251INTERCEPTOR(char *, tempnam, char *dir, char *pfx) {5252 void *ctx;5253 COMMON_INTERCEPTOR_ENTER(ctx, tempnam, dir, pfx);5254 if (dir) COMMON_INTERCEPTOR_READ_RANGE(ctx, dir, internal_strlen(dir) + 1);5255 if (pfx) COMMON_INTERCEPTOR_READ_RANGE(ctx, pfx, internal_strlen(pfx) + 1);5256 char *res = REAL(tempnam)(dir, pfx);5257 if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);5258 return res;5259}5260#define INIT_TEMPNAM COMMON_INTERCEPT_FUNCTION(tempnam);5261#else5262#define INIT_TEMPNAM5263#endif5264 5265#if SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP && !SANITIZER_NETBSD5266INTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name) {5267 void *ctx;5268 COMMON_INTERCEPTOR_ENTER(ctx, pthread_setname_np, thread, name);5269 COMMON_INTERCEPTOR_READ_STRING(ctx, name, 0);5270 COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name);5271 return REAL(pthread_setname_np)(thread, name);5272}5273#define INIT_PTHREAD_SETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_setname_np);5274#elif SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP && SANITIZER_NETBSD5275INTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name, void *arg) {5276 void *ctx;5277 char newname[32]; // PTHREAD_MAX_NAMELEN_NP=325278 COMMON_INTERCEPTOR_ENTER(ctx, pthread_setname_np, thread, name, arg);5279 COMMON_INTERCEPTOR_READ_STRING(ctx, name, 0);5280 internal_snprintf(newname, sizeof(newname), name, arg);5281 COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, newname);5282 return REAL(pthread_setname_np)(thread, name, arg);5283}5284#define INIT_PTHREAD_SETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_setname_np);5285#else5286#define INIT_PTHREAD_SETNAME_NP5287#endif5288 5289#if SANITIZER_INTERCEPT_PTHREAD_GETNAME_NP5290INTERCEPTOR(int, pthread_getname_np, uptr thread, char *name, SIZE_T len) {5291 void *ctx;5292 COMMON_INTERCEPTOR_ENTER(ctx, pthread_getname_np, thread, name, len);5293 int res = REAL(pthread_getname_np)(thread, name, len);5294 if (!res)5295 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, internal_strnlen(name, len) + 1);5296 return res;5297}5298#define INIT_PTHREAD_GETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_getname_np);5299#else5300#define INIT_PTHREAD_GETNAME_NP5301#endif5302 5303#if SANITIZER_INTERCEPT_SINCOS5304INTERCEPTOR(void, sincos, double x, double *sin, double *cos) {5305 void *ctx;5306 COMMON_INTERCEPTOR_ENTER(ctx, sincos, x, sin, cos);5307 // FIXME: under ASan the call below may write to freed memory and corrupt5308 // its metadata. See5309 // https://github.com/google/sanitizers/issues/321.5310 REAL(sincos)(x, sin, cos);5311 if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));5312 if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));5313}5314INTERCEPTOR(void, sincosf, float x, float *sin, float *cos) {5315 void *ctx;5316 COMMON_INTERCEPTOR_ENTER(ctx, sincosf, x, sin, cos);5317 // FIXME: under ASan the call below may write to freed memory and corrupt5318 // its metadata. See5319 // https://github.com/google/sanitizers/issues/321.5320 REAL(sincosf)(x, sin, cos);5321 if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));5322 if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));5323}5324INTERCEPTOR(void, sincosl, long double x, long double *sin, long double *cos) {5325 void *ctx;5326 COMMON_INTERCEPTOR_ENTER(ctx, sincosl, x, sin, cos);5327 // FIXME: under ASan the call below may write to freed memory and corrupt5328 // its metadata. See5329 // https://github.com/google/sanitizers/issues/321.5330 REAL(sincosl)(x, sin, cos);5331 if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));5332 if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));5333}5334#define INIT_SINCOS \5335 COMMON_INTERCEPT_FUNCTION(sincos); \5336 COMMON_INTERCEPT_FUNCTION(sincosf); \5337 COMMON_INTERCEPT_FUNCTION_LDBL(sincosl);5338#else5339#define INIT_SINCOS5340#endif5341 5342#if SANITIZER_INTERCEPT_REMQUO5343INTERCEPTOR(double, remquo, double x, double y, int *quo) {5344 void *ctx;5345 COMMON_INTERCEPTOR_ENTER(ctx, remquo, x, y, quo);5346 // FIXME: under ASan the call below may write to freed memory and corrupt5347 // its metadata. See5348 // https://github.com/google/sanitizers/issues/321.5349 double res = REAL(remquo)(x, y, quo);5350 if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));5351 return res;5352}5353INTERCEPTOR(float, remquof, float x, float y, int *quo) {5354 void *ctx;5355 COMMON_INTERCEPTOR_ENTER(ctx, remquof, x, y, quo);5356 // FIXME: under ASan the call below may write to freed memory and corrupt5357 // its metadata. See5358 // https://github.com/google/sanitizers/issues/321.5359 float res = REAL(remquof)(x, y, quo);5360 if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));5361 return res;5362}5363#define INIT_REMQUO \5364 COMMON_INTERCEPT_FUNCTION(remquo); \5365 COMMON_INTERCEPT_FUNCTION(remquof);5366#else5367#define INIT_REMQUO5368#endif5369 5370#if SANITIZER_INTERCEPT_REMQUOL5371INTERCEPTOR(long double, remquol, long double x, long double y, int *quo) {5372 void *ctx;5373 COMMON_INTERCEPTOR_ENTER(ctx, remquol, x, y, quo);5374 // FIXME: under ASan the call below may write to freed memory and corrupt5375 // its metadata. See5376 // https://github.com/google/sanitizers/issues/321.5377 long double res = REAL(remquol)(x, y, quo);5378 if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));5379 return res;5380}5381#define INIT_REMQUOL \5382 COMMON_INTERCEPT_FUNCTION_LDBL(remquol);5383#else5384#define INIT_REMQUOL5385#endif5386 5387#if SANITIZER_INTERCEPT_LGAMMA5388extern int signgam;5389INTERCEPTOR(double, lgamma, double x) {5390 void *ctx;5391 COMMON_INTERCEPTOR_ENTER(ctx, lgamma, x);5392 double res = REAL(lgamma)(x);5393 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));5394 return res;5395}5396INTERCEPTOR(float, lgammaf, float x) {5397 void *ctx;5398 COMMON_INTERCEPTOR_ENTER(ctx, lgammaf, x);5399 float res = REAL(lgammaf)(x);5400 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));5401 return res;5402}5403#define INIT_LGAMMA \5404 COMMON_INTERCEPT_FUNCTION(lgamma); \5405 COMMON_INTERCEPT_FUNCTION(lgammaf);5406#else5407#define INIT_LGAMMA5408#endif5409 5410#if SANITIZER_INTERCEPT_LGAMMAL5411INTERCEPTOR(long double, lgammal, long double x) {5412 void *ctx;5413 COMMON_INTERCEPTOR_ENTER(ctx, lgammal, x);5414 long double res = REAL(lgammal)(x);5415 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));5416 return res;5417}5418#define INIT_LGAMMAL \5419 COMMON_INTERCEPT_FUNCTION_LDBL(lgammal);5420#else5421#define INIT_LGAMMAL5422#endif5423 5424#if SANITIZER_INTERCEPT_LGAMMA_R5425INTERCEPTOR(double, lgamma_r, double x, int *signp) {5426 void *ctx;5427 COMMON_INTERCEPTOR_ENTER(ctx, lgamma_r, x, signp);5428 // FIXME: under ASan the call below may write to freed memory and corrupt5429 // its metadata. See5430 // https://github.com/google/sanitizers/issues/321.5431 double res = REAL(lgamma_r)(x, signp);5432 if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));5433 return res;5434}5435INTERCEPTOR(float, lgammaf_r, float x, int *signp) {5436 void *ctx;5437 COMMON_INTERCEPTOR_ENTER(ctx, lgammaf_r, x, signp);5438 // FIXME: under ASan the call below may write to freed memory and corrupt5439 // its metadata. See5440 // https://github.com/google/sanitizers/issues/321.5441 float res = REAL(lgammaf_r)(x, signp);5442 if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));5443 return res;5444}5445#define INIT_LGAMMA_R \5446 COMMON_INTERCEPT_FUNCTION(lgamma_r); \5447 COMMON_INTERCEPT_FUNCTION(lgammaf_r);5448#else5449#define INIT_LGAMMA_R5450#endif5451 5452#if SANITIZER_INTERCEPT_LGAMMAL_R5453INTERCEPTOR(long double, lgammal_r, long double x, int *signp) {5454 void *ctx;5455 COMMON_INTERCEPTOR_ENTER(ctx, lgammal_r, x, signp);5456 // FIXME: under ASan the call below may write to freed memory and corrupt5457 // its metadata. See5458 // https://github.com/google/sanitizers/issues/321.5459 long double res = REAL(lgammal_r)(x, signp);5460 if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));5461 return res;5462}5463#define INIT_LGAMMAL_R COMMON_INTERCEPT_FUNCTION_LDBL(lgammal_r);5464#else5465#define INIT_LGAMMAL_R5466#endif5467 5468#if SANITIZER_INTERCEPT_DRAND48_R5469INTERCEPTOR(int, drand48_r, void *buffer, double *result) {5470 void *ctx;5471 COMMON_INTERCEPTOR_ENTER(ctx, drand48_r, buffer, result);5472 // FIXME: under ASan the call below may write to freed memory and corrupt5473 // its metadata. See5474 // https://github.com/google/sanitizers/issues/321.5475 int res = REAL(drand48_r)(buffer, result);5476 if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));5477 return res;5478}5479INTERCEPTOR(int, lrand48_r, void *buffer, long *result) {5480 void *ctx;5481 COMMON_INTERCEPTOR_ENTER(ctx, lrand48_r, buffer, result);5482 // FIXME: under ASan the call below may write to freed memory and corrupt5483 // its metadata. See5484 // https://github.com/google/sanitizers/issues/321.5485 int res = REAL(lrand48_r)(buffer, result);5486 if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));5487 return res;5488}5489#define INIT_DRAND48_R \5490 COMMON_INTERCEPT_FUNCTION(drand48_r); \5491 COMMON_INTERCEPT_FUNCTION(lrand48_r);5492#else5493#define INIT_DRAND48_R5494#endif5495 5496#if SANITIZER_INTERCEPT_RAND_R5497INTERCEPTOR(int, rand_r, unsigned *seedp) {5498 void *ctx;5499 COMMON_INTERCEPTOR_ENTER(ctx, rand_r, seedp);5500 COMMON_INTERCEPTOR_READ_RANGE(ctx, seedp, sizeof(*seedp));5501 return REAL(rand_r)(seedp);5502}5503#define INIT_RAND_R COMMON_INTERCEPT_FUNCTION(rand_r);5504#else5505#define INIT_RAND_R5506#endif5507 5508#if SANITIZER_INTERCEPT_GETLINE5509INTERCEPTOR(SSIZE_T, getline, char **lineptr, SIZE_T *n, void *stream) {5510 void *ctx;5511 COMMON_INTERCEPTOR_ENTER(ctx, getline, lineptr, n, stream);5512 // FIXME: under ASan the call below may write to freed memory and corrupt5513 // its metadata. See5514 // https://github.com/google/sanitizers/issues/321.5515 SSIZE_T res = REAL(getline)(lineptr, n, stream);5516 if (res > 0) {5517 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr));5518 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));5519 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1);5520 }5521 return res;5522}5523 5524// FIXME: under ASan the call below may write to freed memory and corrupt its5525// metadata. See5526// https://github.com/google/sanitizers/issues/321.5527#define GETDELIM_INTERCEPTOR_IMPL(vname) \5528 { \5529 void *ctx; \5530 COMMON_INTERCEPTOR_ENTER(ctx, vname, lineptr, n, delim, stream); \5531 SSIZE_T res = REAL(vname)(lineptr, n, delim, stream); \5532 if (res > 0) { \5533 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr)); \5534 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n)); \5535 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1); \5536 } \5537 return res; \5538 }5539 5540INTERCEPTOR(SSIZE_T, __getdelim, char **lineptr, SIZE_T *n, int delim,5541 void *stream)5542GETDELIM_INTERCEPTOR_IMPL(__getdelim)5543 5544// There's no __getdelim() on FreeBSD so we supply the getdelim() interceptor5545// with its own body.5546INTERCEPTOR(SSIZE_T, getdelim, char **lineptr, SIZE_T *n, int delim,5547 void *stream)5548GETDELIM_INTERCEPTOR_IMPL(getdelim)5549 5550#define INIT_GETLINE \5551 COMMON_INTERCEPT_FUNCTION(getline); \5552 COMMON_INTERCEPT_FUNCTION(__getdelim); \5553 COMMON_INTERCEPT_FUNCTION(getdelim);5554#else5555#define INIT_GETLINE5556#endif5557 5558#if SANITIZER_INTERCEPT_ICONV5559INTERCEPTOR(SIZE_T, iconv, void *cd, char **inbuf, SIZE_T *inbytesleft,5560 char **outbuf, SIZE_T *outbytesleft) {5561 void *ctx;5562 COMMON_INTERCEPTOR_ENTER(ctx, iconv, cd, inbuf, inbytesleft, outbuf,5563 outbytesleft);5564 if (inbytesleft)5565 COMMON_INTERCEPTOR_READ_RANGE(ctx, inbytesleft, sizeof(*inbytesleft));5566 if (inbuf && inbytesleft)5567 COMMON_INTERCEPTOR_READ_RANGE(ctx, *inbuf, *inbytesleft);5568 if (outbytesleft)5569 COMMON_INTERCEPTOR_READ_RANGE(ctx, outbytesleft, sizeof(*outbytesleft));5570 void *outbuf_orig = outbuf ? *outbuf : nullptr;5571 // FIXME: under ASan the call below may write to freed memory and corrupt5572 // its metadata. See5573 // https://github.com/google/sanitizers/issues/321.5574 SIZE_T res = REAL(iconv)(cd, inbuf, inbytesleft, outbuf, outbytesleft);5575 if (outbuf && *outbuf > outbuf_orig) {5576 SIZE_T sz = (char *)*outbuf - (char *)outbuf_orig;5577 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, outbuf_orig, sz);5578 }5579 return res;5580}5581#define INIT_ICONV COMMON_INTERCEPT_FUNCTION(iconv);5582#else5583#define INIT_ICONV5584#endif5585 5586#if SANITIZER_INTERCEPT_TIMES5587INTERCEPTOR(__sanitizer_clock_t, times, void *tms) {5588 void *ctx;5589 COMMON_INTERCEPTOR_ENTER(ctx, times, tms);5590 // FIXME: under ASan the call below may write to freed memory and corrupt5591 // its metadata. See5592 // https://github.com/google/sanitizers/issues/321.5593 __sanitizer_clock_t res = REAL(times)(tms);5594 if (res != (__sanitizer_clock_t)-1 && tms)5595 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tms, struct_tms_sz);5596 return res;5597}5598#define INIT_TIMES COMMON_INTERCEPT_FUNCTION(times);5599#else5600#define INIT_TIMES5601#endif5602 5603#if SANITIZER_S390 && \5604 (SANITIZER_INTERCEPT_TLS_GET_ADDR || SANITIZER_INTERCEPT_TLS_GET_OFFSET)5605extern "C" uptr __tls_get_offset_wrapper(void *arg, uptr (*fn)(void *arg));5606DEFINE_REAL(uptr, __tls_get_offset, void *arg)5607#endif5608 5609#if SANITIZER_INTERCEPT_TLS_GET_ADDR5610#if !SANITIZER_S3905611#define INIT_TLS_GET_ADDR COMMON_INTERCEPT_FUNCTION(__tls_get_addr)5612// If you see any crashes around this functions, there are 2 known issues with5613// it: 1. __tls_get_addr can be called with mis-aligned stack due to:5614// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=580665615// 2. It can be called recursively if sanitizer code uses __tls_get_addr5616// to access thread local variables (it should not happen normally,5617// because sanitizers use initial-exec tls model).5618INTERCEPTOR(void *, __tls_get_addr, void *arg) {5619 void *ctx;5620 COMMON_INTERCEPTOR_ENTER(ctx, __tls_get_addr, arg);5621 void *res = REAL(__tls_get_addr)(arg);5622 uptr tls_begin, tls_end;5623 COMMON_INTERCEPTOR_GET_TLS_RANGE(&tls_begin, &tls_end);5624 DTLS::DTV *dtv = DTLS_on_tls_get_addr(arg, res, tls_begin, tls_end);5625 if (dtv) {5626 // New DTLS block has been allocated.5627 COMMON_INTERCEPTOR_INITIALIZE_RANGE((void *)dtv->beg, dtv->size);5628 }5629 return res;5630}5631#if SANITIZER_PPC5632// On PowerPC, we also need to intercept __tls_get_addr_opt, which has5633// mostly the same semantics as __tls_get_addr, but its presence enables5634// some optimizations in linker (which are safe to ignore here).5635INTERCEPTOR(void *, __tls_get_addr_opt, void *arg) ALIAS(WRAP(__tls_get_addr));5636#endif5637#else // SANITIZER_S3905638// On s390, we have to intercept two functions here:5639// - __tls_get_addr_internal, which is a glibc-internal function that is like5640// the usual __tls_get_addr, but returns a TP-relative offset instead of5641// a proper pointer. It is used by dlsym for TLS symbols.5642// - __tls_get_offset, which is like the above, but also takes a GOT-relative5643// descriptor offset as an argument instead of a pointer. GOT address5644// is passed in r12, so it's necessary to write it in assembly. This is5645// the function used by the compiler.5646#define INIT_TLS_GET_ADDR COMMON_INTERCEPT_FUNCTION(__tls_get_offset)5647INTERCEPTOR(uptr, __tls_get_addr_internal, void *arg) {5648 void *ctx;5649 COMMON_INTERCEPTOR_ENTER(ctx, __tls_get_addr_internal, arg);5650 uptr res = __tls_get_offset_wrapper(arg, REAL(__tls_get_offset));5651 uptr tp = reinterpret_cast<uptr>(__builtin_thread_pointer());5652 void *ptr = reinterpret_cast<void *>(res + tp);5653 uptr tls_begin, tls_end;5654 COMMON_INTERCEPTOR_GET_TLS_RANGE(&tls_begin, &tls_end);5655 DTLS::DTV *dtv = DTLS_on_tls_get_addr(arg, ptr, tls_begin, tls_end);5656 if (dtv) {5657 // New DTLS block has been allocated.5658 COMMON_INTERCEPTOR_INITIALIZE_RANGE((void *)dtv->beg, dtv->size);5659 }5660 return res;5661}5662#endif // SANITIZER_S3905663#else5664#define INIT_TLS_GET_ADDR5665#endif5666 5667#if SANITIZER_S390 && \5668 (SANITIZER_INTERCEPT_TLS_GET_ADDR || SANITIZER_INTERCEPT_TLS_GET_OFFSET)5669// We need a hidden symbol aliasing the above, so that we can jump5670// directly to it from the assembly below.5671extern "C" __attribute__((visibility("hidden"))) uptr __tls_get_addr_hidden(5672 void *arg) ALIAS(WRAP(__tls_get_addr_internal));5673extern "C" uptr __tls_get_offset(void *arg);5674extern "C" uptr TRAMPOLINE(__tls_get_offset)(void *arg);5675extern "C" uptr WRAP(__tls_get_offset)(void *arg);5676// Now carefully intercept __tls_get_offset.5677asm(5678 ".text\n"5679// The __intercept_ version has to exist, so that gen_dynamic_list.py5680// exports our symbol.5681 ".weak __tls_get_offset\n"5682 ".set __tls_get_offset, __interceptor___tls_get_offset\n"5683 ".global __interceptor___tls_get_offset\n"5684 ".type __interceptor___tls_get_offset, @function\n"5685 "__interceptor___tls_get_offset:\n"5686#ifdef __s390x__5687 "la %r2, 0(%r2,%r12)\n"5688 "jg __tls_get_addr_hidden\n"5689#else5690 "basr %r3,0\n"5691 "0: la %r2,0(%r2,%r12)\n"5692 "l %r4,1f-0b(%r3)\n"5693 "b 0(%r4,%r3)\n"5694 "1: .long __tls_get_addr_hidden - 0b\n"5695#endif5696 ".size __interceptor___tls_get_offset, .-__interceptor___tls_get_offset\n"5697// Assembly wrapper to call REAL(__tls_get_offset)(arg)5698 ".type __tls_get_offset_wrapper, @function\n"5699 "__tls_get_offset_wrapper:\n"5700#ifdef __s390x__5701 "sgr %r2,%r12\n"5702#else5703 "sr %r2,%r12\n"5704#endif5705 "br %r3\n"5706 ".size __tls_get_offset_wrapper, .-__tls_get_offset_wrapper\n"5707);5708#endif5709 5710#if SANITIZER_INTERCEPT_LISTXATTR5711INTERCEPTOR(SSIZE_T, listxattr, const char *path, char *list, SIZE_T size) {5712 void *ctx;5713 COMMON_INTERCEPTOR_ENTER(ctx, listxattr, path, list, size);5714 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);5715 // FIXME: under ASan the call below may write to freed memory and corrupt5716 // its metadata. See5717 // https://github.com/google/sanitizers/issues/321.5718 SSIZE_T res = REAL(listxattr)(path, list, size);5719 // Here and below, size == 0 is a special case where nothing is written to the5720 // buffer, and res contains the desired buffer size.5721 if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);5722 return res;5723}5724INTERCEPTOR(SSIZE_T, llistxattr, const char *path, char *list, SIZE_T size) {5725 void *ctx;5726 COMMON_INTERCEPTOR_ENTER(ctx, llistxattr, path, list, size);5727 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);5728 // FIXME: under ASan the call below may write to freed memory and corrupt5729 // its metadata. See5730 // https://github.com/google/sanitizers/issues/321.5731 SSIZE_T res = REAL(llistxattr)(path, list, size);5732 if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);5733 return res;5734}5735INTERCEPTOR(SSIZE_T, flistxattr, int fd, char *list, SIZE_T size) {5736 void *ctx;5737 COMMON_INTERCEPTOR_ENTER(ctx, flistxattr, fd, list, size);5738 // FIXME: under ASan the call below may write to freed memory and corrupt5739 // its metadata. See5740 // https://github.com/google/sanitizers/issues/321.5741 SSIZE_T res = REAL(flistxattr)(fd, list, size);5742 if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);5743 return res;5744}5745#define INIT_LISTXATTR \5746 COMMON_INTERCEPT_FUNCTION(listxattr); \5747 COMMON_INTERCEPT_FUNCTION(llistxattr); \5748 COMMON_INTERCEPT_FUNCTION(flistxattr);5749#else5750#define INIT_LISTXATTR5751#endif5752 5753#if SANITIZER_INTERCEPT_GETXATTR5754INTERCEPTOR(SSIZE_T, getxattr, const char *path, const char *name, char *value,5755 SIZE_T size) {5756 void *ctx;5757 COMMON_INTERCEPTOR_ENTER(ctx, getxattr, path, name, value, size);5758 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);5759 if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);5760 // FIXME: under ASan the call below may write to freed memory and corrupt5761 // its metadata. See5762 // https://github.com/google/sanitizers/issues/321.5763 SSIZE_T res = REAL(getxattr)(path, name, value, size);5764 if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);5765 return res;5766}5767INTERCEPTOR(SSIZE_T, lgetxattr, const char *path, const char *name, char *value,5768 SIZE_T size) {5769 void *ctx;5770 COMMON_INTERCEPTOR_ENTER(ctx, lgetxattr, path, name, value, size);5771 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);5772 if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);5773 // FIXME: under ASan the call below may write to freed memory and corrupt5774 // its metadata. See5775 // https://github.com/google/sanitizers/issues/321.5776 SSIZE_T res = REAL(lgetxattr)(path, name, value, size);5777 if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);5778 return res;5779}5780INTERCEPTOR(SSIZE_T, fgetxattr, int fd, const char *name, char *value,5781 SIZE_T size) {5782 void *ctx;5783 COMMON_INTERCEPTOR_ENTER(ctx, fgetxattr, fd, name, value, size);5784 if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);5785 // FIXME: under ASan the call below may write to freed memory and corrupt5786 // its metadata. See5787 // https://github.com/google/sanitizers/issues/321.5788 SSIZE_T res = REAL(fgetxattr)(fd, name, value, size);5789 if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);5790 return res;5791}5792#define INIT_GETXATTR \5793 COMMON_INTERCEPT_FUNCTION(getxattr); \5794 COMMON_INTERCEPT_FUNCTION(lgetxattr); \5795 COMMON_INTERCEPT_FUNCTION(fgetxattr);5796#else5797#define INIT_GETXATTR5798#endif5799 5800#if SANITIZER_INTERCEPT_GETRESID5801INTERCEPTOR(int, getresuid, void *ruid, void *euid, void *suid) {5802 void *ctx;5803 COMMON_INTERCEPTOR_ENTER(ctx, getresuid, ruid, euid, suid);5804 // FIXME: under ASan the call below may write to freed memory and corrupt5805 // its metadata. See5806 // https://github.com/google/sanitizers/issues/321.5807 int res = REAL(getresuid)(ruid, euid, suid);5808 if (res >= 0) {5809 if (ruid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ruid, uid_t_sz);5810 if (euid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, euid, uid_t_sz);5811 if (suid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, suid, uid_t_sz);5812 }5813 return res;5814}5815INTERCEPTOR(int, getresgid, void *rgid, void *egid, void *sgid) {5816 void *ctx;5817 COMMON_INTERCEPTOR_ENTER(ctx, getresgid, rgid, egid, sgid);5818 // FIXME: under ASan the call below may write to freed memory and corrupt5819 // its metadata. See5820 // https://github.com/google/sanitizers/issues/321.5821 int res = REAL(getresgid)(rgid, egid, sgid);5822 if (res >= 0) {5823 if (rgid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rgid, gid_t_sz);5824 if (egid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, egid, gid_t_sz);5825 if (sgid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sgid, gid_t_sz);5826 }5827 return res;5828}5829#define INIT_GETRESID \5830 COMMON_INTERCEPT_FUNCTION(getresuid); \5831 COMMON_INTERCEPT_FUNCTION(getresgid);5832#else5833#define INIT_GETRESID5834#endif5835 5836#if SANITIZER_INTERCEPT_GETIFADDRS5837// As long as getifaddrs()/freeifaddrs() use calloc()/free(), we don't need to5838// intercept freeifaddrs(). If that ceases to be the case, we might need to5839// intercept it to poison the memory again.5840INTERCEPTOR(int, getifaddrs, __sanitizer_ifaddrs **ifap) {5841 void *ctx;5842 COMMON_INTERCEPTOR_ENTER(ctx, getifaddrs, ifap);5843 // FIXME: under ASan the call below may write to freed memory and corrupt5844 // its metadata. See5845 // https://github.com/google/sanitizers/issues/321.5846 int res = REAL(getifaddrs)(ifap);5847 if (res == 0 && ifap) {5848 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifap, sizeof(void *));5849 __sanitizer_ifaddrs *p = *ifap;5850 while (p) {5851 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(__sanitizer_ifaddrs));5852 if (p->ifa_name)5853 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_name,5854 internal_strlen(p->ifa_name) + 1);5855 if (p->ifa_addr)5856 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_addr, struct_sockaddr_sz);5857 if (p->ifa_netmask)5858 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_netmask, struct_sockaddr_sz);5859 // On Linux this is a union, but the other member also points to a5860 // struct sockaddr, so the following is sufficient.5861 if (p->ifa_dstaddr)5862 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_dstaddr, struct_sockaddr_sz);5863 // FIXME(smatveev): Unpoison p->ifa_data as well.5864 p = p->ifa_next;5865 }5866 }5867 return res;5868}5869#define INIT_GETIFADDRS \5870 COMMON_INTERCEPT_FUNCTION(getifaddrs);5871#else5872#define INIT_GETIFADDRS5873#endif5874 5875#if SANITIZER_INTERCEPT_IF_INDEXTONAME5876INTERCEPTOR(char *, if_indextoname, unsigned int ifindex, char* ifname) {5877 void *ctx;5878 COMMON_INTERCEPTOR_ENTER(ctx, if_indextoname, ifindex, ifname);5879 // FIXME: under ASan the call below may write to freed memory and corrupt5880 // its metadata. See5881 // https://github.com/google/sanitizers/issues/321.5882 char *res = REAL(if_indextoname)(ifindex, ifname);5883 if (res && ifname)5884 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifname, internal_strlen(ifname) + 1);5885 return res;5886}5887INTERCEPTOR(unsigned int, if_nametoindex, const char* ifname) {5888 void *ctx;5889 COMMON_INTERCEPTOR_ENTER(ctx, if_nametoindex, ifname);5890 if (ifname)5891 COMMON_INTERCEPTOR_READ_RANGE(ctx, ifname, internal_strlen(ifname) + 1);5892 return REAL(if_nametoindex)(ifname);5893}5894#define INIT_IF_INDEXTONAME \5895 COMMON_INTERCEPT_FUNCTION(if_indextoname); \5896 COMMON_INTERCEPT_FUNCTION(if_nametoindex);5897#else5898#define INIT_IF_INDEXTONAME5899#endif5900 5901#if SANITIZER_INTERCEPT_CAPGET5902INTERCEPTOR(int, capget, void *hdrp, void *datap) {5903 void *ctx;5904 COMMON_INTERCEPTOR_ENTER(ctx, capget, hdrp, datap);5905 if (hdrp)5906 COMMON_INTERCEPTOR_READ_RANGE(ctx, hdrp, __user_cap_header_struct_sz);5907 // FIXME: under ASan the call below may write to freed memory and corrupt5908 // its metadata. See5909 // https://github.com/google/sanitizers/issues/321.5910 int res = REAL(capget)(hdrp, datap);5911 if (res == 0 && datap) {5912 unsigned datasz = __user_cap_data_struct_sz(hdrp);5913 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, datap, datasz);5914 }5915 // We can also return -1 and write to hdrp->version if the version passed in5916 // hdrp->version is unsupported. But that's not a trivial condition to check,5917 // and anyway COMMON_INTERCEPTOR_READ_RANGE protects us to some extent.5918 return res;5919}5920INTERCEPTOR(int, capset, void *hdrp, const void *datap) {5921 void *ctx;5922 COMMON_INTERCEPTOR_ENTER(ctx, capset, hdrp, datap);5923 if (hdrp)5924 COMMON_INTERCEPTOR_READ_RANGE(ctx, hdrp, __user_cap_header_struct_sz);5925 if (datap) {5926 unsigned datasz = __user_cap_data_struct_sz(hdrp);5927 COMMON_INTERCEPTOR_READ_RANGE(ctx, datap, datasz);5928 }5929 return REAL(capset)(hdrp, datap);5930}5931#define INIT_CAPGET \5932 COMMON_INTERCEPT_FUNCTION(capget); \5933 COMMON_INTERCEPT_FUNCTION(capset);5934#else5935#define INIT_CAPGET5936#endif5937 5938#if SANITIZER_INTERCEPT_FTIME5939INTERCEPTOR(int, ftime, __sanitizer_timeb *tp) {5940 void *ctx;5941 COMMON_INTERCEPTOR_ENTER(ctx, ftime, tp);5942 // FIXME: under ASan the call below may write to freed memory and corrupt5943 // its metadata. See5944 // https://github.com/google/sanitizers/issues/321.5945 int res = REAL(ftime)(tp);5946 if (tp)5947 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, sizeof(*tp));5948 return res;5949}5950#define INIT_FTIME COMMON_INTERCEPT_FUNCTION(ftime);5951#else5952#define INIT_FTIME5953#endif // SANITIZER_INTERCEPT_FTIME5954 5955#if SANITIZER_INTERCEPT_XDR5956INTERCEPTOR(void, xdrmem_create, __sanitizer_XDR *xdrs, uptr addr,5957 unsigned size, int op) {5958 void *ctx;5959 COMMON_INTERCEPTOR_ENTER(ctx, xdrmem_create, xdrs, addr, size, op);5960 // FIXME: under ASan the call below may write to freed memory and corrupt5961 // its metadata. See5962 // https://github.com/google/sanitizers/issues/321.5963 REAL(xdrmem_create)(xdrs, addr, size, op);5964 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdrs, sizeof(*xdrs));5965 if (op == __sanitizer_XDR_ENCODE) {5966 // It's not obvious how much data individual xdr_ routines write.5967 // Simply unpoison the entire target buffer in advance.5968 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (void *)addr, size);5969 }5970}5971 5972INTERCEPTOR(void, xdrstdio_create, __sanitizer_XDR *xdrs, void *file, int op) {5973 void *ctx;5974 COMMON_INTERCEPTOR_ENTER(ctx, xdrstdio_create, xdrs, file, op);5975 // FIXME: under ASan the call below may write to freed memory and corrupt5976 // its metadata. See5977 // https://github.com/google/sanitizers/issues/321.5978 REAL(xdrstdio_create)(xdrs, file, op);5979 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdrs, sizeof(*xdrs));5980}5981 5982// FIXME: under ASan the call below may write to freed memory and corrupt5983// its metadata. See5984// https://github.com/google/sanitizers/issues/321.5985#define XDR_INTERCEPTOR(F, T) \5986 INTERCEPTOR(int, F, __sanitizer_XDR *xdrs, T *p) { \5987 void *ctx; \5988 COMMON_INTERCEPTOR_ENTER(ctx, F, xdrs, p); \5989 if (p && xdrs->x_op == __sanitizer_XDR_ENCODE) \5990 COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p)); \5991 int res = REAL(F)(xdrs, p); \5992 if (res && p && xdrs->x_op == __sanitizer_XDR_DECODE) \5993 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); \5994 return res; \5995 }5996 5997XDR_INTERCEPTOR(xdr_short, short)5998XDR_INTERCEPTOR(xdr_u_short, unsigned short)5999XDR_INTERCEPTOR(xdr_int, int)6000XDR_INTERCEPTOR(xdr_u_int, unsigned)6001XDR_INTERCEPTOR(xdr_long, long)6002XDR_INTERCEPTOR(xdr_u_long, unsigned long)6003XDR_INTERCEPTOR(xdr_hyper, long long)6004XDR_INTERCEPTOR(xdr_u_hyper, unsigned long long)6005XDR_INTERCEPTOR(xdr_longlong_t, long long)6006XDR_INTERCEPTOR(xdr_u_longlong_t, unsigned long long)6007XDR_INTERCEPTOR(xdr_int8_t, u8)6008XDR_INTERCEPTOR(xdr_uint8_t, u8)6009XDR_INTERCEPTOR(xdr_int16_t, u16)6010XDR_INTERCEPTOR(xdr_uint16_t, u16)6011XDR_INTERCEPTOR(xdr_int32_t, u32)6012XDR_INTERCEPTOR(xdr_uint32_t, u32)6013XDR_INTERCEPTOR(xdr_int64_t, u64)6014XDR_INTERCEPTOR(xdr_uint64_t, u64)6015XDR_INTERCEPTOR(xdr_quad_t, long long)6016XDR_INTERCEPTOR(xdr_u_quad_t, unsigned long long)6017XDR_INTERCEPTOR(xdr_bool, bool)6018XDR_INTERCEPTOR(xdr_enum, int)6019XDR_INTERCEPTOR(xdr_char, char)6020XDR_INTERCEPTOR(xdr_u_char, unsigned char)6021XDR_INTERCEPTOR(xdr_float, float)6022XDR_INTERCEPTOR(xdr_double, double)6023 6024// FIXME: intercept xdr_array, opaque, union, vector, reference, pointer,6025// wrapstring, sizeof6026 6027INTERCEPTOR(int, xdr_bytes, __sanitizer_XDR *xdrs, char **p, unsigned *sizep,6028 unsigned maxsize) {6029 void *ctx;6030 COMMON_INTERCEPTOR_ENTER(ctx, xdr_bytes, xdrs, p, sizep, maxsize);6031 if (p && sizep && xdrs->x_op == __sanitizer_XDR_ENCODE) {6032 COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p));6033 COMMON_INTERCEPTOR_READ_RANGE(ctx, sizep, sizeof(*sizep));6034 COMMON_INTERCEPTOR_READ_RANGE(ctx, *p, *sizep);6035 }6036 // FIXME: under ASan the call below may write to freed memory and corrupt6037 // its metadata. See6038 // https://github.com/google/sanitizers/issues/321.6039 int res = REAL(xdr_bytes)(xdrs, p, sizep, maxsize);6040 if (p && sizep && xdrs->x_op == __sanitizer_XDR_DECODE) {6041 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));6042 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizep, sizeof(*sizep));6043 if (res && *p && *sizep) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, *sizep);6044 }6045 return res;6046}6047 6048INTERCEPTOR(int, xdr_string, __sanitizer_XDR *xdrs, char **p,6049 unsigned maxsize) {6050 void *ctx;6051 COMMON_INTERCEPTOR_ENTER(ctx, xdr_string, xdrs, p, maxsize);6052 if (p && xdrs->x_op == __sanitizer_XDR_ENCODE) {6053 COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p));6054 COMMON_INTERCEPTOR_READ_RANGE(ctx, *p, internal_strlen(*p) + 1);6055 }6056 // FIXME: under ASan the call below may write to freed memory and corrupt6057 // its metadata. See6058 // https://github.com/google/sanitizers/issues/321.6059 int res = REAL(xdr_string)(xdrs, p, maxsize);6060 if (p && xdrs->x_op == __sanitizer_XDR_DECODE) {6061 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));6062 if (res && *p)6063 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, internal_strlen(*p) + 1);6064 }6065 return res;6066}6067 6068#define INIT_XDR \6069 COMMON_INTERCEPT_FUNCTION(xdrmem_create); \6070 COMMON_INTERCEPT_FUNCTION(xdrstdio_create); \6071 COMMON_INTERCEPT_FUNCTION(xdr_short); \6072 COMMON_INTERCEPT_FUNCTION(xdr_u_short); \6073 COMMON_INTERCEPT_FUNCTION(xdr_int); \6074 COMMON_INTERCEPT_FUNCTION(xdr_u_int); \6075 COMMON_INTERCEPT_FUNCTION(xdr_long); \6076 COMMON_INTERCEPT_FUNCTION(xdr_u_long); \6077 COMMON_INTERCEPT_FUNCTION(xdr_hyper); \6078 COMMON_INTERCEPT_FUNCTION(xdr_u_hyper); \6079 COMMON_INTERCEPT_FUNCTION(xdr_longlong_t); \6080 COMMON_INTERCEPT_FUNCTION(xdr_u_longlong_t); \6081 COMMON_INTERCEPT_FUNCTION(xdr_int8_t); \6082 COMMON_INTERCEPT_FUNCTION(xdr_uint8_t); \6083 COMMON_INTERCEPT_FUNCTION(xdr_int16_t); \6084 COMMON_INTERCEPT_FUNCTION(xdr_uint16_t); \6085 COMMON_INTERCEPT_FUNCTION(xdr_int32_t); \6086 COMMON_INTERCEPT_FUNCTION(xdr_uint32_t); \6087 COMMON_INTERCEPT_FUNCTION(xdr_int64_t); \6088 COMMON_INTERCEPT_FUNCTION(xdr_uint64_t); \6089 COMMON_INTERCEPT_FUNCTION(xdr_quad_t); \6090 COMMON_INTERCEPT_FUNCTION(xdr_u_quad_t); \6091 COMMON_INTERCEPT_FUNCTION(xdr_bool); \6092 COMMON_INTERCEPT_FUNCTION(xdr_enum); \6093 COMMON_INTERCEPT_FUNCTION(xdr_char); \6094 COMMON_INTERCEPT_FUNCTION(xdr_u_char); \6095 COMMON_INTERCEPT_FUNCTION(xdr_float); \6096 COMMON_INTERCEPT_FUNCTION(xdr_double); \6097 COMMON_INTERCEPT_FUNCTION(xdr_bytes); \6098 COMMON_INTERCEPT_FUNCTION(xdr_string);6099#else6100#define INIT_XDR6101#endif // SANITIZER_INTERCEPT_XDR6102 6103#if SANITIZER_INTERCEPT_XDRREC6104typedef int (*xdrrec_cb)(char*, char*, int);6105struct XdrRecWrapper {6106 char *handle;6107 xdrrec_cb rd, wr;6108};6109typedef AddrHashMap<XdrRecWrapper *, 11> XdrRecWrapMap;6110static XdrRecWrapMap *xdrrec_wrap_map;6111 6112static int xdrrec_wr_wrap(char *handle, char *buf, int count) {6113 COMMON_INTERCEPTOR_UNPOISON_PARAM(3);6114 COMMON_INTERCEPTOR_INITIALIZE_RANGE(buf, count);6115 XdrRecWrapper *wrap = (XdrRecWrapper *)handle;6116 return wrap->wr(wrap->handle, buf, count);6117}6118 6119static int xdrrec_rd_wrap(char *handle, char *buf, int count) {6120 COMMON_INTERCEPTOR_UNPOISON_PARAM(3);6121 XdrRecWrapper *wrap = (XdrRecWrapper *)handle;6122 return wrap->rd(wrap->handle, buf, count);6123}6124 6125// This doesn't apply to the solaris version as it has a different function6126// signature.6127INTERCEPTOR(void, xdrrec_create, __sanitizer_XDR *xdr, unsigned sndsize,6128 unsigned rcvsize, char *handle, int (*rd)(char*, char*, int),6129 int (*wr)(char*, char*, int)) {6130 void *ctx;6131 COMMON_INTERCEPTOR_ENTER(ctx, xdrrec_create, xdr, sndsize, rcvsize,6132 handle, rd, wr);6133 COMMON_INTERCEPTOR_READ_RANGE(ctx, &xdr->x_op, sizeof xdr->x_op);6134 6135 // We can't allocate a wrapper on the stack, as the handle is used outside6136 // this stack frame. So we put it on the heap, and keep track of it with6137 // the HashMap (keyed by x_private). When we later need to xdr_destroy,6138 // we can index the map, free the wrapper, and then clean the map entry.6139 XdrRecWrapper *wrap_data =6140 (XdrRecWrapper *)InternalAlloc(sizeof(XdrRecWrapper));6141 wrap_data->handle = handle;6142 wrap_data->rd = rd;6143 wrap_data->wr = wr;6144 if (wr)6145 wr = xdrrec_wr_wrap;6146 if (rd)6147 rd = xdrrec_rd_wrap;6148 handle = (char *)wrap_data;6149 6150 REAL(xdrrec_create)(xdr, sndsize, rcvsize, handle, rd, wr);6151 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdr, sizeof *xdr);6152 6153 XdrRecWrapMap::Handle wrap(xdrrec_wrap_map, xdr->x_private, false, true);6154 *wrap = wrap_data;6155}6156 6157// We have to intercept this to be able to free wrapper memory;6158// otherwise it's not necessary.6159INTERCEPTOR(void, xdr_destroy, __sanitizer_XDR *xdr) {6160 void *ctx;6161 COMMON_INTERCEPTOR_ENTER(ctx, xdr_destroy, xdr);6162 6163 XdrRecWrapMap::Handle wrap(xdrrec_wrap_map, xdr->x_private, true);6164 InternalFree(*wrap);6165 REAL(xdr_destroy)(xdr);6166}6167#define INIT_XDRREC_LINUX \6168 static u64 xdrrec_wrap_mem[sizeof(XdrRecWrapMap) / sizeof(u64) + 1]; \6169 xdrrec_wrap_map = new ((void *)&xdrrec_wrap_mem) XdrRecWrapMap(); \6170 COMMON_INTERCEPT_FUNCTION(xdrrec_create); \6171 COMMON_INTERCEPT_FUNCTION(xdr_destroy);6172#else6173#define INIT_XDRREC_LINUX6174#endif6175 6176#if SANITIZER_INTERCEPT_TSEARCH6177INTERCEPTOR(void *, tsearch, void *key, void **rootp,6178 int (*compar)(const void *, const void *)) {6179 void *ctx;6180 COMMON_INTERCEPTOR_ENTER(ctx, tsearch, key, rootp, compar);6181 // FIXME: under ASan the call below may write to freed memory and corrupt6182 // its metadata. See6183 // https://github.com/google/sanitizers/issues/321.6184 void *res = REAL(tsearch)(key, rootp, compar);6185 if (res && *(void **)res == key)6186 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(void *));6187 return res;6188}6189#define INIT_TSEARCH COMMON_INTERCEPT_FUNCTION(tsearch);6190#else6191#define INIT_TSEARCH6192#endif6193 6194#if SANITIZER_INTERCEPT_LIBIO_INTERNALS || SANITIZER_INTERCEPT_FOPEN || \6195 SANITIZER_INTERCEPT_OPEN_MEMSTREAM6196void unpoison_file(__sanitizer_FILE *fp) {6197#if SANITIZER_HAS_STRUCT_FILE6198 COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp, sizeof(*fp));6199#if SANITIZER_NETBSD6200 if (fp->_bf._base && fp->_bf._size > 0)6201 COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp->_bf._base,6202 fp->_bf._size);6203#else6204 if (fp->_IO_read_base && fp->_IO_read_base < fp->_IO_read_end)6205 COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp->_IO_read_base,6206 fp->_IO_read_end - fp->_IO_read_base);6207 if (fp->_IO_write_base && fp->_IO_write_base < fp->_IO_write_end)6208 COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp->_IO_write_base,6209 fp->_IO_write_end - fp->_IO_write_base);6210#endif6211#endif // SANITIZER_HAS_STRUCT_FILE6212}6213#endif6214 6215#if SANITIZER_INTERCEPT_LIBIO_INTERNALS6216// These guys are called when a .c source is built with -O2.6217INTERCEPTOR(int, __uflow, __sanitizer_FILE *fp) {6218 void *ctx;6219 COMMON_INTERCEPTOR_ENTER(ctx, __uflow, fp);6220 int res = REAL(__uflow)(fp);6221 unpoison_file(fp);6222 return res;6223}6224INTERCEPTOR(int, __underflow, __sanitizer_FILE *fp) {6225 void *ctx;6226 COMMON_INTERCEPTOR_ENTER(ctx, __underflow, fp);6227 int res = REAL(__underflow)(fp);6228 unpoison_file(fp);6229 return res;6230}6231INTERCEPTOR(int, __overflow, __sanitizer_FILE *fp, int ch) {6232 void *ctx;6233 COMMON_INTERCEPTOR_ENTER(ctx, __overflow, fp, ch);6234 int res = REAL(__overflow)(fp, ch);6235 unpoison_file(fp);6236 return res;6237}6238INTERCEPTOR(int, __wuflow, __sanitizer_FILE *fp) {6239 void *ctx;6240 COMMON_INTERCEPTOR_ENTER(ctx, __wuflow, fp);6241 int res = REAL(__wuflow)(fp);6242 unpoison_file(fp);6243 return res;6244}6245INTERCEPTOR(int, __wunderflow, __sanitizer_FILE *fp) {6246 void *ctx;6247 COMMON_INTERCEPTOR_ENTER(ctx, __wunderflow, fp);6248 int res = REAL(__wunderflow)(fp);6249 unpoison_file(fp);6250 return res;6251}6252INTERCEPTOR(int, __woverflow, __sanitizer_FILE *fp, int ch) {6253 void *ctx;6254 COMMON_INTERCEPTOR_ENTER(ctx, __woverflow, fp, ch);6255 int res = REAL(__woverflow)(fp, ch);6256 unpoison_file(fp);6257 return res;6258}6259#define INIT_LIBIO_INTERNALS \6260 COMMON_INTERCEPT_FUNCTION(__uflow); \6261 COMMON_INTERCEPT_FUNCTION(__underflow); \6262 COMMON_INTERCEPT_FUNCTION(__overflow); \6263 COMMON_INTERCEPT_FUNCTION(__wuflow); \6264 COMMON_INTERCEPT_FUNCTION(__wunderflow); \6265 COMMON_INTERCEPT_FUNCTION(__woverflow);6266#else6267#define INIT_LIBIO_INTERNALS6268#endif6269 6270#if SANITIZER_INTERCEPT_FOPEN6271INTERCEPTOR(__sanitizer_FILE *, fopen, const char *path, const char *mode) {6272 void *ctx;6273 COMMON_INTERCEPTOR_ENTER(ctx, fopen, path, mode);6274 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);6275 COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, internal_strlen(mode) + 1);6276 __sanitizer_FILE *res = REAL(fopen)(path, mode);6277 COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);6278 if (res) unpoison_file(res);6279 return res;6280}6281INTERCEPTOR(__sanitizer_FILE *, fdopen, int fd, const char *mode) {6282 void *ctx;6283 COMMON_INTERCEPTOR_ENTER(ctx, fdopen, fd, mode);6284 COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, internal_strlen(mode) + 1);6285 __sanitizer_FILE *res = REAL(fdopen)(fd, mode);6286 if (res) unpoison_file(res);6287 return res;6288}6289INTERCEPTOR(__sanitizer_FILE *, freopen, const char *path, const char *mode,6290 __sanitizer_FILE *fp) {6291 void *ctx;6292 COMMON_INTERCEPTOR_ENTER(ctx, freopen, path, mode, fp);6293 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);6294 COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, internal_strlen(mode) + 1);6295 COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);6296 __sanitizer_FILE *res = REAL(freopen)(path, mode, fp);6297 COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);6298 if (res) unpoison_file(res);6299 return res;6300}6301#define INIT_FOPEN \6302 COMMON_INTERCEPT_FUNCTION(fopen); \6303 COMMON_INTERCEPT_FUNCTION(fdopen); \6304 COMMON_INTERCEPT_FUNCTION(freopen);6305#else6306#define INIT_FOPEN6307#endif6308 6309#if SANITIZER_INTERCEPT_FLOPEN6310INTERCEPTOR(int, flopen, const char *path, int flags, ...) {6311 void *ctx;6312 va_list ap;6313 va_start(ap, flags);6314 u16 mode = static_cast<u16>(va_arg(ap, u32));6315 va_end(ap);6316 COMMON_INTERCEPTOR_ENTER(ctx, flopen, path, flags, mode);6317 if (path) {6318 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);6319 }6320 return COMMON_INTERCEPTOR_BLOCK_REAL(flopen)(path, flags, mode);6321}6322 6323INTERCEPTOR(int, flopenat, int dirfd, const char *path, int flags, ...) {6324 void *ctx;6325 va_list ap;6326 va_start(ap, flags);6327 u16 mode = static_cast<u16>(va_arg(ap, u32));6328 va_end(ap);6329 COMMON_INTERCEPTOR_ENTER(ctx, flopen, path, flags, mode);6330 if (path) {6331 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);6332 }6333 return COMMON_INTERCEPTOR_BLOCK_REAL(flopenat)(dirfd, path, flags, mode);6334}6335 6336#define INIT_FLOPEN \6337 COMMON_INTERCEPT_FUNCTION(flopen); \6338 COMMON_INTERCEPT_FUNCTION(flopenat);6339#else6340#define INIT_FLOPEN6341#endif6342 6343#if SANITIZER_INTERCEPT_FOPEN646344INTERCEPTOR(__sanitizer_FILE *, fopen64, const char *path, const char *mode) {6345 void *ctx;6346 COMMON_INTERCEPTOR_ENTER(ctx, fopen64, path, mode);6347 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);6348 COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, internal_strlen(mode) + 1);6349 __sanitizer_FILE *res = REAL(fopen64)(path, mode);6350 COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);6351 if (res) unpoison_file(res);6352 return res;6353}6354INTERCEPTOR(__sanitizer_FILE *, freopen64, const char *path, const char *mode,6355 __sanitizer_FILE *fp) {6356 void *ctx;6357 COMMON_INTERCEPTOR_ENTER(ctx, freopen64, path, mode, fp);6358 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);6359 COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, internal_strlen(mode) + 1);6360 COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);6361 __sanitizer_FILE *res = REAL(freopen64)(path, mode, fp);6362 COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);6363 if (res) unpoison_file(res);6364 return res;6365}6366#define INIT_FOPEN64 \6367 COMMON_INTERCEPT_FUNCTION(fopen64); \6368 COMMON_INTERCEPT_FUNCTION(freopen64);6369#else6370#define INIT_FOPEN646371#endif6372 6373#if SANITIZER_INTERCEPT_OPEN_MEMSTREAM6374INTERCEPTOR(__sanitizer_FILE *, open_memstream, char **ptr, SIZE_T *sizeloc) {6375 void *ctx;6376 COMMON_INTERCEPTOR_ENTER(ctx, open_memstream, ptr, sizeloc);6377 // FIXME: under ASan the call below may write to freed memory and corrupt6378 // its metadata. See6379 // https://github.com/google/sanitizers/issues/321.6380 __sanitizer_FILE *res = REAL(open_memstream)(ptr, sizeloc);6381 if (res) {6382 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, sizeof(*ptr));6383 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizeloc, sizeof(*sizeloc));6384 unpoison_file(res);6385 FileMetadata file = {ptr, sizeloc};6386 SetInterceptorMetadata(res, file);6387 }6388 return res;6389}6390INTERCEPTOR(__sanitizer_FILE *, open_wmemstream, wchar_t **ptr,6391 SIZE_T *sizeloc) {6392 void *ctx;6393 COMMON_INTERCEPTOR_ENTER(ctx, open_wmemstream, ptr, sizeloc);6394 __sanitizer_FILE *res = REAL(open_wmemstream)(ptr, sizeloc);6395 if (res) {6396 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, sizeof(*ptr));6397 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizeloc, sizeof(*sizeloc));6398 unpoison_file(res);6399 FileMetadata file = {(char **)ptr, sizeloc};6400 SetInterceptorMetadata(res, file);6401 }6402 return res;6403}6404INTERCEPTOR(__sanitizer_FILE *, fmemopen, void *buf, SIZE_T size,6405 const char *mode) {6406 void *ctx;6407 COMMON_INTERCEPTOR_ENTER(ctx, fmemopen, buf, size, mode);6408 // FIXME: under ASan the call below may write to freed memory and corrupt6409 // its metadata. See6410 // https://github.com/google/sanitizers/issues/321.6411 __sanitizer_FILE *res = REAL(fmemopen)(buf, size, mode);6412 if (res) unpoison_file(res);6413 return res;6414}6415#define INIT_OPEN_MEMSTREAM \6416 COMMON_INTERCEPT_FUNCTION(open_memstream); \6417 COMMON_INTERCEPT_FUNCTION(open_wmemstream); \6418 COMMON_INTERCEPT_FUNCTION(fmemopen);6419#else6420#define INIT_OPEN_MEMSTREAM6421#endif6422 6423#if SANITIZER_INTERCEPT_OBSTACK6424static void initialize_obstack(__sanitizer_obstack *obstack) {6425 COMMON_INTERCEPTOR_INITIALIZE_RANGE(obstack, sizeof(*obstack));6426 if (obstack->chunk)6427 COMMON_INTERCEPTOR_INITIALIZE_RANGE(obstack->chunk,6428 sizeof(*obstack->chunk));6429}6430 6431INTERCEPTOR(int, _obstack_begin_1, __sanitizer_obstack *obstack, int sz,6432 int align, void *(*alloc_fn)(uptr arg, uptr sz),6433 void (*free_fn)(uptr arg, void *p)) {6434 void *ctx;6435 COMMON_INTERCEPTOR_ENTER(ctx, _obstack_begin_1, obstack, sz, align, alloc_fn,6436 free_fn);6437 int res = REAL(_obstack_begin_1)(obstack, sz, align, alloc_fn, free_fn);6438 if (res) initialize_obstack(obstack);6439 return res;6440}6441INTERCEPTOR(int, _obstack_begin, __sanitizer_obstack *obstack, int sz,6442 int align, void *(*alloc_fn)(uptr sz), void (*free_fn)(void *p)) {6443 void *ctx;6444 COMMON_INTERCEPTOR_ENTER(ctx, _obstack_begin, obstack, sz, align, alloc_fn,6445 free_fn);6446 int res = REAL(_obstack_begin)(obstack, sz, align, alloc_fn, free_fn);6447 if (res) initialize_obstack(obstack);6448 return res;6449}6450INTERCEPTOR(void, _obstack_newchunk, __sanitizer_obstack *obstack, int length) {6451 void *ctx;6452 COMMON_INTERCEPTOR_ENTER(ctx, _obstack_newchunk, obstack, length);6453 REAL(_obstack_newchunk)(obstack, length);6454 if (obstack->chunk)6455 COMMON_INTERCEPTOR_INITIALIZE_RANGE(6456 obstack->chunk, obstack->next_free - (char *)obstack->chunk);6457}6458#define INIT_OBSTACK \6459 COMMON_INTERCEPT_FUNCTION(_obstack_begin_1); \6460 COMMON_INTERCEPT_FUNCTION(_obstack_begin); \6461 COMMON_INTERCEPT_FUNCTION(_obstack_newchunk);6462#else6463#define INIT_OBSTACK6464#endif6465 6466#if SANITIZER_INTERCEPT_FFLUSH6467INTERCEPTOR(int, fflush, __sanitizer_FILE *fp) {6468 void *ctx;6469 COMMON_INTERCEPTOR_ENTER(ctx, fflush, fp);6470 if (fp)6471 unpoison_file(fp);6472 int res = REAL(fflush)(fp);6473 // FIXME: handle fp == NULL6474 if (fp) {6475 const FileMetadata *m = GetInterceptorMetadata(fp);6476 if (m) COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);6477 }6478 return res;6479}6480#define INIT_FFLUSH COMMON_INTERCEPT_FUNCTION(fflush);6481#else6482#define INIT_FFLUSH6483#endif6484 6485#if SANITIZER_INTERCEPT_FCLOSE6486INTERCEPTOR(int, fclose, __sanitizer_FILE *fp) {6487 void *ctx;6488 COMMON_INTERCEPTOR_ENTER(ctx, fclose, fp);6489 COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);6490 const FileMetadata *m = GetInterceptorMetadata(fp);6491 if (fp)6492 unpoison_file(fp);6493 int res = REAL(fclose)(fp);6494 if (m) {6495 COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);6496 DeleteInterceptorMetadata(fp);6497 }6498 return res;6499}6500#define INIT_FCLOSE COMMON_INTERCEPT_FUNCTION(fclose);6501#else6502#define INIT_FCLOSE6503#endif6504 6505#if SANITIZER_INTERCEPT_DLOPEN_DLCLOSE6506INTERCEPTOR(void*, dlopen, const char *filename, int flag) {6507 void *ctx;6508 COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlopen, filename, flag);6509 6510 if (filename) {6511 COMMON_INTERCEPTOR_READ_STRING(ctx, filename, 0);6512 6513# if !SANITIZER_DYNAMIC6514 // We care about a very specific use-case: dladdr on6515 // statically-linked ASan may return <main program>6516 // instead of the library.6517 // We therefore only take effect if the sanitizer is statically6518 // linked, and we don't bother canonicalizing paths because6519 // dladdr should return the same address both times (we assume6520 // the user did not canonicalize the result from dladdr).6521 if (common_flags()->test_only_replace_dlopen_main_program) {6522 VPrintf(1, "dlopen interceptor: filename: %s\n", filename);6523 6524 const char *SelfFName = DladdrSelfFName();6525 VPrintf(1, "dlopen interceptor: DladdrSelfFName: %p %s\n",6526 (const void *)SelfFName, SelfFName);6527 6528 if (SelfFName && internal_strcmp(SelfFName, filename) == 0) {6529 // It's possible they copied the string from dladdr, so6530 // we do a string comparison rather than pointer comparison.6531 VPrintf(1, "dlopen interceptor: replacing %s because it matches %s\n",6532 filename, SelfFName);6533 filename = (char *)0; // RTLD_DEFAULT6534 }6535 }6536# endif // !SANITIZER_DYNAMIC6537 }6538 6539 void *res = COMMON_INTERCEPTOR_DLOPEN(filename, flag);6540 Symbolizer::GetOrInit()->InvalidateModuleList();6541 COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, res);6542 return res;6543}6544 6545INTERCEPTOR(int, dlclose, void *handle) {6546 void *ctx;6547 COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlclose, handle);6548 int res = REAL(dlclose)(handle);6549 Symbolizer::GetOrInit()->InvalidateModuleList();6550 COMMON_INTERCEPTOR_LIBRARY_UNLOADED();6551 return res;6552}6553#define INIT_DLOPEN_DLCLOSE \6554 COMMON_INTERCEPT_FUNCTION(dlopen); \6555 COMMON_INTERCEPT_FUNCTION(dlclose);6556#else6557#define INIT_DLOPEN_DLCLOSE6558#endif6559 6560#if SANITIZER_INTERCEPT_GETPASS6561INTERCEPTOR(char *, getpass, const char *prompt) {6562 void *ctx;6563 COMMON_INTERCEPTOR_ENTER(ctx, getpass, prompt);6564 if (prompt)6565 COMMON_INTERCEPTOR_READ_RANGE(ctx, prompt, internal_strlen(prompt)+1);6566 char *res = REAL(getpass)(prompt);6567 if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res)+1);6568 return res;6569}6570 6571#define INIT_GETPASS COMMON_INTERCEPT_FUNCTION(getpass);6572#else6573#define INIT_GETPASS6574#endif6575 6576#if SANITIZER_INTERCEPT_TIMERFD6577INTERCEPTOR(int, timerfd_settime, int fd, int flags, void *new_value,6578 void *old_value) {6579 void *ctx;6580 COMMON_INTERCEPTOR_ENTER(ctx, timerfd_settime, fd, flags, new_value,6581 old_value);6582 COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerspec_sz);6583 int res = REAL(timerfd_settime)(fd, flags, new_value, old_value);6584 if (res != -1 && old_value)6585 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerspec_sz);6586 return res;6587}6588 6589INTERCEPTOR(int, timerfd_gettime, int fd, void *curr_value) {6590 void *ctx;6591 COMMON_INTERCEPTOR_ENTER(ctx, timerfd_gettime, fd, curr_value);6592 int res = REAL(timerfd_gettime)(fd, curr_value);6593 if (res != -1 && curr_value)6594 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerspec_sz);6595 return res;6596}6597#define INIT_TIMERFD \6598 COMMON_INTERCEPT_FUNCTION(timerfd_settime); \6599 COMMON_INTERCEPT_FUNCTION(timerfd_gettime);6600#else6601#define INIT_TIMERFD6602#endif6603 6604#if SANITIZER_INTERCEPT_MLOCKX6605// Linux kernel has a bug that leads to kernel deadlock if a process6606// maps TBs of memory and then calls mlock().6607static void MlockIsUnsupported() {6608 static atomic_uint8_t printed;6609 if (atomic_exchange(&printed, 1, memory_order_relaxed))6610 return;6611 VPrintf(1, "%s ignores mlock/mlockall/munlock/munlockall\n",6612 SanitizerToolName);6613}6614 6615INTERCEPTOR(int, mlock, const void *addr, usize len) {6616 MlockIsUnsupported();6617 return 0;6618}6619 6620INTERCEPTOR(int, munlock, const void *addr, usize len) {6621 MlockIsUnsupported();6622 return 0;6623}6624 6625INTERCEPTOR(int, mlockall, int flags) {6626 MlockIsUnsupported();6627 return 0;6628}6629 6630INTERCEPTOR(int, munlockall, void) {6631 MlockIsUnsupported();6632 return 0;6633}6634 6635#define INIT_MLOCKX \6636 COMMON_INTERCEPT_FUNCTION(mlock); \6637 COMMON_INTERCEPT_FUNCTION(munlock); \6638 COMMON_INTERCEPT_FUNCTION(mlockall); \6639 COMMON_INTERCEPT_FUNCTION(munlockall);6640 6641#else6642#define INIT_MLOCKX6643#endif // SANITIZER_INTERCEPT_MLOCKX6644 6645#if SANITIZER_INTERCEPT_FOPENCOOKIE6646struct WrappedCookie {6647 void *real_cookie;6648 __sanitizer_cookie_io_functions_t real_io_funcs;6649};6650 6651static uptr wrapped_read(void *cookie, char *buf, uptr size) {6652 COMMON_INTERCEPTOR_UNPOISON_PARAM(3);6653 WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;6654 __sanitizer_cookie_io_read real_read = wrapped_cookie->real_io_funcs.read;6655 return real_read ? real_read(wrapped_cookie->real_cookie, buf, size) : 0;6656}6657 6658static uptr wrapped_write(void *cookie, const char *buf, uptr size) {6659 COMMON_INTERCEPTOR_UNPOISON_PARAM(3);6660 WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;6661 __sanitizer_cookie_io_write real_write = wrapped_cookie->real_io_funcs.write;6662 return real_write ? real_write(wrapped_cookie->real_cookie, buf, size) : size;6663}6664 6665static int wrapped_seek(void *cookie, u64 *offset, int whence) {6666 COMMON_INTERCEPTOR_UNPOISON_PARAM(3);6667 COMMON_INTERCEPTOR_INITIALIZE_RANGE(offset, sizeof(*offset));6668 WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;6669 __sanitizer_cookie_io_seek real_seek = wrapped_cookie->real_io_funcs.seek;6670 return real_seek ? real_seek(wrapped_cookie->real_cookie, offset, whence)6671 : -1;6672}6673 6674static int wrapped_close(void *cookie) {6675 COMMON_INTERCEPTOR_UNPOISON_PARAM(1);6676 WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;6677 __sanitizer_cookie_io_close real_close = wrapped_cookie->real_io_funcs.close;6678 int res = real_close ? real_close(wrapped_cookie->real_cookie) : 0;6679 InternalFree(wrapped_cookie);6680 return res;6681}6682 6683INTERCEPTOR(__sanitizer_FILE *, fopencookie, void *cookie, const char *mode,6684 __sanitizer_cookie_io_functions_t io_funcs) {6685 void *ctx;6686 COMMON_INTERCEPTOR_ENTER(ctx, fopencookie, cookie, mode, io_funcs);6687 WrappedCookie *wrapped_cookie =6688 (WrappedCookie *)InternalAlloc(sizeof(WrappedCookie));6689 wrapped_cookie->real_cookie = cookie;6690 wrapped_cookie->real_io_funcs = io_funcs;6691 __sanitizer_FILE *res =6692 REAL(fopencookie)(wrapped_cookie, mode, {wrapped_read, wrapped_write,6693 wrapped_seek, wrapped_close});6694 return res;6695}6696 6697#define INIT_FOPENCOOKIE COMMON_INTERCEPT_FUNCTION(fopencookie);6698#else6699#define INIT_FOPENCOOKIE6700#endif // SANITIZER_INTERCEPT_FOPENCOOKIE6701 6702#if SANITIZER_INTERCEPT_SEM6703INTERCEPTOR(int, sem_init, __sanitizer_sem_t *s, int pshared, unsigned value) {6704 void *ctx;6705 COMMON_INTERCEPTOR_ENTER(ctx, sem_init, s, pshared, value);6706 // Workaround a bug in glibc's "old" semaphore implementation by6707 // zero-initializing the sem_t contents. This has to be done here because6708 // interceptors bind to the lowest version before glibc 2.36, hitting the6709 // buggy code path while the non-sanitized build of the same code works fine.6710 REAL(memset)(s, 0, sizeof(*s));6711 int res = REAL(sem_init)(s, pshared, value);6712 return res;6713}6714 6715INTERCEPTOR(int, sem_destroy, __sanitizer_sem_t *s) {6716 void *ctx;6717 COMMON_INTERCEPTOR_ENTER(ctx, sem_destroy, s);6718 int res = REAL(sem_destroy)(s);6719 return res;6720}6721 6722INTERCEPTOR(int, sem_wait, __sanitizer_sem_t *s) {6723 void *ctx;6724 COMMON_INTERCEPTOR_ENTER(ctx, sem_wait, s);6725 int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_wait)(s);6726 if (res == 0) {6727 COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);6728 }6729 return res;6730}6731 6732INTERCEPTOR(int, sem_trywait, __sanitizer_sem_t *s) {6733 void *ctx;6734 COMMON_INTERCEPTOR_ENTER(ctx, sem_trywait, s);6735 int res = REAL(sem_trywait)(s);6736 if (res == 0) {6737 COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);6738 }6739 return res;6740}6741 6742INTERCEPTOR(int, sem_timedwait, __sanitizer_sem_t *s, void *abstime) {6743 void *ctx;6744 COMMON_INTERCEPTOR_ENTER(ctx, sem_timedwait, s, abstime);6745 COMMON_INTERCEPTOR_READ_RANGE(ctx, abstime, struct_timespec_sz);6746 int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_timedwait)(s, abstime);6747 if (res == 0) {6748 COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);6749 }6750 return res;6751}6752 6753INTERCEPTOR(int, sem_post, __sanitizer_sem_t *s) {6754 void *ctx;6755 COMMON_INTERCEPTOR_ENTER(ctx, sem_post, s);6756 COMMON_INTERCEPTOR_RELEASE(ctx, (uptr)s);6757 int res = REAL(sem_post)(s);6758 return res;6759}6760 6761INTERCEPTOR(int, sem_getvalue, __sanitizer_sem_t *s, int *sval) {6762 void *ctx;6763 COMMON_INTERCEPTOR_ENTER(ctx, sem_getvalue, s, sval);6764 int res = REAL(sem_getvalue)(s, sval);6765 if (res == 0) {6766 COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);6767 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sval, sizeof(*sval));6768 }6769 return res;6770}6771 6772INTERCEPTOR(__sanitizer_sem_t *, sem_open, const char *name, int oflag, ...) {6773 void *ctx;6774 va_list ap;6775 va_start(ap, oflag);6776 u32 mode = va_arg(ap, u32);6777 u32 value = va_arg(ap, u32);6778 COMMON_INTERCEPTOR_ENTER(ctx, sem_open, name, oflag, mode, value);6779 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);6780 __sanitizer_sem_t *s = REAL(sem_open)(name, oflag, mode, value);6781 if (s)6782 COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, sizeof(*s));6783 va_end(ap);6784 return s;6785}6786 6787INTERCEPTOR(int, sem_unlink, const char *name) {6788 void *ctx;6789 COMMON_INTERCEPTOR_ENTER(ctx, sem_unlink, name);6790 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);6791 return REAL(sem_unlink)(name);6792}6793 6794# define INIT_SEM \6795 COMMON_INTERCEPT_FUNCTION(sem_init); \6796 COMMON_INTERCEPT_FUNCTION(sem_destroy); \6797 COMMON_INTERCEPT_FUNCTION(sem_wait); \6798 COMMON_INTERCEPT_FUNCTION(sem_trywait); \6799 COMMON_INTERCEPT_FUNCTION(sem_timedwait); \6800 COMMON_INTERCEPT_FUNCTION(sem_post); \6801 COMMON_INTERCEPT_FUNCTION(sem_getvalue); \6802 COMMON_INTERCEPT_FUNCTION(sem_open); \6803 COMMON_INTERCEPT_FUNCTION(sem_unlink);6804#else6805# define INIT_SEM6806#endif // SANITIZER_INTERCEPT_SEM6807 6808#if SANITIZER_INTERCEPT_PTHREAD_SETCANCEL6809INTERCEPTOR(int, pthread_setcancelstate, int state, int *oldstate) {6810 void *ctx;6811 COMMON_INTERCEPTOR_ENTER(ctx, pthread_setcancelstate, state, oldstate);6812 int res = REAL(pthread_setcancelstate)(state, oldstate);6813 if (res == 0 && oldstate != nullptr)6814 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldstate, sizeof(*oldstate));6815 return res;6816}6817 6818INTERCEPTOR(int, pthread_setcanceltype, int type, int *oldtype) {6819 void *ctx;6820 COMMON_INTERCEPTOR_ENTER(ctx, pthread_setcanceltype, type, oldtype);6821 int res = REAL(pthread_setcanceltype)(type, oldtype);6822 if (res == 0 && oldtype != nullptr)6823 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldtype, sizeof(*oldtype));6824 return res;6825}6826#define INIT_PTHREAD_SETCANCEL \6827 COMMON_INTERCEPT_FUNCTION(pthread_setcancelstate); \6828 COMMON_INTERCEPT_FUNCTION(pthread_setcanceltype);6829#else6830#define INIT_PTHREAD_SETCANCEL6831#endif6832 6833#if SANITIZER_INTERCEPT_MINCORE6834INTERCEPTOR(int, mincore, void *addr, uptr length, unsigned char *vec) {6835 void *ctx;6836 COMMON_INTERCEPTOR_ENTER(ctx, mincore, addr, length, vec);6837 int res = REAL(mincore)(addr, length, vec);6838 if (res == 0) {6839 uptr page_size = GetPageSizeCached();6840 uptr vec_size = ((length + page_size - 1) & (~(page_size - 1))) / page_size;6841 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, vec, vec_size);6842 }6843 return res;6844}6845#define INIT_MINCORE COMMON_INTERCEPT_FUNCTION(mincore);6846#else6847#define INIT_MINCORE6848#endif6849 6850#if SANITIZER_INTERCEPT_PROCESS_VM_READV6851INTERCEPTOR(SSIZE_T, process_vm_readv, int pid, __sanitizer_iovec *local_iov,6852 uptr liovcnt, __sanitizer_iovec *remote_iov, uptr riovcnt,6853 uptr flags) {6854 void *ctx;6855 COMMON_INTERCEPTOR_ENTER(ctx, process_vm_readv, pid, local_iov, liovcnt,6856 remote_iov, riovcnt, flags);6857 SSIZE_T res = REAL(process_vm_readv)(pid, local_iov, liovcnt, remote_iov,6858 riovcnt, flags);6859 if (res > 0)6860 write_iovec(ctx, local_iov, liovcnt, res);6861 return res;6862}6863 6864INTERCEPTOR(SSIZE_T, process_vm_writev, int pid, __sanitizer_iovec *local_iov,6865 uptr liovcnt, __sanitizer_iovec *remote_iov, uptr riovcnt,6866 uptr flags) {6867 void *ctx;6868 COMMON_INTERCEPTOR_ENTER(ctx, process_vm_writev, pid, local_iov, liovcnt,6869 remote_iov, riovcnt, flags);6870 SSIZE_T res = REAL(process_vm_writev)(pid, local_iov, liovcnt, remote_iov,6871 riovcnt, flags);6872 if (res > 0)6873 read_iovec(ctx, local_iov, liovcnt, res);6874 return res;6875}6876#define INIT_PROCESS_VM_READV \6877 COMMON_INTERCEPT_FUNCTION(process_vm_readv); \6878 COMMON_INTERCEPT_FUNCTION(process_vm_writev);6879#else6880#define INIT_PROCESS_VM_READV6881#endif6882 6883#if SANITIZER_INTERCEPT_CTERMID6884INTERCEPTOR(char *, ctermid, char *s) {6885 void *ctx;6886 COMMON_INTERCEPTOR_ENTER(ctx, ctermid, s);6887 char *res = REAL(ctermid)(s);6888 if (res) {6889 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);6890 }6891 return res;6892}6893#define INIT_CTERMID COMMON_INTERCEPT_FUNCTION(ctermid);6894#else6895#define INIT_CTERMID6896#endif6897 6898#if SANITIZER_INTERCEPT_CTERMID_R6899INTERCEPTOR(char *, ctermid_r, char *s) {6900 void *ctx;6901 COMMON_INTERCEPTOR_ENTER(ctx, ctermid_r, s);6902 char *res = REAL(ctermid_r)(s);6903 if (res) {6904 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);6905 }6906 return res;6907}6908#define INIT_CTERMID_R COMMON_INTERCEPT_FUNCTION(ctermid_r);6909#else6910#define INIT_CTERMID_R6911#endif6912 6913#if SANITIZER_INTERCEPT_RECV_RECVFROM6914INTERCEPTOR(SSIZE_T, recv, int fd, void *buf, SIZE_T len, int flags) {6915 void *ctx;6916 COMMON_INTERCEPTOR_ENTER(ctx, recv, fd, buf, len, flags);6917 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);6918 SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(recv)(fd, buf, len, flags);6919 if (res > 0) {6920 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, Min((SIZE_T)res, len));6921 }6922 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);6923 return res;6924}6925 6926INTERCEPTOR(SSIZE_T, recvfrom, int fd, void *buf, SIZE_T len, int flags,6927 void *srcaddr, int *addrlen) {6928 void *ctx;6929 COMMON_INTERCEPTOR_ENTER(ctx, recvfrom, fd, buf, len, flags, srcaddr,6930 addrlen);6931 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);6932 SIZE_T srcaddr_sz;6933 if (srcaddr) srcaddr_sz = *addrlen;6934 (void)srcaddr_sz; // prevent "set but not used" warning6935 SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(recvfrom)(fd, buf, len, flags,6936 srcaddr, addrlen);6937 if (res > 0)6938 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, Min((SIZE_T)res, len));6939 if (res >= 0 && srcaddr)6940 COMMON_INTERCEPTOR_INITIALIZE_RANGE(srcaddr,6941 Min((SIZE_T)*addrlen, srcaddr_sz));6942 return res;6943}6944#define INIT_RECV_RECVFROM \6945 COMMON_INTERCEPT_FUNCTION(recv); \6946 COMMON_INTERCEPT_FUNCTION(recvfrom);6947#else6948#define INIT_RECV_RECVFROM6949#endif6950 6951#if SANITIZER_INTERCEPT_SEND_SENDTO6952INTERCEPTOR(SSIZE_T, send, int fd, void *buf, SIZE_T len, int flags) {6953 void *ctx;6954 COMMON_INTERCEPTOR_ENTER(ctx, send, fd, buf, len, flags);6955 if (fd >= 0) {6956 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);6957 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);6958 }6959 SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(send)(fd, buf, len, flags);6960 if (common_flags()->intercept_send && res > 0)6961 COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, Min((SIZE_T)res, len));6962 return res;6963}6964 6965INTERCEPTOR(SSIZE_T, sendto, int fd, void *buf, SIZE_T len, int flags,6966 void *dstaddr, int addrlen) {6967 void *ctx;6968 COMMON_INTERCEPTOR_ENTER(ctx, sendto, fd, buf, len, flags, dstaddr, addrlen);6969 if (fd >= 0) {6970 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);6971 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);6972 }6973 // Can't check dstaddr as it may have uninitialized padding at the end.6974 SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(sendto)(fd, buf, len, flags,6975 dstaddr, addrlen);6976 if (common_flags()->intercept_send && res > 0)6977 COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, Min((SIZE_T)res, len));6978 return res;6979}6980#define INIT_SEND_SENDTO \6981 COMMON_INTERCEPT_FUNCTION(send); \6982 COMMON_INTERCEPT_FUNCTION(sendto);6983#else6984#define INIT_SEND_SENDTO6985#endif6986 6987#if SANITIZER_INTERCEPT_EVENTFD_READ_WRITE6988INTERCEPTOR(int, eventfd_read, int fd, __sanitizer_eventfd_t *value) {6989 void *ctx;6990 COMMON_INTERCEPTOR_ENTER(ctx, eventfd_read, fd, value);6991 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);6992 int res = COMMON_INTERCEPTOR_BLOCK_REAL(eventfd_read)(fd, value);6993 if (res == 0) {6994 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, sizeof(*value));6995 if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);6996 }6997 return res;6998}6999INTERCEPTOR(int, eventfd_write, int fd, __sanitizer_eventfd_t value) {7000 void *ctx;7001 COMMON_INTERCEPTOR_ENTER(ctx, eventfd_write, fd, value);7002 if (fd >= 0) {7003 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);7004 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);7005 }7006 int res = COMMON_INTERCEPTOR_BLOCK_REAL(eventfd_write)(fd, value);7007 return res;7008}7009#define INIT_EVENTFD_READ_WRITE \7010 COMMON_INTERCEPT_FUNCTION(eventfd_read); \7011 COMMON_INTERCEPT_FUNCTION(eventfd_write)7012#else7013#define INIT_EVENTFD_READ_WRITE7014#endif7015 7016#if SANITIZER_INTERCEPT_STAT7017INTERCEPTOR(int, stat, const char *path, void *buf) {7018 void *ctx;7019 COMMON_INTERCEPTOR_ENTER(ctx, stat, path, buf);7020 if (common_flags()->intercept_stat)7021 COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);7022 int res = REAL(stat)(path, buf);7023 if (!res)7024 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz);7025 return res;7026}7027#define INIT_STAT COMMON_INTERCEPT_FUNCTION(stat)7028#else7029#define INIT_STAT7030#endif7031 7032#if SANITIZER_INTERCEPT_STAT647033INTERCEPTOR(int, stat64, const char *path, void *buf) {7034 void *ctx;7035 COMMON_INTERCEPTOR_ENTER(ctx, stat64, path, buf);7036 if (common_flags()->intercept_stat)7037 COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);7038 int res = REAL(stat64)(path, buf);7039 if (!res)7040 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat64_sz);7041 return res;7042}7043#define INIT_STAT64 COMMON_INTERCEPT_FUNCTION(stat64)7044#else7045#define INIT_STAT647046#endif7047 7048 7049#if SANITIZER_INTERCEPT_LSTAT7050INTERCEPTOR(int, lstat, const char *path, void *buf) {7051 void *ctx;7052 COMMON_INTERCEPTOR_ENTER(ctx, lstat, path, buf);7053 if (common_flags()->intercept_stat)7054 COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);7055 int res = REAL(lstat)(path, buf);7056 if (!res)7057 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz);7058 return res;7059}7060#define INIT_LSTAT COMMON_INTERCEPT_FUNCTION(lstat)7061#else7062#define INIT_LSTAT7063#endif7064 7065#if SANITIZER_INTERCEPT_STAT647066INTERCEPTOR(int, lstat64, const char *path, void *buf) {7067 void *ctx;7068 COMMON_INTERCEPTOR_ENTER(ctx, lstat64, path, buf);7069 if (common_flags()->intercept_stat)7070 COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);7071 int res = REAL(lstat64)(path, buf);7072 if (!res)7073 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat64_sz);7074 return res;7075}7076#define INIT_LSTAT64 COMMON_INTERCEPT_FUNCTION(lstat64)7077#else7078#define INIT_LSTAT647079#endif7080 7081#if SANITIZER_INTERCEPT___XSTAT7082INTERCEPTOR(int, __xstat, int version, const char *path, void *buf) {7083 void *ctx;7084 COMMON_INTERCEPTOR_ENTER(ctx, __xstat, version, path, buf);7085 if (common_flags()->intercept_stat)7086 COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);7087 int res = REAL(__xstat)(version, path, buf);7088 if (!res)7089 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz);7090 return res;7091}7092#define INIT___XSTAT COMMON_INTERCEPT_FUNCTION(__xstat)7093#else7094#define INIT___XSTAT7095#endif7096 7097#if SANITIZER_INTERCEPT___XSTAT647098INTERCEPTOR(int, __xstat64, int version, const char *path, void *buf) {7099 void *ctx;7100 COMMON_INTERCEPTOR_ENTER(ctx, __xstat64, version, path, buf);7101 if (common_flags()->intercept_stat)7102 COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);7103 int res = REAL(__xstat64)(version, path, buf);7104 if (!res)7105 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat64_sz);7106 return res;7107}7108#define INIT___XSTAT64 COMMON_INTERCEPT_FUNCTION(__xstat64)7109#else7110#define INIT___XSTAT647111#endif7112 7113#if SANITIZER_INTERCEPT___LXSTAT7114INTERCEPTOR(int, __lxstat, int version, const char *path, void *buf) {7115 void *ctx;7116 COMMON_INTERCEPTOR_ENTER(ctx, __lxstat, version, path, buf);7117 if (common_flags()->intercept_stat)7118 COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);7119 int res = REAL(__lxstat)(version, path, buf);7120 if (!res)7121 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz);7122 return res;7123}7124#define INIT___LXSTAT COMMON_INTERCEPT_FUNCTION(__lxstat)7125#else7126#define INIT___LXSTAT7127#endif7128 7129#if SANITIZER_INTERCEPT___LXSTAT647130INTERCEPTOR(int, __lxstat64, int version, const char *path, void *buf) {7131 void *ctx;7132 COMMON_INTERCEPTOR_ENTER(ctx, __lxstat64, version, path, buf);7133 if (common_flags()->intercept_stat)7134 COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);7135 int res = REAL(__lxstat64)(version, path, buf);7136 if (!res)7137 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat64_sz);7138 return res;7139}7140#define INIT___LXSTAT64 COMMON_INTERCEPT_FUNCTION(__lxstat64)7141#else7142#define INIT___LXSTAT647143#endif7144 7145// FIXME: add other *stat interceptor7146 7147#if SANITIZER_INTERCEPT_UTMP7148INTERCEPTOR(void *, getutent, int dummy) {7149 void *ctx;7150 COMMON_INTERCEPTOR_ENTER(ctx, getutent, dummy);7151 void *res = REAL(getutent)(dummy);7152 if (res)7153 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmp_sz);7154 return res;7155}7156INTERCEPTOR(void *, getutid, void *ut) {7157 void *ctx;7158 COMMON_INTERCEPTOR_ENTER(ctx, getutid, ut);7159 void *res = REAL(getutid)(ut);7160 if (res)7161 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmp_sz);7162 return res;7163}7164INTERCEPTOR(void *, getutline, void *ut) {7165 void *ctx;7166 COMMON_INTERCEPTOR_ENTER(ctx, getutline, ut);7167 void *res = REAL(getutline)(ut);7168 if (res)7169 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmp_sz);7170 return res;7171}7172#define INIT_UTMP \7173 COMMON_INTERCEPT_FUNCTION(getutent); \7174 COMMON_INTERCEPT_FUNCTION(getutid); \7175 COMMON_INTERCEPT_FUNCTION(getutline);7176#else7177#define INIT_UTMP7178#endif7179 7180#if SANITIZER_INTERCEPT_UTMPX7181INTERCEPTOR(void *, getutxent, int dummy) {7182 void *ctx;7183 COMMON_INTERCEPTOR_ENTER(ctx, getutxent, dummy);7184 void *res = REAL(getutxent)(dummy);7185 if (res)7186 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmpx_sz);7187 return res;7188}7189INTERCEPTOR(void *, getutxid, void *ut) {7190 void *ctx;7191 COMMON_INTERCEPTOR_ENTER(ctx, getutxid, ut);7192 void *res = REAL(getutxid)(ut);7193 if (res)7194 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmpx_sz);7195 return res;7196}7197INTERCEPTOR(void *, getutxline, void *ut) {7198 void *ctx;7199 COMMON_INTERCEPTOR_ENTER(ctx, getutxline, ut);7200 void *res = REAL(getutxline)(ut);7201 if (res)7202 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmpx_sz);7203 return res;7204}7205INTERCEPTOR(void *, pututxline, const void *ut) {7206 void *ctx;7207 COMMON_INTERCEPTOR_ENTER(ctx, pututxline, ut);7208 if (ut)7209 COMMON_INTERCEPTOR_READ_RANGE(ctx, ut, __sanitizer::struct_utmpx_sz);7210 void *res = REAL(pututxline)(ut);7211 if (res)7212 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, __sanitizer::struct_utmpx_sz);7213 return res;7214}7215#define INIT_UTMPX \7216 COMMON_INTERCEPT_FUNCTION(getutxent); \7217 COMMON_INTERCEPT_FUNCTION(getutxid); \7218 COMMON_INTERCEPT_FUNCTION(getutxline); \7219 COMMON_INTERCEPT_FUNCTION(pututxline);7220#else7221#define INIT_UTMPX7222#endif7223 7224#if SANITIZER_INTERCEPT_GETLOADAVG7225INTERCEPTOR(int, getloadavg, double *loadavg, int nelem) {7226 void *ctx;7227 COMMON_INTERCEPTOR_ENTER(ctx, getloadavg, loadavg, nelem);7228 int res = REAL(getloadavg)(loadavg, nelem);7229 if (res > 0)7230 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, loadavg, res * sizeof(*loadavg));7231 return res;7232}7233#define INIT_GETLOADAVG \7234 COMMON_INTERCEPT_FUNCTION(getloadavg);7235#else7236#define INIT_GETLOADAVG7237#endif7238 7239#if SANITIZER_INTERCEPT_MCHECK_MPROBE7240INTERCEPTOR(int, mcheck, void (*abortfunc)(int mstatus)) {7241 return 0;7242}7243 7244INTERCEPTOR(int, mcheck_pedantic, void (*abortfunc)(int mstatus)) {7245 return 0;7246}7247 7248INTERCEPTOR(int, mprobe, void *ptr) {7249 return 0;7250}7251#endif7252 7253#if SANITIZER_INTERCEPT_WCSLEN7254INTERCEPTOR(SIZE_T, wcslen, const wchar_t *s) {7255 void *ctx;7256 COMMON_INTERCEPTOR_ENTER(ctx, wcslen, s);7257 SIZE_T res = REAL(wcslen)(s);7258 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, sizeof(wchar_t) * (res + 1));7259 return res;7260}7261 7262INTERCEPTOR(SIZE_T, wcsnlen, const wchar_t *s, SIZE_T n) {7263 void *ctx;7264 COMMON_INTERCEPTOR_ENTER(ctx, wcsnlen, s, n);7265 SIZE_T res = REAL(wcsnlen)(s, n);7266 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, sizeof(wchar_t) * Min(res + 1, n));7267 return res;7268}7269#define INIT_WCSLEN \7270 COMMON_INTERCEPT_FUNCTION(wcslen); \7271 COMMON_INTERCEPT_FUNCTION(wcsnlen);7272#else7273#define INIT_WCSLEN7274#endif7275 7276#if SANITIZER_INTERCEPT_WCSCAT7277INTERCEPTOR(wchar_t *, wcscat, wchar_t *dst, const wchar_t *src) {7278 void *ctx;7279 COMMON_INTERCEPTOR_ENTER(ctx, wcscat, dst, src);7280 SIZE_T src_size = internal_wcslen(src);7281 SIZE_T dst_size = internal_wcslen(dst);7282 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, (src_size + 1) * sizeof(wchar_t));7283 COMMON_INTERCEPTOR_READ_RANGE(ctx, dst, (dst_size + 1) * sizeof(wchar_t));7284 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst + dst_size,7285 (src_size + 1) * sizeof(wchar_t));7286 return REAL(wcscat)(dst, src);7287}7288 7289INTERCEPTOR(wchar_t *, wcsncat, wchar_t *dst, const wchar_t *src, SIZE_T n) {7290 void *ctx;7291 COMMON_INTERCEPTOR_ENTER(ctx, wcsncat, dst, src, n);7292 SIZE_T src_size = internal_wcsnlen(src, n);7293 SIZE_T dst_size = internal_wcslen(dst);7294 COMMON_INTERCEPTOR_READ_RANGE(ctx, src,7295 Min(src_size + 1, n) * sizeof(wchar_t));7296 COMMON_INTERCEPTOR_READ_RANGE(ctx, dst, (dst_size + 1) * sizeof(wchar_t));7297 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst + dst_size,7298 (src_size + 1) * sizeof(wchar_t));7299 return REAL(wcsncat)(dst, src, n);7300}7301#define INIT_WCSCAT \7302 COMMON_INTERCEPT_FUNCTION(wcscat); \7303 COMMON_INTERCEPT_FUNCTION(wcsncat);7304#else7305#define INIT_WCSCAT7306#endif7307 7308#if SANITIZER_INTERCEPT_WCSDUP7309INTERCEPTOR(wchar_t *, wcsdup, wchar_t *s) {7310 void *ctx;7311 COMMON_INTERCEPTOR_ENTER(ctx, wcsdup, s);7312 SIZE_T len = internal_wcslen(s);7313 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, sizeof(wchar_t) * (len + 1));7314 wchar_t *result = REAL(wcsdup)(s);7315 if (result)7316 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(wchar_t) * (len + 1));7317 return result;7318}7319 7320#define INIT_WCSDUP COMMON_INTERCEPT_FUNCTION(wcsdup);7321#else7322#define INIT_WCSDUP7323#endif7324 7325#if SANITIZER_INTERCEPT_STRXFRM7326static SIZE_T RealStrLen(const char *str) { return internal_strlen(str); }7327 7328static SIZE_T RealStrLen(const wchar_t *str) { return internal_wcslen(str); }7329 7330#define STRXFRM_INTERCEPTOR_IMPL(strxfrm, dest, src, len, ...) \7331 { \7332 void *ctx; \7333 COMMON_INTERCEPTOR_ENTER(ctx, strxfrm, dest, src, len, ##__VA_ARGS__); \7334 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, \7335 sizeof(*src) * (RealStrLen(src) + 1)); \7336 SIZE_T res = REAL(strxfrm)(dest, src, len, ##__VA_ARGS__); \7337 if (res < len) \7338 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, sizeof(*src) * (res + 1)); \7339 return res; \7340 }7341 7342INTERCEPTOR(SIZE_T, strxfrm, char *dest, const char *src, SIZE_T len) {7343 STRXFRM_INTERCEPTOR_IMPL(strxfrm, dest, src, len);7344}7345 7346INTERCEPTOR(SIZE_T, strxfrm_l, char *dest, const char *src, SIZE_T len,7347 void *locale) {7348 STRXFRM_INTERCEPTOR_IMPL(strxfrm_l, dest, src, len, locale);7349}7350 7351#define INIT_STRXFRM \7352 COMMON_INTERCEPT_FUNCTION(strxfrm); \7353 COMMON_INTERCEPT_FUNCTION(strxfrm_l);7354#else7355#define INIT_STRXFRM7356#endif7357 7358#if SANITIZER_INTERCEPT___STRXFRM_L7359INTERCEPTOR(SIZE_T, __strxfrm_l, char *dest, const char *src, SIZE_T len,7360 void *locale) {7361 STRXFRM_INTERCEPTOR_IMPL(__strxfrm_l, dest, src, len, locale);7362}7363 7364#define INIT___STRXFRM_L COMMON_INTERCEPT_FUNCTION(__strxfrm_l);7365#else7366#define INIT___STRXFRM_L7367#endif7368 7369#if SANITIZER_INTERCEPT_WCSXFRM7370INTERCEPTOR(SIZE_T, wcsxfrm, wchar_t *dest, const wchar_t *src, SIZE_T len) {7371 STRXFRM_INTERCEPTOR_IMPL(wcsxfrm, dest, src, len);7372}7373 7374INTERCEPTOR(SIZE_T, wcsxfrm_l, wchar_t *dest, const wchar_t *src, SIZE_T len,7375 void *locale) {7376 STRXFRM_INTERCEPTOR_IMPL(wcsxfrm_l, dest, src, len, locale);7377}7378 7379#define INIT_WCSXFRM \7380 COMMON_INTERCEPT_FUNCTION(wcsxfrm); \7381 COMMON_INTERCEPT_FUNCTION(wcsxfrm_l);7382#else7383#define INIT_WCSXFRM7384#endif7385 7386#if SANITIZER_INTERCEPT___WCSXFRM_L7387INTERCEPTOR(SIZE_T, __wcsxfrm_l, wchar_t *dest, const wchar_t *src, SIZE_T len,7388 void *locale) {7389 STRXFRM_INTERCEPTOR_IMPL(__wcsxfrm_l, dest, src, len, locale);7390}7391 7392#define INIT___WCSXFRM_L COMMON_INTERCEPT_FUNCTION(__wcsxfrm_l);7393#else7394#define INIT___WCSXFRM_L7395#endif7396 7397#if SANITIZER_INTERCEPT_ACCT7398INTERCEPTOR(int, acct, const char *file) {7399 void *ctx;7400 COMMON_INTERCEPTOR_ENTER(ctx, acct, file);7401 if (file)7402 COMMON_INTERCEPTOR_READ_RANGE(ctx, file, internal_strlen(file) + 1);7403 return REAL(acct)(file);7404}7405#define INIT_ACCT COMMON_INTERCEPT_FUNCTION(acct)7406#else7407#define INIT_ACCT7408#endif7409 7410#if SANITIZER_INTERCEPT_USER_FROM_UID7411INTERCEPTOR(const char *, user_from_uid, u32 uid, int nouser) {7412 void *ctx;7413 const char *user;7414 COMMON_INTERCEPTOR_ENTER(ctx, user_from_uid, uid, nouser);7415 user = REAL(user_from_uid)(uid, nouser);7416 if (user)7417 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, user, internal_strlen(user) + 1);7418 return user;7419}7420#define INIT_USER_FROM_UID COMMON_INTERCEPT_FUNCTION(user_from_uid)7421#else7422#define INIT_USER_FROM_UID7423#endif7424 7425#if SANITIZER_INTERCEPT_UID_FROM_USER7426INTERCEPTOR(int, uid_from_user, const char *name, u32 *uid) {7427 void *ctx;7428 int res;7429 COMMON_INTERCEPTOR_ENTER(ctx, uid_from_user, name, uid);7430 if (name)7431 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);7432 res = REAL(uid_from_user)(name, uid);7433 if (uid)7434 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, uid, sizeof(*uid));7435 return res;7436}7437#define INIT_UID_FROM_USER COMMON_INTERCEPT_FUNCTION(uid_from_user)7438#else7439#define INIT_UID_FROM_USER7440#endif7441 7442#if SANITIZER_INTERCEPT_GROUP_FROM_GID7443INTERCEPTOR(const char *, group_from_gid, u32 gid, int nogroup) {7444 void *ctx;7445 const char *group;7446 COMMON_INTERCEPTOR_ENTER(ctx, group_from_gid, gid, nogroup);7447 group = REAL(group_from_gid)(gid, nogroup);7448 if (group)7449 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, group, internal_strlen(group) + 1);7450 return group;7451}7452#define INIT_GROUP_FROM_GID COMMON_INTERCEPT_FUNCTION(group_from_gid)7453#else7454#define INIT_GROUP_FROM_GID7455#endif7456 7457#if SANITIZER_INTERCEPT_GID_FROM_GROUP7458INTERCEPTOR(int, gid_from_group, const char *group, u32 *gid) {7459 void *ctx;7460 int res;7461 COMMON_INTERCEPTOR_ENTER(ctx, gid_from_group, group, gid);7462 if (group)7463 COMMON_INTERCEPTOR_READ_RANGE(ctx, group, internal_strlen(group) + 1);7464 res = REAL(gid_from_group)(group, gid);7465 if (gid)7466 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, gid, sizeof(*gid));7467 return res;7468}7469#define INIT_GID_FROM_GROUP COMMON_INTERCEPT_FUNCTION(gid_from_group)7470#else7471#define INIT_GID_FROM_GROUP7472#endif7473 7474#if SANITIZER_INTERCEPT_ACCESS7475INTERCEPTOR(int, access, const char *path, int mode) {7476 void *ctx;7477 COMMON_INTERCEPTOR_ENTER(ctx, access, path, mode);7478 if (path)7479 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);7480 return REAL(access)(path, mode);7481}7482#define INIT_ACCESS COMMON_INTERCEPT_FUNCTION(access)7483#else7484#define INIT_ACCESS7485#endif7486 7487#if SANITIZER_INTERCEPT_FACCESSAT7488INTERCEPTOR(int, faccessat, int fd, const char *path, int mode, int flags) {7489 void *ctx;7490 COMMON_INTERCEPTOR_ENTER(ctx, faccessat, fd, path, mode, flags);7491 if (path)7492 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);7493 return REAL(faccessat)(fd, path, mode, flags);7494}7495#define INIT_FACCESSAT COMMON_INTERCEPT_FUNCTION(faccessat)7496#else7497#define INIT_FACCESSAT7498#endif7499 7500#if SANITIZER_INTERCEPT_GETGROUPLIST7501INTERCEPTOR(int, getgrouplist, const char *name, u32 basegid, u32 *groups,7502 int *ngroups) {7503 void *ctx;7504 int res;7505 COMMON_INTERCEPTOR_ENTER(ctx, getgrouplist, name, basegid, groups, ngroups);7506 if (name)7507 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);7508 if (ngroups)7509 COMMON_INTERCEPTOR_READ_RANGE(ctx, ngroups, sizeof(*ngroups));7510 res = REAL(getgrouplist)(name, basegid, groups, ngroups);7511 if (!res && groups && ngroups) {7512 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, groups, sizeof(*groups) * (*ngroups));7513 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ngroups, sizeof(*ngroups));7514 }7515 return res;7516}7517 7518#define INIT_GETGROUPLIST COMMON_INTERCEPT_FUNCTION(getgrouplist);7519#else7520#define INIT_GETGROUPLIST7521#endif7522 7523#if SANITIZER_INTERCEPT_GETGROUPMEMBERSHIP7524INTERCEPTOR(int, getgroupmembership, const char *name, u32 basegid, u32 *groups,7525 int maxgrp, int *ngroups) {7526 void *ctx;7527 int res;7528 COMMON_INTERCEPTOR_ENTER(ctx, getgroupmembership, name, basegid, groups,7529 maxgrp, ngroups);7530 if (name)7531 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);7532 res = REAL(getgroupmembership)(name, basegid, groups, maxgrp, ngroups);7533 if (!res && groups && ngroups) {7534 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, groups, sizeof(*groups) * (*ngroups));7535 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ngroups, sizeof(*ngroups));7536 }7537 return res;7538}7539 7540#define INIT_GETGROUPMEMBERSHIP COMMON_INTERCEPT_FUNCTION(getgroupmembership);7541#else7542#define INIT_GETGROUPMEMBERSHIP7543#endif7544 7545#if SANITIZER_INTERCEPT_READLINK7546INTERCEPTOR(SSIZE_T, readlink, const char *path, char *buf, SIZE_T bufsiz) {7547 void* ctx;7548 COMMON_INTERCEPTOR_ENTER(ctx, readlink, path, buf, bufsiz);7549 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);7550 SSIZE_T res = REAL(readlink)(path, buf, bufsiz);7551 if (res > 0)7552 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res);7553 return res;7554}7555 7556#define INIT_READLINK COMMON_INTERCEPT_FUNCTION(readlink)7557#else7558#define INIT_READLINK7559#endif7560 7561#if SANITIZER_INTERCEPT_READLINKAT7562INTERCEPTOR(SSIZE_T, readlinkat, int dirfd, const char *path, char *buf,7563 SIZE_T bufsiz) {7564 void* ctx;7565 COMMON_INTERCEPTOR_ENTER(ctx, readlinkat, dirfd, path, buf, bufsiz);7566 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);7567 SSIZE_T res = REAL(readlinkat)(dirfd, path, buf, bufsiz);7568 if (res > 0)7569 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res);7570 return res;7571}7572 7573#define INIT_READLINKAT COMMON_INTERCEPT_FUNCTION(readlinkat)7574#else7575#define INIT_READLINKAT7576#endif7577 7578#if SANITIZER_INTERCEPT_NAME_TO_HANDLE_AT7579INTERCEPTOR(int, name_to_handle_at, int dirfd, const char *pathname,7580 struct file_handle *handle, int *mount_id, int flags) {7581 void* ctx;7582 COMMON_INTERCEPTOR_ENTER(ctx, name_to_handle_at, dirfd, pathname, handle,7583 mount_id, flags);7584 COMMON_INTERCEPTOR_READ_RANGE(ctx, pathname, internal_strlen(pathname) + 1);7585 7586 __sanitizer_file_handle *sanitizer_handle =7587 reinterpret_cast<__sanitizer_file_handle*>(handle);7588 COMMON_INTERCEPTOR_READ_RANGE(7589 ctx, &sanitizer_handle->handle_bytes,7590 sizeof(sanitizer_handle->handle_bytes));7591 7592 int res = REAL(name_to_handle_at)(dirfd, pathname, handle, mount_id, flags);7593 if (!res) {7594 COMMON_INTERCEPTOR_WRITE_RANGE(7595 ctx, &sanitizer_handle->handle_bytes,7596 sizeof(sanitizer_handle->handle_bytes));7597 COMMON_INTERCEPTOR_WRITE_RANGE(7598 ctx, &sanitizer_handle->handle_type,7599 sizeof(sanitizer_handle->handle_type));7600 COMMON_INTERCEPTOR_WRITE_RANGE(7601 ctx, &sanitizer_handle->f_handle, sanitizer_handle->handle_bytes);7602 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mount_id, sizeof(*mount_id));7603 }7604 return res;7605}7606 7607#define INIT_NAME_TO_HANDLE_AT COMMON_INTERCEPT_FUNCTION(name_to_handle_at)7608#else7609#define INIT_NAME_TO_HANDLE_AT7610#endif7611 7612#if SANITIZER_INTERCEPT_OPEN_BY_HANDLE_AT7613INTERCEPTOR(int, open_by_handle_at, int mount_fd, struct file_handle* handle,7614 int flags) {7615 void* ctx;7616 COMMON_INTERCEPTOR_ENTER(ctx, open_by_handle_at, mount_fd, handle, flags);7617 7618 __sanitizer_file_handle *sanitizer_handle =7619 reinterpret_cast<__sanitizer_file_handle*>(handle);7620 COMMON_INTERCEPTOR_READ_RANGE(7621 ctx, &sanitizer_handle->handle_bytes,7622 sizeof(sanitizer_handle->handle_bytes));7623 COMMON_INTERCEPTOR_READ_RANGE(7624 ctx, &sanitizer_handle->handle_type,7625 sizeof(sanitizer_handle->handle_type));7626 COMMON_INTERCEPTOR_READ_RANGE(7627 ctx, &sanitizer_handle->f_handle, sanitizer_handle->handle_bytes);7628 7629 return COMMON_INTERCEPTOR_BLOCK_REAL(open_by_handle_at)(mount_fd, handle,7630 flags);7631}7632 7633#define INIT_OPEN_BY_HANDLE_AT COMMON_INTERCEPT_FUNCTION(open_by_handle_at)7634#else7635#define INIT_OPEN_BY_HANDLE_AT7636#endif7637 7638#if SANITIZER_INTERCEPT_STRLCPY7639INTERCEPTOR(SIZE_T, strlcpy, char *dst, char *src, SIZE_T size) {7640 void *ctx;7641 SIZE_T res;7642 COMMON_INTERCEPTOR_ENTER(ctx, strlcpy, dst, src, size);7643 if (src) {7644 // Keep strnlen as macro argument, as macro may ignore it.7645 COMMON_INTERCEPTOR_READ_STRING(7646 ctx, src, Min(internal_strnlen(src, size), size - 1) + 1);7647 }7648 res = REAL(strlcpy)(dst, src, size);7649 COMMON_INTERCEPTOR_COPY_STRING(ctx, dst, src, internal_strlen(dst) + 1);7650 return res;7651}7652 7653INTERCEPTOR(SIZE_T, strlcat, char *dst, char *src, SIZE_T size) {7654 void *ctx;7655 SIZE_T len = 0;7656 COMMON_INTERCEPTOR_ENTER(ctx, strlcat, dst, src, size);7657 // src is checked in the strlcpy() interceptor7658 if (dst) {7659 len = internal_strnlen(dst, size);7660 COMMON_INTERCEPTOR_READ_STRING(ctx, dst, Min(len, size - 1) + 1);7661 }7662 // Reuse the rest of the code in the strlcpy() interceptor7663 return WRAP(strlcpy)(dst + len, src, size - len) + len;7664}7665#define INIT_STRLCPY \7666 COMMON_INTERCEPT_FUNCTION(strlcpy); \7667 COMMON_INTERCEPT_FUNCTION(strlcat);7668#else7669#define INIT_STRLCPY7670#endif7671 7672#if SANITIZER_INTERCEPT_MMAP7673INTERCEPTOR(void *, mmap, void *addr, SIZE_T sz, int prot, int flags, int fd,7674 OFF_T off) {7675 void *ctx;7676 if (common_flags()->detect_write_exec)7677 ReportMmapWriteExec(prot, flags);7678 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)7679 return (void *)internal_mmap(addr, sz, prot, flags, fd, off);7680 COMMON_INTERCEPTOR_ENTER(ctx, mmap, addr, sz, prot, flags, fd, off);7681 COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, sz, prot, flags, fd, off);7682}7683 7684INTERCEPTOR(int, munmap, void *addr, SIZE_T sz) {7685 void *ctx;7686 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)7687 return (int)internal_munmap(addr, sz);7688 COMMON_INTERCEPTOR_ENTER(ctx, munmap, addr, sz);7689 COMMON_INTERCEPTOR_MUNMAP_IMPL(ctx, addr, sz);7690}7691 7692INTERCEPTOR(int, mprotect, void *addr, SIZE_T sz, int prot) {7693 void *ctx;7694 if (common_flags()->detect_write_exec)7695 ReportMmapWriteExec(prot, 0);7696 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)7697 return (int)internal_mprotect(addr, sz, prot);7698 COMMON_INTERCEPTOR_ENTER(ctx, mprotect, addr, sz, prot);7699 MprotectMallocZones(addr, prot);7700 return REAL(mprotect)(addr, sz, prot);7701}7702#define INIT_MMAP \7703 COMMON_INTERCEPT_FUNCTION(mmap); \7704 COMMON_INTERCEPT_FUNCTION(munmap); \7705 COMMON_INTERCEPT_FUNCTION(mprotect);7706#else7707#define INIT_MMAP7708#endif7709 7710#if SANITIZER_INTERCEPT_MMAP647711INTERCEPTOR(void *, mmap64, void *addr, SIZE_T sz, int prot, int flags, int fd,7712 OFF64_T off) {7713 void *ctx;7714 if (common_flags()->detect_write_exec)7715 ReportMmapWriteExec(prot, flags);7716 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)7717 return (void *)internal_mmap(addr, sz, prot, flags, fd, off);7718 COMMON_INTERCEPTOR_ENTER(ctx, mmap64, addr, sz, prot, flags, fd, off);7719 COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap64, addr, sz, prot, flags, fd, off);7720}7721#define INIT_MMAP64 COMMON_INTERCEPT_FUNCTION(mmap64);7722#else7723#define INIT_MMAP647724#endif7725 7726#if SANITIZER_INTERCEPT_DEVNAME7727INTERCEPTOR(char *, devname, u64 dev, u32 type) {7728 void *ctx;7729 char *name;7730 COMMON_INTERCEPTOR_ENTER(ctx, devname, dev, type);7731 name = REAL(devname)(dev, type);7732 if (name)7733 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, internal_strlen(name) + 1);7734 return name;7735}7736#define INIT_DEVNAME COMMON_INTERCEPT_FUNCTION(devname);7737#else7738#define INIT_DEVNAME7739#endif7740 7741#if SANITIZER_INTERCEPT_DEVNAME_R7742#if SANITIZER_NETBSD7743#define DEVNAME_R_RETTYPE int7744#define DEVNAME_R_SUCCESS(x) (!(x))7745#else7746#define DEVNAME_R_RETTYPE char*7747#define DEVNAME_R_SUCCESS(x) (x)7748#endif7749INTERCEPTOR(DEVNAME_R_RETTYPE, devname_r, u64 dev, u32 type, char *path,7750 uptr len) {7751 void *ctx;7752 COMMON_INTERCEPTOR_ENTER(ctx, devname_r, dev, type, path, len);7753 DEVNAME_R_RETTYPE res = REAL(devname_r)(dev, type, path, len);7754 if (DEVNAME_R_SUCCESS(res))7755 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, path, internal_strlen(path) + 1);7756 return res;7757}7758#define INIT_DEVNAME_R COMMON_INTERCEPT_FUNCTION(devname_r);7759#else7760#define INIT_DEVNAME_R7761#endif7762 7763#if SANITIZER_INTERCEPT_FGETLN7764INTERCEPTOR(char *, fgetln, __sanitizer_FILE *stream, SIZE_T *len) {7765 void *ctx;7766 COMMON_INTERCEPTOR_ENTER(ctx, fgetln, stream, len);7767 char *str = REAL(fgetln)(stream, len);7768 if (str && len) {7769 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len));7770 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, *len);7771 }7772 return str;7773}7774#define INIT_FGETLN COMMON_INTERCEPT_FUNCTION(fgetln)7775#else7776#define INIT_FGETLN7777#endif7778 7779#if SANITIZER_INTERCEPT_STRMODE7780INTERCEPTOR(void, strmode, u32 mode, char *bp) {7781 void *ctx;7782 COMMON_INTERCEPTOR_ENTER(ctx, strmode, mode, bp);7783 REAL(strmode)(mode, bp);7784 if (bp)7785 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, bp, internal_strlen(bp) + 1);7786}7787#define INIT_STRMODE COMMON_INTERCEPT_FUNCTION(strmode)7788#else7789#define INIT_STRMODE7790#endif7791 7792#if SANITIZER_INTERCEPT_TTYENT7793INTERCEPTOR(struct __sanitizer_ttyent *, getttyent, void) {7794 void *ctx;7795 COMMON_INTERCEPTOR_ENTER(ctx, getttyent);7796 struct __sanitizer_ttyent *ttyent = REAL(getttyent)();7797 if (ttyent)7798 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ttyent, struct_ttyent_sz);7799 return ttyent;7800}7801INTERCEPTOR(struct __sanitizer_ttyent *, getttynam, char *name) {7802 void *ctx;7803 COMMON_INTERCEPTOR_ENTER(ctx, getttynam, name);7804 if (name)7805 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);7806 struct __sanitizer_ttyent *ttyent = REAL(getttynam)(name);7807 if (ttyent)7808 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ttyent, struct_ttyent_sz);7809 return ttyent;7810}7811#define INIT_TTYENT \7812 COMMON_INTERCEPT_FUNCTION(getttyent); \7813 COMMON_INTERCEPT_FUNCTION(getttynam);7814#else7815#define INIT_TTYENT7816#endif7817 7818#if SANITIZER_INTERCEPT_TTYENTPATH7819INTERCEPTOR(int, setttyentpath, char *path) {7820 void *ctx;7821 COMMON_INTERCEPTOR_ENTER(ctx, setttyentpath, path);7822 if (path)7823 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);7824 return REAL(setttyentpath)(path);7825}7826#define INIT_TTYENTPATH COMMON_INTERCEPT_FUNCTION(setttyentpath);7827#else7828#define INIT_TTYENTPATH7829#endif7830 7831#if SANITIZER_INTERCEPT_PROTOENT7832static void write_protoent(void *ctx, struct __sanitizer_protoent *p) {7833 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));7834 7835 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_name, internal_strlen(p->p_name) + 1);7836 7837 SIZE_T pp_size = 1; // One handles the trailing \07838 7839 for (char **pp = p->p_aliases; *pp; ++pp, ++pp_size)7840 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *pp, internal_strlen(*pp) + 1);7841 7842 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_aliases, pp_size * sizeof(char *));7843}7844 7845INTERCEPTOR(struct __sanitizer_protoent *, getprotoent,) {7846 void *ctx;7847 COMMON_INTERCEPTOR_ENTER(ctx, getprotoent,);7848 struct __sanitizer_protoent *p = REAL(getprotoent)();7849 if (p)7850 write_protoent(ctx, p);7851 return p;7852}7853 7854INTERCEPTOR(struct __sanitizer_protoent *, getprotobyname, const char *name) {7855 void *ctx;7856 COMMON_INTERCEPTOR_ENTER(ctx, getprotobyname, name);7857 if (name)7858 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);7859 struct __sanitizer_protoent *p = REAL(getprotobyname)(name);7860 if (p)7861 write_protoent(ctx, p);7862 return p;7863}7864 7865INTERCEPTOR(struct __sanitizer_protoent *, getprotobynumber, int proto) {7866 void *ctx;7867 COMMON_INTERCEPTOR_ENTER(ctx, getprotobynumber, proto);7868 struct __sanitizer_protoent *p = REAL(getprotobynumber)(proto);7869 if (p)7870 write_protoent(ctx, p);7871 return p;7872}7873#define INIT_PROTOENT \7874 COMMON_INTERCEPT_FUNCTION(getprotoent); \7875 COMMON_INTERCEPT_FUNCTION(getprotobyname); \7876 COMMON_INTERCEPT_FUNCTION(getprotobynumber)7877#else7878#define INIT_PROTOENT7879#endif7880 7881#if SANITIZER_INTERCEPT_PROTOENT_R7882INTERCEPTOR(int, getprotoent_r, struct __sanitizer_protoent *result_buf,7883 char *buf, SIZE_T buflen, struct __sanitizer_protoent **result) {7884 void *ctx;7885 COMMON_INTERCEPTOR_ENTER(ctx, getprotoent_r, result_buf, buf, buflen,7886 result);7887 int res = REAL(getprotoent_r)(result_buf, buf, buflen, result);7888 7889 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof *result);7890 if (!res && *result)7891 write_protoent(ctx, *result);7892 return res;7893}7894 7895INTERCEPTOR(int, getprotobyname_r, const char *name,7896 struct __sanitizer_protoent *result_buf, char *buf, SIZE_T buflen,7897 struct __sanitizer_protoent **result) {7898 void *ctx;7899 COMMON_INTERCEPTOR_ENTER(ctx, getprotobyname_r, name, result_buf, buf,7900 buflen, result);7901 if (name)7902 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);7903 int res = REAL(getprotobyname_r)(name, result_buf, buf, buflen, result);7904 7905 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof *result);7906 if (!res && *result)7907 write_protoent(ctx, *result);7908 return res;7909}7910 7911INTERCEPTOR(int, getprotobynumber_r, int num,7912 struct __sanitizer_protoent *result_buf, char *buf,7913 SIZE_T buflen, struct __sanitizer_protoent **result) {7914 void *ctx;7915 COMMON_INTERCEPTOR_ENTER(ctx, getprotobynumber_r, num, result_buf, buf,7916 buflen, result);7917 int res = REAL(getprotobynumber_r)(num, result_buf, buf, buflen, result);7918 7919 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof *result);7920 if (!res && *result)7921 write_protoent(ctx, *result);7922 return res;7923}7924 7925#define INIT_PROTOENT_R \7926 COMMON_INTERCEPT_FUNCTION(getprotoent_r); \7927 COMMON_INTERCEPT_FUNCTION(getprotobyname_r); \7928 COMMON_INTERCEPT_FUNCTION(getprotobynumber_r);7929#else7930#define INIT_PROTOENT_R7931#endif7932 7933#if SANITIZER_INTERCEPT_NETENT7934INTERCEPTOR(struct __sanitizer_netent *, getnetent,) {7935 void *ctx;7936 COMMON_INTERCEPTOR_ENTER(ctx, getnetent,);7937 struct __sanitizer_netent *n = REAL(getnetent)();7938 if (n) {7939 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));7940 7941 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_name, internal_strlen(n->n_name) + 1);7942 7943 SIZE_T nn_size = 1; // One handles the trailing \07944 7945 for (char **nn = n->n_aliases; *nn; ++nn, ++nn_size)7946 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, internal_strlen(*nn) + 1);7947 7948 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases, nn_size * sizeof(char *));7949 }7950 return n;7951}7952 7953INTERCEPTOR(struct __sanitizer_netent *, getnetbyname, const char *name) {7954 void *ctx;7955 COMMON_INTERCEPTOR_ENTER(ctx, getnetbyname, name);7956 if (name)7957 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);7958 struct __sanitizer_netent *n = REAL(getnetbyname)(name);7959 if (n) {7960 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));7961 7962 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_name, internal_strlen(n->n_name) + 1);7963 7964 SIZE_T nn_size = 1; // One handles the trailing \07965 7966 for (char **nn = n->n_aliases; *nn; ++nn, ++nn_size)7967 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, internal_strlen(*nn) + 1);7968 7969 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases, nn_size * sizeof(char *));7970 }7971 return n;7972}7973 7974INTERCEPTOR(struct __sanitizer_netent *, getnetbyaddr, u32 net, int type) {7975 void *ctx;7976 COMMON_INTERCEPTOR_ENTER(ctx, getnetbyaddr, net, type);7977 struct __sanitizer_netent *n = REAL(getnetbyaddr)(net, type);7978 if (n) {7979 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));7980 7981 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_name, internal_strlen(n->n_name) + 1);7982 7983 SIZE_T nn_size = 1; // One handles the trailing \07984 7985 for (char **nn = n->n_aliases; *nn; ++nn, ++nn_size)7986 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, internal_strlen(*nn) + 1);7987 7988 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases, nn_size * sizeof(char *));7989 }7990 return n;7991}7992#define INIT_NETENT \7993 COMMON_INTERCEPT_FUNCTION(getnetent); \7994 COMMON_INTERCEPT_FUNCTION(getnetbyname); \7995 COMMON_INTERCEPT_FUNCTION(getnetbyaddr)7996#else7997#define INIT_NETENT7998#endif7999 8000#if SANITIZER_INTERCEPT_GETMNTINFO8001INTERCEPTOR(int, getmntinfo, void **mntbufp, int flags) {8002 void *ctx;8003 COMMON_INTERCEPTOR_ENTER(ctx, getmntinfo, mntbufp, flags);8004 int cnt = REAL(getmntinfo)(mntbufp, flags);8005 if (cnt > 0 && mntbufp) {8006 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mntbufp, sizeof(void *));8007 if (*mntbufp)8008#if SANITIZER_NETBSD8009 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *mntbufp, cnt * struct_statvfs_sz);8010#else8011 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *mntbufp, cnt * struct_statfs_sz);8012#endif8013 }8014 return cnt;8015}8016#define INIT_GETMNTINFO COMMON_INTERCEPT_FUNCTION(getmntinfo)8017#else8018#define INIT_GETMNTINFO8019#endif8020 8021#if SANITIZER_INTERCEPT_MI_VECTOR_HASH8022INTERCEPTOR(void, mi_vector_hash, const void *key, SIZE_T len, u32 seed,8023 u32 hashes[3]) {8024 void *ctx;8025 COMMON_INTERCEPTOR_ENTER(ctx, mi_vector_hash, key, len, seed, hashes);8026 if (key)8027 COMMON_INTERCEPTOR_READ_RANGE(ctx, key, len);8028 REAL(mi_vector_hash)(key, len, seed, hashes);8029 if (hashes)8030 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hashes, sizeof(hashes[0]) * 3);8031}8032#define INIT_MI_VECTOR_HASH COMMON_INTERCEPT_FUNCTION(mi_vector_hash)8033#else8034#define INIT_MI_VECTOR_HASH8035#endif8036 8037#if SANITIZER_INTERCEPT_SETVBUF8038INTERCEPTOR(int, setvbuf, __sanitizer_FILE *stream, char *buf, int mode,8039 SIZE_T size) {8040 void *ctx;8041 COMMON_INTERCEPTOR_ENTER(ctx, setvbuf, stream, buf, mode, size);8042 int ret = REAL(setvbuf)(stream, buf, mode, size);8043 if (buf)8044 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, size);8045 if (stream)8046 unpoison_file(stream);8047 return ret;8048}8049 8050INTERCEPTOR(void, setbuf, __sanitizer_FILE *stream, char *buf) {8051 void *ctx;8052 COMMON_INTERCEPTOR_ENTER(ctx, setbuf, stream, buf);8053 REAL(setbuf)(stream, buf);8054 if (buf) {8055 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer_bufsiz);8056 }8057 if (stream)8058 unpoison_file(stream);8059}8060 8061INTERCEPTOR(void, setbuffer, __sanitizer_FILE *stream, char *buf, SIZE_T size) {8062 void *ctx;8063 COMMON_INTERCEPTOR_ENTER(ctx, setbuffer, stream, buf, size);8064 REAL(setbuffer)(stream, buf, size);8065 if (buf) {8066 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, size);8067 }8068 if (stream)8069 unpoison_file(stream);8070}8071 8072INTERCEPTOR(void, setlinebuf, __sanitizer_FILE *stream) {8073 void *ctx;8074 COMMON_INTERCEPTOR_ENTER(ctx, setlinebuf, stream);8075 REAL(setlinebuf)(stream);8076 if (stream)8077 unpoison_file(stream);8078}8079#define INIT_SETVBUF COMMON_INTERCEPT_FUNCTION(setvbuf); \8080 COMMON_INTERCEPT_FUNCTION(setbuf); \8081 COMMON_INTERCEPT_FUNCTION(setbuffer); \8082 COMMON_INTERCEPT_FUNCTION(setlinebuf)8083#else8084#define INIT_SETVBUF8085#endif8086 8087#if SANITIZER_INTERCEPT_GETVFSSTAT8088INTERCEPTOR(int, getvfsstat, void *buf, SIZE_T bufsize, int flags) {8089 void *ctx;8090 COMMON_INTERCEPTOR_ENTER(ctx, getvfsstat, buf, bufsize, flags);8091 int ret = REAL(getvfsstat)(buf, bufsize, flags);8092 if (buf && ret > 0)8093 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, ret * struct_statvfs_sz);8094 return ret;8095}8096#define INIT_GETVFSSTAT COMMON_INTERCEPT_FUNCTION(getvfsstat)8097#else8098#define INIT_GETVFSSTAT8099#endif8100 8101#if SANITIZER_INTERCEPT_REGEX8102INTERCEPTOR(int, regcomp, void *preg, const char *pattern, int cflags) {8103 void *ctx;8104 COMMON_INTERCEPTOR_ENTER(ctx, regcomp, preg, pattern, cflags);8105 if (pattern)8106 COMMON_INTERCEPTOR_READ_RANGE(ctx, pattern, internal_strlen(pattern) + 1);8107 int res = REAL(regcomp)(preg, pattern, cflags);8108 if (preg)8109 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, preg, struct_regex_sz);8110 return res;8111}8112INTERCEPTOR(int, regexec, const void *preg, const char *string, SIZE_T nmatch,8113 struct __sanitizer_regmatch *pmatch[], int eflags) {8114 void *ctx;8115 COMMON_INTERCEPTOR_ENTER(ctx, regexec, preg, string, nmatch, pmatch, eflags);8116 if (preg)8117 COMMON_INTERCEPTOR_READ_RANGE(ctx, preg, struct_regex_sz);8118 if (string)8119 COMMON_INTERCEPTOR_READ_RANGE(ctx, string, internal_strlen(string) + 1);8120 int res = REAL(regexec)(preg, string, nmatch, pmatch, eflags);8121 if (!res && pmatch)8122 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pmatch, nmatch * struct_regmatch_sz);8123 return res;8124}8125INTERCEPTOR(SIZE_T, regerror, int errcode, const void *preg, char *errbuf,8126 SIZE_T errbuf_size) {8127 void *ctx;8128 COMMON_INTERCEPTOR_ENTER(ctx, regerror, errcode, preg, errbuf, errbuf_size);8129 if (preg)8130 COMMON_INTERCEPTOR_READ_RANGE(ctx, preg, struct_regex_sz);8131 SIZE_T res = REAL(regerror)(errcode, preg, errbuf, errbuf_size);8132 if (errbuf)8133 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, errbuf, internal_strlen(errbuf) + 1);8134 return res;8135}8136INTERCEPTOR(void, regfree, const void *preg) {8137 void *ctx;8138 COMMON_INTERCEPTOR_ENTER(ctx, regfree, preg);8139 if (preg)8140 COMMON_INTERCEPTOR_READ_RANGE(ctx, preg, struct_regex_sz);8141 REAL(regfree)(preg);8142}8143#define INIT_REGEX \8144 COMMON_INTERCEPT_FUNCTION(regcomp); \8145 COMMON_INTERCEPT_FUNCTION_GLIBC_VER_MIN(regexec, "GLIBC_2.3.4"); \8146 COMMON_INTERCEPT_FUNCTION(regerror); \8147 COMMON_INTERCEPT_FUNCTION(regfree);8148#else8149#define INIT_REGEX8150#endif8151 8152#if SANITIZER_INTERCEPT_REGEXSUB8153INTERCEPTOR(SSIZE_T, regnsub, char *buf, SIZE_T bufsiz, const char *sub,8154 const struct __sanitizer_regmatch *rm, const char *str) {8155 void *ctx;8156 COMMON_INTERCEPTOR_ENTER(ctx, regnsub, buf, bufsiz, sub, rm, str);8157 if (sub)8158 COMMON_INTERCEPTOR_READ_RANGE(ctx, sub, internal_strlen(sub) + 1);8159 // The implementation demands and hardcodes 10 elements8160 if (rm)8161 COMMON_INTERCEPTOR_READ_RANGE(ctx, rm, 10 * struct_regmatch_sz);8162 if (str)8163 COMMON_INTERCEPTOR_READ_RANGE(ctx, str, internal_strlen(str) + 1);8164 SSIZE_T res = REAL(regnsub)(buf, bufsiz, sub, rm, str);8165 if (res > 0 && buf)8166 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, internal_strlen(buf) + 1);8167 return res;8168}8169INTERCEPTOR(SSIZE_T, regasub, char **buf, const char *sub,8170 const struct __sanitizer_regmatch *rm, const char *sstr) {8171 void *ctx;8172 COMMON_INTERCEPTOR_ENTER(ctx, regasub, buf, sub, rm, sstr);8173 if (sub)8174 COMMON_INTERCEPTOR_READ_RANGE(ctx, sub, internal_strlen(sub) + 1);8175 // Hardcode 10 elements as this is hardcoded size8176 if (rm)8177 COMMON_INTERCEPTOR_READ_RANGE(ctx, rm, 10 * struct_regmatch_sz);8178 if (sstr)8179 COMMON_INTERCEPTOR_READ_RANGE(ctx, sstr, internal_strlen(sstr) + 1);8180 SSIZE_T res = REAL(regasub)(buf, sub, rm, sstr);8181 if (res > 0 && buf) {8182 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sizeof(char *));8183 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *buf, internal_strlen(*buf) + 1);8184 }8185 return res;8186}8187 8188#define INIT_REGEXSUB \8189 COMMON_INTERCEPT_FUNCTION(regnsub); \8190 COMMON_INTERCEPT_FUNCTION(regasub);8191#else8192#define INIT_REGEXSUB8193#endif8194 8195#if SANITIZER_INTERCEPT_FTS8196INTERCEPTOR(void *, fts_open, char *const *path_argv, int options,8197 int (*compar)(void **, void **)) {8198 void *ctx;8199 COMMON_INTERCEPTOR_ENTER(ctx, fts_open, path_argv, options, compar);8200 if (path_argv) {8201 for (char *const *pa = path_argv; ; ++pa) {8202 COMMON_INTERCEPTOR_READ_RANGE(ctx, pa, sizeof(char **));8203 if (!*pa)8204 break;8205 COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, internal_strlen(*pa) + 1);8206 }8207 }8208 // TODO(kamil): handle compar callback8209 void *fts = REAL(fts_open)(path_argv, options, compar);8210 if (fts)8211 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, fts, struct_FTS_sz);8212 return fts;8213}8214 8215INTERCEPTOR(void *, fts_read, void *ftsp) {8216 void *ctx;8217 COMMON_INTERCEPTOR_ENTER(ctx, fts_read, ftsp);8218 if (ftsp)8219 COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz);8220 void *ftsent = REAL(fts_read)(ftsp);8221 if (ftsent)8222 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ftsent, struct_FTSENT_sz);8223 return ftsent;8224}8225 8226INTERCEPTOR(void *, fts_children, void *ftsp, int options) {8227 void *ctx;8228 COMMON_INTERCEPTOR_ENTER(ctx, fts_children, ftsp, options);8229 if (ftsp)8230 COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz);8231 void *ftsent = REAL(fts_children)(ftsp, options);8232 if (ftsent)8233 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ftsent, struct_FTSENT_sz);8234 return ftsent;8235}8236 8237INTERCEPTOR(int, fts_set, void *ftsp, void *f, int options) {8238 void *ctx;8239 COMMON_INTERCEPTOR_ENTER(ctx, fts_set, ftsp, f, options);8240 if (ftsp)8241 COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz);8242 if (f)8243 COMMON_INTERCEPTOR_READ_RANGE(ctx, f, struct_FTSENT_sz);8244 return REAL(fts_set)(ftsp, f, options);8245}8246 8247INTERCEPTOR(int, fts_close, void *ftsp) {8248 void *ctx;8249 COMMON_INTERCEPTOR_ENTER(ctx, fts_close, ftsp);8250 if (ftsp)8251 COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz);8252 return REAL(fts_close)(ftsp);8253}8254#define INIT_FTS \8255 COMMON_INTERCEPT_FUNCTION(fts_open); \8256 COMMON_INTERCEPT_FUNCTION(fts_read); \8257 COMMON_INTERCEPT_FUNCTION(fts_children); \8258 COMMON_INTERCEPT_FUNCTION(fts_set); \8259 COMMON_INTERCEPT_FUNCTION(fts_close);8260#else8261#define INIT_FTS8262#endif8263 8264#if SANITIZER_INTERCEPT_SYSCTL8265INTERCEPTOR(int, sysctl, int *name, unsigned int namelen, void *oldp,8266 SIZE_T *oldlenp, void *newp, SIZE_T newlen) {8267 void *ctx;8268 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)8269 return internal_sysctl(name, namelen, oldp, oldlenp, newp, newlen);8270 COMMON_INTERCEPTOR_ENTER(ctx, sysctl, name, namelen, oldp, oldlenp, newp,8271 newlen);8272 if (name)8273 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, namelen * sizeof(*name));8274 if (oldlenp)8275 COMMON_INTERCEPTOR_READ_RANGE(ctx, oldlenp, sizeof(*oldlenp));8276 if (newp && newlen)8277 COMMON_INTERCEPTOR_READ_RANGE(ctx, newp, newlen);8278 int res = REAL(sysctl)(name, namelen, oldp, oldlenp, newp, newlen);8279 if (!res) {8280 if (oldlenp) {8281 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldlenp, sizeof(*oldlenp));8282 if (oldp)8283 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldp, *oldlenp);8284 }8285 }8286 return res;8287}8288 8289INTERCEPTOR(int, sysctlbyname, char *sname, void *oldp, SIZE_T *oldlenp,8290 void *newp, SIZE_T newlen) {8291 void *ctx;8292 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)8293 return internal_sysctlbyname(sname, oldp, oldlenp, newp, newlen);8294 COMMON_INTERCEPTOR_ENTER(ctx, sysctlbyname, sname, oldp, oldlenp, newp,8295 newlen);8296 if (sname)8297 COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, internal_strlen(sname) + 1);8298 if (oldlenp)8299 COMMON_INTERCEPTOR_READ_RANGE(ctx, oldlenp, sizeof(*oldlenp));8300 if (newp && newlen)8301 COMMON_INTERCEPTOR_READ_RANGE(ctx, newp, newlen);8302 int res = REAL(sysctlbyname)(sname, oldp, oldlenp, newp, newlen);8303 if (!res) {8304 if (oldlenp) {8305 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldlenp, sizeof(*oldlenp));8306 if (oldp)8307 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldp, *oldlenp);8308 }8309 }8310 return res;8311}8312 8313INTERCEPTOR(int, sysctlnametomib, const char *sname, int *name,8314 SIZE_T *namelenp) {8315 void *ctx;8316 COMMON_INTERCEPTOR_ENTER(ctx, sysctlnametomib, sname, name, namelenp);8317 if (sname)8318 COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, internal_strlen(sname) + 1);8319 if (namelenp)8320 COMMON_INTERCEPTOR_READ_RANGE(ctx, namelenp, sizeof(*namelenp));8321 int res = REAL(sysctlnametomib)(sname, name, namelenp);8322 if (!res) {8323 if (namelenp) {8324 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelenp, sizeof(*namelenp));8325 if (name)8326 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, *namelenp * sizeof(*name));8327 }8328 }8329 return res;8330}8331 8332#define INIT_SYSCTL \8333 COMMON_INTERCEPT_FUNCTION(sysctl); \8334 COMMON_INTERCEPT_FUNCTION(sysctlbyname); \8335 COMMON_INTERCEPT_FUNCTION(sysctlnametomib);8336#else8337#define INIT_SYSCTL8338#endif8339 8340#if SANITIZER_INTERCEPT_ASYSCTL8341INTERCEPTOR(void *, asysctl, const int *name, SIZE_T namelen, SIZE_T *len) {8342 void *ctx;8343 COMMON_INTERCEPTOR_ENTER(ctx, asysctl, name, namelen, len);8344 if (name)8345 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, sizeof(*name) * namelen);8346 void *res = REAL(asysctl)(name, namelen, len);8347 if (res && len) {8348 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len));8349 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, *len);8350 }8351 return res;8352}8353 8354INTERCEPTOR(void *, asysctlbyname, const char *sname, SIZE_T *len) {8355 void *ctx;8356 COMMON_INTERCEPTOR_ENTER(ctx, asysctlbyname, sname, len);8357 if (sname)8358 COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, internal_strlen(sname) + 1);8359 void *res = REAL(asysctlbyname)(sname, len);8360 if (res && len) {8361 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len));8362 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, *len);8363 }8364 return res;8365}8366#define INIT_ASYSCTL \8367 COMMON_INTERCEPT_FUNCTION(asysctl); \8368 COMMON_INTERCEPT_FUNCTION(asysctlbyname);8369#else8370#define INIT_ASYSCTL8371#endif8372 8373#if SANITIZER_INTERCEPT_SYSCTLGETMIBINFO8374INTERCEPTOR(int, sysctlgetmibinfo, char *sname, int *name,8375 unsigned int *namelenp, char *cname, SIZE_T *csz, void **rnode,8376 int v) {8377 void *ctx;8378 COMMON_INTERCEPTOR_ENTER(ctx, sysctlgetmibinfo, sname, name, namelenp, cname,8379 csz, rnode, v);8380 if (sname)8381 COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, internal_strlen(sname) + 1);8382 if (namelenp)8383 COMMON_INTERCEPTOR_READ_RANGE(ctx, namelenp, sizeof(*namelenp));8384 if (csz)8385 COMMON_INTERCEPTOR_READ_RANGE(ctx, csz, sizeof(*csz));8386 // Skip rnode, it's rarely used and not trivial to sanitize8387 // It's also used mostly internally8388 int res = REAL(sysctlgetmibinfo)(sname, name, namelenp, cname, csz, rnode, v);8389 if (!res) {8390 if (namelenp) {8391 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelenp, sizeof(*namelenp));8392 if (name)8393 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, *namelenp * sizeof(*name));8394 }8395 if (csz) {8396 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, csz, sizeof(*csz));8397 if (cname)8398 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cname, *csz);8399 }8400 }8401 return res;8402}8403#define INIT_SYSCTLGETMIBINFO \8404 COMMON_INTERCEPT_FUNCTION(sysctlgetmibinfo);8405#else8406#define INIT_SYSCTLGETMIBINFO8407#endif8408 8409#if SANITIZER_INTERCEPT_NL_LANGINFO8410INTERCEPTOR(char *, nl_langinfo, long item) {8411 void *ctx;8412 COMMON_INTERCEPTOR_ENTER(ctx, nl_langinfo, item);8413 char *ret = REAL(nl_langinfo)(item);8414 if (ret)8415 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, internal_strlen(ret) + 1);8416 return ret;8417}8418#define INIT_NL_LANGINFO COMMON_INTERCEPT_FUNCTION(nl_langinfo)8419#else8420#define INIT_NL_LANGINFO8421#endif8422 8423#if SANITIZER_INTERCEPT_MODCTL8424INTERCEPTOR(int, modctl, int operation, void *argp) {8425 void *ctx;8426 int ret;8427 COMMON_INTERCEPTOR_ENTER(ctx, modctl, operation, argp);8428 8429 if (operation == modctl_load) {8430 if (argp) {8431 __sanitizer_modctl_load_t *ml = (__sanitizer_modctl_load_t *)argp;8432 COMMON_INTERCEPTOR_READ_RANGE(ctx, ml, sizeof(*ml));8433 if (ml->ml_filename)8434 COMMON_INTERCEPTOR_READ_RANGE(ctx, ml->ml_filename,8435 internal_strlen(ml->ml_filename) + 1);8436 if (ml->ml_props)8437 COMMON_INTERCEPTOR_READ_RANGE(ctx, ml->ml_props, ml->ml_propslen);8438 }8439 ret = REAL(modctl)(operation, argp);8440 } else if (operation == modctl_unload) {8441 if (argp) {8442 const char *name = (const char *)argp;8443 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);8444 }8445 ret = REAL(modctl)(operation, argp);8446 } else if (operation == modctl_stat) {8447 uptr iov_len;8448 struct __sanitizer_iovec *iov = (struct __sanitizer_iovec *)argp;8449 if (iov) {8450 COMMON_INTERCEPTOR_READ_RANGE(ctx, iov, sizeof(*iov));8451 iov_len = iov->iov_len;8452 }8453 ret = REAL(modctl)(operation, argp);8454 if (iov)8455 COMMON_INTERCEPTOR_WRITE_RANGE(8456 ctx, iov->iov_base, Min(iov_len, iov->iov_len));8457 } else if (operation == modctl_exists) {8458 ret = REAL(modctl)(operation, argp);8459 } else {8460 ret = REAL(modctl)(operation, argp);8461 }8462 8463 return ret;8464}8465#define INIT_MODCTL COMMON_INTERCEPT_FUNCTION(modctl)8466#else8467#define INIT_MODCTL8468#endif8469 8470#if SANITIZER_INTERCEPT_STRTONUM8471INTERCEPTOR(long long, strtonum, const char *nptr, long long minval,8472 long long maxval, const char **errstr) {8473 void *ctx;8474 COMMON_INTERCEPTOR_ENTER(ctx, strtonum, nptr, minval, maxval, errstr);8475 8476 // TODO(kamil): Implement strtoll as a common inteceptor8477 char *real_endptr;8478 long long ret = (long long)REAL(strtoimax)(nptr, &real_endptr, 10);8479 StrtolFixAndCheck(ctx, nptr, nullptr, real_endptr, 10);8480 8481 ret = REAL(strtonum)(nptr, minval, maxval, errstr);8482 if (errstr) {8483 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, errstr, sizeof(const char *));8484 if (*errstr)8485 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *errstr, internal_strlen(*errstr) + 1);8486 }8487 return ret;8488}8489#define INIT_STRTONUM COMMON_INTERCEPT_FUNCTION(strtonum)8490#else8491#define INIT_STRTONUM8492#endif8493 8494#if SANITIZER_INTERCEPT_FPARSELN8495INTERCEPTOR(char *, fparseln, __sanitizer_FILE *stream, SIZE_T *len,8496 SIZE_T *lineno, const char delim[3], int flags) {8497 void *ctx;8498 COMMON_INTERCEPTOR_ENTER(ctx, fparseln, stream, len, lineno, delim, flags);8499 if (lineno)8500 COMMON_INTERCEPTOR_READ_RANGE(ctx, lineno, sizeof(*lineno));8501 if (delim)8502 COMMON_INTERCEPTOR_READ_RANGE(ctx, delim, sizeof(delim[0]) * 3);8503 char *ret = REAL(fparseln)(stream, len, lineno, delim, flags);8504 if (ret) {8505 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, internal_strlen(ret) + 1);8506 if (len)8507 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len));8508 if (lineno)8509 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineno, sizeof(*lineno));8510 }8511 return ret;8512}8513#define INIT_FPARSELN COMMON_INTERCEPT_FUNCTION(fparseln)8514#else8515#define INIT_FPARSELN8516#endif8517 8518#if SANITIZER_INTERCEPT_STATVFS18519INTERCEPTOR(int, statvfs1, const char *path, void *buf, int flags) {8520 void *ctx;8521 COMMON_INTERCEPTOR_ENTER(ctx, statvfs1, path, buf, flags);8522 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);8523 int res = REAL(statvfs1)(path, buf, flags);8524 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);8525 return res;8526}8527INTERCEPTOR(int, fstatvfs1, int fd, void *buf, int flags) {8528 void *ctx;8529 COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs1, fd, buf, flags);8530 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);8531 int res = REAL(fstatvfs1)(fd, buf, flags);8532 if (!res) {8533 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);8534 if (fd >= 0)8535 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);8536 }8537 return res;8538}8539#define INIT_STATVFS1 \8540 COMMON_INTERCEPT_FUNCTION(statvfs1); \8541 COMMON_INTERCEPT_FUNCTION(fstatvfs1);8542#else8543#define INIT_STATVFS18544#endif8545 8546#if SANITIZER_INTERCEPT_STRTOI8547INTERCEPTOR(INTMAX_T, strtoi, const char *nptr, char **endptr, int base,8548 INTMAX_T low, INTMAX_T high, int *rstatus) {8549 void *ctx;8550 COMMON_INTERCEPTOR_ENTER(ctx, strtoi, nptr, endptr, base, low, high, rstatus);8551 char *real_endptr;8552 INTMAX_T ret = REAL(strtoi)(nptr, &real_endptr, base, low, high, rstatus);8553 StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);8554 if (rstatus)8555 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rstatus, sizeof(*rstatus));8556 return ret;8557}8558 8559INTERCEPTOR(UINTMAX_T, strtou, const char *nptr, char **endptr, int base,8560 UINTMAX_T low, UINTMAX_T high, int *rstatus) {8561 void *ctx;8562 COMMON_INTERCEPTOR_ENTER(ctx, strtou, nptr, endptr, base, low, high, rstatus);8563 char *real_endptr;8564 UINTMAX_T ret = REAL(strtou)(nptr, &real_endptr, base, low, high, rstatus);8565 StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);8566 if (rstatus)8567 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rstatus, sizeof(*rstatus));8568 return ret;8569}8570#define INIT_STRTOI \8571 COMMON_INTERCEPT_FUNCTION(strtoi); \8572 COMMON_INTERCEPT_FUNCTION(strtou)8573#else8574#define INIT_STRTOI8575#endif8576 8577#if SANITIZER_INTERCEPT_CAPSICUM8578#define CAP_RIGHTS_INIT_INTERCEPTOR(cap_rights_init, rights, ...) \8579 { \8580 void *ctx; \8581 COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_init, rights, ##__VA_ARGS__); \8582 if (rights) \8583 COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights)); \8584 __sanitizer_cap_rights_t *ret = \8585 REAL(cap_rights_init)(rights, ##__VA_ARGS__); \8586 if (ret) \8587 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret)); \8588 return ret; \8589 }8590 8591#define CAP_RIGHTS_SET_INTERCEPTOR(cap_rights_set, rights, ...) \8592 { \8593 void *ctx; \8594 COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_set, rights, ##__VA_ARGS__); \8595 if (rights) \8596 COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights)); \8597 __sanitizer_cap_rights_t *ret = \8598 REAL(cap_rights_set)(rights, ##__VA_ARGS__); \8599 if (ret) \8600 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret)); \8601 return ret; \8602 }8603 8604#define CAP_RIGHTS_CLEAR_INTERCEPTOR(cap_rights_clear, rights, ...) \8605 { \8606 void *ctx; \8607 COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_clear, rights, ##__VA_ARGS__); \8608 if (rights) \8609 COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights)); \8610 __sanitizer_cap_rights_t *ret = \8611 REAL(cap_rights_clear)(rights, ##__VA_ARGS__); \8612 if (ret) \8613 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret)); \8614 return ret; \8615 }8616 8617#define CAP_RIGHTS_IS_SET_INTERCEPTOR(cap_rights_is_set, rights, ...) \8618 { \8619 void *ctx; \8620 COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_is_set, rights, ##__VA_ARGS__); \8621 if (rights) \8622 COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights)); \8623 return REAL(cap_rights_is_set)(rights, ##__VA_ARGS__); \8624 }8625 8626INTERCEPTOR(__sanitizer_cap_rights_t *, cap_rights_init,8627 __sanitizer_cap_rights_t *rights) {8628 CAP_RIGHTS_INIT_INTERCEPTOR(cap_rights_init, rights);8629}8630 8631INTERCEPTOR(__sanitizer_cap_rights_t *, cap_rights_set,8632 __sanitizer_cap_rights_t *rights) {8633 CAP_RIGHTS_SET_INTERCEPTOR(cap_rights_set, rights);8634}8635 8636INTERCEPTOR(__sanitizer_cap_rights_t *, cap_rights_clear,8637 __sanitizer_cap_rights_t *rights) {8638 CAP_RIGHTS_CLEAR_INTERCEPTOR(cap_rights_clear, rights);8639}8640 8641INTERCEPTOR(bool, cap_rights_is_set,8642 __sanitizer_cap_rights_t *rights) {8643 CAP_RIGHTS_IS_SET_INTERCEPTOR(cap_rights_is_set, rights);8644}8645 8646INTERCEPTOR(int, cap_rights_limit, int fd,8647 const __sanitizer_cap_rights_t *rights) {8648 void *ctx;8649 COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_limit, fd, rights);8650 if (rights)8651 COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights));8652 8653 return REAL(cap_rights_limit)(fd, rights);8654}8655 8656INTERCEPTOR(int, cap_rights_get, int fd, __sanitizer_cap_rights_t *rights) {8657 void *ctx;8658 COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_get, fd, rights);8659 int ret = REAL(cap_rights_get)(fd, rights);8660 if (!ret && rights)8661 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rights, sizeof(*rights));8662 8663 return ret;8664}8665 8666INTERCEPTOR(bool, cap_rights_is_valid, const __sanitizer_cap_rights_t *rights) {8667 void *ctx;8668 COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_is_valid, rights);8669 if (rights)8670 COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights));8671 8672 return REAL(cap_rights_is_valid(rights));8673}8674 8675INTERCEPTOR(__sanitizer_cap_rights *, cap_rights_merge,8676 __sanitizer_cap_rights *dst, const __sanitizer_cap_rights *src) {8677 void *ctx;8678 COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_merge, dst, src);8679 if (src)8680 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));8681 8682 __sanitizer_cap_rights *ret = REAL(cap_rights_merge)(dst, src);8683 if (dst)8684 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(*dst));8685 8686 return ret;8687}8688 8689INTERCEPTOR(__sanitizer_cap_rights *, cap_rights_remove,8690 __sanitizer_cap_rights *dst, const __sanitizer_cap_rights *src) {8691 void *ctx;8692 COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_remove, dst, src);8693 if (src)8694 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));8695 8696 __sanitizer_cap_rights *ret = REAL(cap_rights_remove)(dst, src);8697 if (dst)8698 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(*dst));8699 8700 return ret;8701}8702 8703INTERCEPTOR(bool, cap_rights_contains, const __sanitizer_cap_rights *big,8704 const __sanitizer_cap_rights *little) {8705 void *ctx;8706 COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_contains, big, little);8707 if (little)8708 COMMON_INTERCEPTOR_READ_RANGE(ctx, little, sizeof(*little));8709 if (big)8710 COMMON_INTERCEPTOR_READ_RANGE(ctx, big, sizeof(*big));8711 8712 return REAL(cap_rights_contains)(big, little);8713}8714 8715INTERCEPTOR(int, cap_ioctls_limit, int fd, const uptr *cmds, SIZE_T ncmds) {8716 void *ctx;8717 COMMON_INTERCEPTOR_ENTER(ctx, cap_ioctls_limit, fd, cmds, ncmds);8718 if (cmds)8719 COMMON_INTERCEPTOR_READ_RANGE(ctx, cmds, sizeof(*cmds) * ncmds);8720 8721 return REAL(cap_ioctls_limit)(fd, cmds, ncmds);8722}8723 8724INTERCEPTOR(int, cap_ioctls_get, int fd, uptr *cmds, SIZE_T maxcmds) {8725 void *ctx;8726 COMMON_INTERCEPTOR_ENTER(ctx, cap_ioctls_get, fd, cmds, maxcmds);8727 int ret = REAL(cap_ioctls_get)(fd, cmds, maxcmds);8728 if (!ret && cmds)8729 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cmds, sizeof(*cmds) * maxcmds);8730 8731 return ret;8732}8733#define INIT_CAPSICUM \8734 COMMON_INTERCEPT_FUNCTION(cap_rights_init); \8735 COMMON_INTERCEPT_FUNCTION(cap_rights_set); \8736 COMMON_INTERCEPT_FUNCTION(cap_rights_clear); \8737 COMMON_INTERCEPT_FUNCTION(cap_rights_is_set); \8738 COMMON_INTERCEPT_FUNCTION(cap_rights_get); \8739 COMMON_INTERCEPT_FUNCTION(cap_rights_limit); \8740 COMMON_INTERCEPT_FUNCTION(cap_rights_contains); \8741 COMMON_INTERCEPT_FUNCTION(cap_rights_remove); \8742 COMMON_INTERCEPT_FUNCTION(cap_rights_merge); \8743 COMMON_INTERCEPT_FUNCTION(cap_rights_is_valid); \8744 COMMON_INTERCEPT_FUNCTION(cap_ioctls_get); \8745 COMMON_INTERCEPT_FUNCTION(cap_ioctls_limit)8746#else8747#define INIT_CAPSICUM8748#endif8749 8750#if SANITIZER_INTERCEPT_SHA18751INTERCEPTOR(void, SHA1Init, void *context) {8752 void *ctx;8753 COMMON_INTERCEPTOR_ENTER(ctx, SHA1Init, context);8754 REAL(SHA1Init)(context);8755 if (context)8756 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, SHA1_CTX_sz);8757}8758INTERCEPTOR(void, SHA1Update, void *context, const u8 *data, unsigned len) {8759 void *ctx;8760 COMMON_INTERCEPTOR_ENTER(ctx, SHA1Update, context, data, len);8761 if (data && len > 0)8762 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);8763 if (context)8764 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA1_CTX_sz);8765 REAL(SHA1Update)(context, data, len);8766 if (context)8767 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, SHA1_CTX_sz);8768}8769INTERCEPTOR(void, SHA1Final, u8 digest[20], void *context) {8770 void *ctx;8771 COMMON_INTERCEPTOR_ENTER(ctx, SHA1Final, digest, context);8772 if (context)8773 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA1_CTX_sz);8774 REAL(SHA1Final)(digest, context);8775 if (digest)8776 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(u8) * 20);8777}8778INTERCEPTOR(void, SHA1Transform, u32 state[5], u8 buffer[64]) {8779 void *ctx;8780 COMMON_INTERCEPTOR_ENTER(ctx, SHA1Transform, state, buffer);8781 if (state)8782 COMMON_INTERCEPTOR_READ_RANGE(ctx, state, sizeof(u32) * 5);8783 if (buffer)8784 COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, sizeof(u8) * 64);8785 REAL(SHA1Transform)(state, buffer);8786 if (state)8787 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, state, sizeof(u32) * 5);8788}8789INTERCEPTOR(char *, SHA1End, void *context, char *buf) {8790 void *ctx;8791 COMMON_INTERCEPTOR_ENTER(ctx, SHA1End, context, buf);8792 if (context)8793 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA1_CTX_sz);8794 char *ret = REAL(SHA1End)(context, buf);8795 if (ret)8796 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length);8797 return ret;8798}8799INTERCEPTOR(char *, SHA1File, char *filename, char *buf) {8800 void *ctx;8801 COMMON_INTERCEPTOR_ENTER(ctx, SHA1File, filename, buf);8802 if (filename)8803 COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1);8804 char *ret = REAL(SHA1File)(filename, buf);8805 if (ret)8806 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length);8807 return ret;8808}8809INTERCEPTOR(char *, SHA1FileChunk, char *filename, char *buf, OFF_T offset,8810 OFF_T length) {8811 void *ctx;8812 COMMON_INTERCEPTOR_ENTER(ctx, SHA1FileChunk, filename, buf, offset, length);8813 if (filename)8814 COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1);8815 char *ret = REAL(SHA1FileChunk)(filename, buf, offset, length);8816 if (ret)8817 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length);8818 return ret;8819}8820INTERCEPTOR(char *, SHA1Data, u8 *data, SIZE_T len, char *buf) {8821 void *ctx;8822 COMMON_INTERCEPTOR_ENTER(ctx, SHA1Data, data, len, buf);8823 if (data)8824 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);8825 char *ret = REAL(SHA1Data)(data, len, buf);8826 if (ret)8827 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length);8828 return ret;8829}8830#define INIT_SHA1 \8831 COMMON_INTERCEPT_FUNCTION(SHA1Init); \8832 COMMON_INTERCEPT_FUNCTION(SHA1Update); \8833 COMMON_INTERCEPT_FUNCTION(SHA1Final); \8834 COMMON_INTERCEPT_FUNCTION(SHA1Transform); \8835 COMMON_INTERCEPT_FUNCTION(SHA1End); \8836 COMMON_INTERCEPT_FUNCTION(SHA1File); \8837 COMMON_INTERCEPT_FUNCTION(SHA1FileChunk); \8838 COMMON_INTERCEPT_FUNCTION(SHA1Data)8839#else8840#define INIT_SHA18841#endif8842 8843#if SANITIZER_INTERCEPT_MD48844INTERCEPTOR(void, MD4Init, void *context) {8845 void *ctx;8846 COMMON_INTERCEPTOR_ENTER(ctx, MD4Init, context);8847 REAL(MD4Init)(context);8848 if (context)8849 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD4_CTX_sz);8850}8851 8852INTERCEPTOR(void, MD4Update, void *context, const unsigned char *data,8853 unsigned int len) {8854 void *ctx;8855 COMMON_INTERCEPTOR_ENTER(ctx, MD4Update, context, data, len);8856 if (data && len > 0)8857 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);8858 if (context)8859 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD4_CTX_sz);8860 REAL(MD4Update)(context, data, len);8861 if (context)8862 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD4_CTX_sz);8863}8864 8865INTERCEPTOR(void, MD4Final, unsigned char digest[16], void *context) {8866 void *ctx;8867 COMMON_INTERCEPTOR_ENTER(ctx, MD4Final, digest, context);8868 if (context)8869 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD4_CTX_sz);8870 REAL(MD4Final)(digest, context);8871 if (digest)8872 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(unsigned char) * 16);8873}8874 8875INTERCEPTOR(char *, MD4End, void *context, char *buf) {8876 void *ctx;8877 COMMON_INTERCEPTOR_ENTER(ctx, MD4End, context, buf);8878 if (context)8879 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD4_CTX_sz);8880 char *ret = REAL(MD4End)(context, buf);8881 if (ret)8882 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD4_return_length);8883 return ret;8884}8885 8886INTERCEPTOR(char *, MD4File, const char *filename, char *buf) {8887 void *ctx;8888 COMMON_INTERCEPTOR_ENTER(ctx, MD4File, filename, buf);8889 if (filename)8890 COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1);8891 char *ret = REAL(MD4File)(filename, buf);8892 if (ret)8893 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD4_return_length);8894 return ret;8895}8896 8897INTERCEPTOR(char *, MD4Data, const unsigned char *data, unsigned int len,8898 char *buf) {8899 void *ctx;8900 COMMON_INTERCEPTOR_ENTER(ctx, MD4Data, data, len, buf);8901 if (data && len > 0)8902 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);8903 char *ret = REAL(MD4Data)(data, len, buf);8904 if (ret)8905 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD4_return_length);8906 return ret;8907}8908 8909#define INIT_MD4 \8910 COMMON_INTERCEPT_FUNCTION(MD4Init); \8911 COMMON_INTERCEPT_FUNCTION(MD4Update); \8912 COMMON_INTERCEPT_FUNCTION(MD4Final); \8913 COMMON_INTERCEPT_FUNCTION(MD4End); \8914 COMMON_INTERCEPT_FUNCTION(MD4File); \8915 COMMON_INTERCEPT_FUNCTION(MD4Data)8916#else8917#define INIT_MD48918#endif8919 8920#if SANITIZER_INTERCEPT_RMD1608921INTERCEPTOR(void, RMD160Init, void *context) {8922 void *ctx;8923 COMMON_INTERCEPTOR_ENTER(ctx, RMD160Init, context);8924 REAL(RMD160Init)(context);8925 if (context)8926 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, RMD160_CTX_sz);8927}8928INTERCEPTOR(void, RMD160Update, void *context, const u8 *data, unsigned len) {8929 void *ctx;8930 COMMON_INTERCEPTOR_ENTER(ctx, RMD160Update, context, data, len);8931 if (data && len > 0)8932 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);8933 if (context)8934 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, RMD160_CTX_sz);8935 REAL(RMD160Update)(context, data, len);8936 if (context)8937 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, RMD160_CTX_sz);8938}8939INTERCEPTOR(void, RMD160Final, u8 digest[20], void *context) {8940 void *ctx;8941 COMMON_INTERCEPTOR_ENTER(ctx, RMD160Final, digest, context);8942 if (context)8943 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, RMD160_CTX_sz);8944 REAL(RMD160Final)(digest, context);8945 if (digest)8946 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(u8) * 20);8947}8948INTERCEPTOR(void, RMD160Transform, u32 state[5], u16 buffer[16]) {8949 void *ctx;8950 COMMON_INTERCEPTOR_ENTER(ctx, RMD160Transform, state, buffer);8951 if (state)8952 COMMON_INTERCEPTOR_READ_RANGE(ctx, state, sizeof(u32) * 5);8953 if (buffer)8954 COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, sizeof(u32) * 16);8955 REAL(RMD160Transform)(state, buffer);8956 if (state)8957 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, state, sizeof(u32) * 5);8958}8959INTERCEPTOR(char *, RMD160End, void *context, char *buf) {8960 void *ctx;8961 COMMON_INTERCEPTOR_ENTER(ctx, RMD160End, context, buf);8962 if (context)8963 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, RMD160_CTX_sz);8964 char *ret = REAL(RMD160End)(context, buf);8965 if (ret)8966 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length);8967 return ret;8968}8969INTERCEPTOR(char *, RMD160File, char *filename, char *buf) {8970 void *ctx;8971 COMMON_INTERCEPTOR_ENTER(ctx, RMD160File, filename, buf);8972 if (filename)8973 COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1);8974 char *ret = REAL(RMD160File)(filename, buf);8975 if (ret)8976 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length);8977 return ret;8978}8979INTERCEPTOR(char *, RMD160FileChunk, char *filename, char *buf, OFF_T offset,8980 OFF_T length) {8981 void *ctx;8982 COMMON_INTERCEPTOR_ENTER(ctx, RMD160FileChunk, filename, buf, offset, length);8983 if (filename)8984 COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1);8985 char *ret = REAL(RMD160FileChunk)(filename, buf, offset, length);8986 if (ret)8987 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length);8988 return ret;8989}8990INTERCEPTOR(char *, RMD160Data, u8 *data, SIZE_T len, char *buf) {8991 void *ctx;8992 COMMON_INTERCEPTOR_ENTER(ctx, RMD160Data, data, len, buf);8993 if (data && len > 0)8994 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);8995 char *ret = REAL(RMD160Data)(data, len, buf);8996 if (ret)8997 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length);8998 return ret;8999}9000#define INIT_RMD160 \9001 COMMON_INTERCEPT_FUNCTION(RMD160Init); \9002 COMMON_INTERCEPT_FUNCTION(RMD160Update); \9003 COMMON_INTERCEPT_FUNCTION(RMD160Final); \9004 COMMON_INTERCEPT_FUNCTION(RMD160Transform); \9005 COMMON_INTERCEPT_FUNCTION(RMD160End); \9006 COMMON_INTERCEPT_FUNCTION(RMD160File); \9007 COMMON_INTERCEPT_FUNCTION(RMD160FileChunk); \9008 COMMON_INTERCEPT_FUNCTION(RMD160Data)9009#else9010#define INIT_RMD1609011#endif9012 9013#if SANITIZER_INTERCEPT_FSEEK9014INTERCEPTOR(int, fseek, __sanitizer_FILE *stream, long int offset, int whence) {9015 void *ctx;9016 COMMON_INTERCEPTOR_ENTER(ctx, fseek, stream, offset, whence);9017 return REAL(fseek)(stream, offset, whence);9018}9019INTERCEPTOR(int, fseeko, __sanitizer_FILE *stream, OFF_T offset, int whence) {9020 void *ctx;9021 COMMON_INTERCEPTOR_ENTER(ctx, fseeko, stream, offset, whence);9022 return REAL(fseeko)(stream, offset, whence);9023}9024INTERCEPTOR(long int, ftell, __sanitizer_FILE *stream) {9025 void *ctx;9026 COMMON_INTERCEPTOR_ENTER(ctx, ftell, stream);9027 return REAL(ftell)(stream);9028}9029INTERCEPTOR(OFF_T, ftello, __sanitizer_FILE *stream) {9030 void *ctx;9031 COMMON_INTERCEPTOR_ENTER(ctx, ftello, stream);9032 return REAL(ftello)(stream);9033}9034INTERCEPTOR(void, rewind, __sanitizer_FILE *stream) {9035 void *ctx;9036 COMMON_INTERCEPTOR_ENTER(ctx, rewind, stream);9037 return REAL(rewind)(stream);9038}9039INTERCEPTOR(int, fgetpos, __sanitizer_FILE *stream, void *pos) {9040 void *ctx;9041 COMMON_INTERCEPTOR_ENTER(ctx, fgetpos, stream, pos);9042 int ret = REAL(fgetpos)(stream, pos);9043 if (pos && !ret)9044 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pos, fpos_t_sz);9045 return ret;9046}9047INTERCEPTOR(int, fsetpos, __sanitizer_FILE *stream, const void *pos) {9048 void *ctx;9049 COMMON_INTERCEPTOR_ENTER(ctx, fsetpos, stream, pos);9050 if (pos)9051 COMMON_INTERCEPTOR_READ_RANGE(ctx, pos, fpos_t_sz);9052 return REAL(fsetpos)(stream, pos);9053}9054#define INIT_FSEEK \9055 COMMON_INTERCEPT_FUNCTION(fseek); \9056 COMMON_INTERCEPT_FUNCTION(fseeko); \9057 COMMON_INTERCEPT_FUNCTION(ftell); \9058 COMMON_INTERCEPT_FUNCTION(ftello); \9059 COMMON_INTERCEPT_FUNCTION(rewind); \9060 COMMON_INTERCEPT_FUNCTION(fgetpos); \9061 COMMON_INTERCEPT_FUNCTION(fsetpos)9062#else9063#define INIT_FSEEK9064#endif9065 9066#if SANITIZER_INTERCEPT_MD29067INTERCEPTOR(void, MD2Init, void *context) {9068 void *ctx;9069 COMMON_INTERCEPTOR_ENTER(ctx, MD2Init, context);9070 REAL(MD2Init)(context);9071 if (context)9072 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD2_CTX_sz);9073}9074 9075INTERCEPTOR(void, MD2Update, void *context, const unsigned char *data,9076 unsigned int len) {9077 void *ctx;9078 COMMON_INTERCEPTOR_ENTER(ctx, MD2Update, context, data, len);9079 if (data && len > 0)9080 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);9081 if (context)9082 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD2_CTX_sz);9083 REAL(MD2Update)(context, data, len);9084 if (context)9085 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD2_CTX_sz);9086}9087 9088INTERCEPTOR(void, MD2Final, unsigned char digest[16], void *context) {9089 void *ctx;9090 COMMON_INTERCEPTOR_ENTER(ctx, MD2Final, digest, context);9091 if (context)9092 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD2_CTX_sz);9093 REAL(MD2Final)(digest, context);9094 if (digest)9095 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(unsigned char) * 16);9096}9097 9098INTERCEPTOR(char *, MD2End, void *context, char *buf) {9099 void *ctx;9100 COMMON_INTERCEPTOR_ENTER(ctx, MD2End, context, buf);9101 if (context)9102 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD2_CTX_sz);9103 char *ret = REAL(MD2End)(context, buf);9104 if (ret)9105 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD2_return_length);9106 return ret;9107}9108 9109INTERCEPTOR(char *, MD2File, const char *filename, char *buf) {9110 void *ctx;9111 COMMON_INTERCEPTOR_ENTER(ctx, MD2File, filename, buf);9112 if (filename)9113 COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1);9114 char *ret = REAL(MD2File)(filename, buf);9115 if (ret)9116 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD2_return_length);9117 return ret;9118}9119 9120INTERCEPTOR(char *, MD2Data, const unsigned char *data, unsigned int len,9121 char *buf) {9122 void *ctx;9123 COMMON_INTERCEPTOR_ENTER(ctx, MD2Data, data, len, buf);9124 if (data && len > 0)9125 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);9126 char *ret = REAL(MD2Data)(data, len, buf);9127 if (ret)9128 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD2_return_length);9129 return ret;9130}9131 9132#define INIT_MD2 \9133 COMMON_INTERCEPT_FUNCTION(MD2Init); \9134 COMMON_INTERCEPT_FUNCTION(MD2Update); \9135 COMMON_INTERCEPT_FUNCTION(MD2Final); \9136 COMMON_INTERCEPT_FUNCTION(MD2End); \9137 COMMON_INTERCEPT_FUNCTION(MD2File); \9138 COMMON_INTERCEPT_FUNCTION(MD2Data)9139#else9140#define INIT_MD29141#endif9142 9143#if SANITIZER_INTERCEPT_VIS9144INTERCEPTOR(char *, vis, char *dst, int c, int flag, int nextc) {9145 void *ctx;9146 COMMON_INTERCEPTOR_ENTER(ctx, vis, dst, c, flag, nextc);9147 char *end = REAL(vis)(dst, c, flag, nextc);9148 // dst is NULL terminated and end points to the NULL char9149 if (dst && end)9150 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, end - dst + 1);9151 return end;9152}9153INTERCEPTOR(char *, nvis, char *dst, SIZE_T dlen, int c, int flag, int nextc) {9154 void *ctx;9155 COMMON_INTERCEPTOR_ENTER(ctx, nvis, dst, dlen, c, flag, nextc);9156 char *end = REAL(nvis)(dst, dlen, c, flag, nextc);9157 // nvis cannot make sure the dst is NULL terminated9158 if (dst && end)9159 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, end - dst + 1);9160 return end;9161}9162INTERCEPTOR(int, strvis, char *dst, const char *src, int flag) {9163 void *ctx;9164 COMMON_INTERCEPTOR_ENTER(ctx, strvis, dst, src, flag);9165 if (src)9166 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);9167 int len = REAL(strvis)(dst, src, flag);9168 if (dst)9169 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1);9170 return len;9171}9172INTERCEPTOR(int, stravis, char **dst, const char *src, int flag) {9173 void *ctx;9174 COMMON_INTERCEPTOR_ENTER(ctx, stravis, dst, src, flag);9175 if (src)9176 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);9177 int len = REAL(stravis)(dst, src, flag);9178 if (dst) {9179 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(char *));9180 if (*dst)9181 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *dst, len + 1);9182 }9183 return len;9184}9185INTERCEPTOR(int, strnvis, char *dst, SIZE_T dlen, const char *src, int flag) {9186 void *ctx;9187 COMMON_INTERCEPTOR_ENTER(ctx, strnvis, dst, dlen, src, flag);9188 if (src)9189 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);9190 int len = REAL(strnvis)(dst, dlen, src, flag);9191 // The interface will be valid even if there is no space for NULL char9192 if (dst && len > 0)9193 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1);9194 return len;9195}9196INTERCEPTOR(int, strvisx, char *dst, const char *src, SIZE_T len, int flag) {9197 void *ctx;9198 COMMON_INTERCEPTOR_ENTER(ctx, strvisx, dst, src, len, flag);9199 if (src)9200 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);9201 int ret = REAL(strvisx)(dst, src, len, flag);9202 if (dst)9203 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);9204 return ret;9205}9206INTERCEPTOR(int, strnvisx, char *dst, SIZE_T dlen, const char *src, SIZE_T len,9207 int flag) {9208 void *ctx;9209 COMMON_INTERCEPTOR_ENTER(ctx, strnvisx, dst, dlen, src, len, flag);9210 if (src)9211 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);9212 int ret = REAL(strnvisx)(dst, dlen, src, len, flag);9213 if (dst && ret >= 0)9214 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);9215 return ret;9216}9217INTERCEPTOR(int, strenvisx, char *dst, SIZE_T dlen, const char *src, SIZE_T len,9218 int flag, int *cerr_ptr) {9219 void *ctx;9220 COMMON_INTERCEPTOR_ENTER(ctx, strenvisx, dst, dlen, src, len, flag, cerr_ptr);9221 if (src)9222 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);9223 // FIXME: only need to be checked when "flag | VIS_NOLOCALE" doesn't hold9224 // according to the implementation9225 if (cerr_ptr)9226 COMMON_INTERCEPTOR_READ_RANGE(ctx, cerr_ptr, sizeof(int));9227 int ret = REAL(strenvisx)(dst, dlen, src, len, flag, cerr_ptr);9228 if (dst && ret >= 0)9229 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);9230 if (cerr_ptr)9231 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cerr_ptr, sizeof(int));9232 return ret;9233}9234INTERCEPTOR(char *, svis, char *dst, int c, int flag, int nextc,9235 const char *extra) {9236 void *ctx;9237 COMMON_INTERCEPTOR_ENTER(ctx, svis, dst, c, flag, nextc, extra);9238 if (extra)9239 COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, internal_strlen(extra) + 1);9240 char *end = REAL(svis)(dst, c, flag, nextc, extra);9241 if (dst && end)9242 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, end - dst + 1);9243 return end;9244}9245INTERCEPTOR(char *, snvis, char *dst, SIZE_T dlen, int c, int flag, int nextc,9246 const char *extra) {9247 void *ctx;9248 COMMON_INTERCEPTOR_ENTER(ctx, snvis, dst, dlen, c, flag, nextc, extra);9249 if (extra)9250 COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, internal_strlen(extra) + 1);9251 char *end = REAL(snvis)(dst, dlen, c, flag, nextc, extra);9252 if (dst && end)9253 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst,9254 Min((SIZE_T)(end - dst + 1), dlen));9255 return end;9256}9257INTERCEPTOR(int, strsvis, char *dst, const char *src, int flag,9258 const char *extra) {9259 void *ctx;9260 COMMON_INTERCEPTOR_ENTER(ctx, strsvis, dst, src, flag, extra);9261 if (src)9262 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);9263 if (extra)9264 COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, internal_strlen(extra) + 1);9265 int len = REAL(strsvis)(dst, src, flag, extra);9266 if (dst)9267 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1);9268 return len;9269}9270INTERCEPTOR(int, strsnvis, char *dst, SIZE_T dlen, const char *src, int flag,9271 const char *extra) {9272 void *ctx;9273 COMMON_INTERCEPTOR_ENTER(ctx, strsnvis, dst, dlen, src, flag, extra);9274 if (src)9275 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);9276 if (extra)9277 COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, internal_strlen(extra) + 1);9278 int len = REAL(strsnvis)(dst, dlen, src, flag, extra);9279 // The interface will be valid even if there is no space for NULL char9280 if (dst && len >= 0)9281 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1);9282 return len;9283}9284INTERCEPTOR(int, strsvisx, char *dst, const char *src, SIZE_T len, int flag,9285 const char *extra) {9286 void *ctx;9287 COMMON_INTERCEPTOR_ENTER(ctx, strsvisx, dst, src, len, flag, extra);9288 if (src)9289 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);9290 if (extra)9291 COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, internal_strlen(extra) + 1);9292 int ret = REAL(strsvisx)(dst, src, len, flag, extra);9293 if (dst)9294 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);9295 return ret;9296}9297INTERCEPTOR(int, strsnvisx, char *dst, SIZE_T dlen, const char *src, SIZE_T len,9298 int flag, const char *extra) {9299 void *ctx;9300 COMMON_INTERCEPTOR_ENTER(ctx, strsnvisx, dst, dlen, src, len, flag, extra);9301 if (src)9302 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);9303 if (extra)9304 COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, internal_strlen(extra) + 1);9305 int ret = REAL(strsnvisx)(dst, dlen, src, len, flag, extra);9306 if (dst && ret >= 0)9307 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);9308 return ret;9309}9310INTERCEPTOR(int, strsenvisx, char *dst, SIZE_T dlen, const char *src,9311 SIZE_T len, int flag, const char *extra, int *cerr_ptr) {9312 void *ctx;9313 COMMON_INTERCEPTOR_ENTER(ctx, strsenvisx, dst, dlen, src, len, flag, extra,9314 cerr_ptr);9315 if (src)9316 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);9317 if (extra)9318 COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, internal_strlen(extra) + 1);9319 // FIXME: only need to be checked when "flag | VIS_NOLOCALE" doesn't hold9320 // according to the implementation9321 if (cerr_ptr)9322 COMMON_INTERCEPTOR_READ_RANGE(ctx, cerr_ptr, sizeof(int));9323 int ret = REAL(strsenvisx)(dst, dlen, src, len, flag, extra, cerr_ptr);9324 if (dst && ret >= 0)9325 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);9326 if (cerr_ptr)9327 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cerr_ptr, sizeof(int));9328 return ret;9329}9330INTERCEPTOR(int, unvis, char *cp, int c, int *astate, int flag) {9331 void *ctx;9332 COMMON_INTERCEPTOR_ENTER(ctx, unvis, cp, c, astate, flag);9333 if (astate)9334 COMMON_INTERCEPTOR_READ_RANGE(ctx, astate, sizeof(*astate));9335 int ret = REAL(unvis)(cp, c, astate, flag);9336 if (ret == unvis_valid || ret == unvis_validpush) {9337 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cp, sizeof(*cp));9338 }9339 return ret;9340}9341INTERCEPTOR(int, strunvis, char *dst, const char *src) {9342 void *ctx;9343 COMMON_INTERCEPTOR_ENTER(ctx, strunvis, dst, src);9344 if (src)9345 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);9346 int ret = REAL(strunvis)(dst, src);9347 if (ret != -1)9348 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);9349 return ret;9350}9351INTERCEPTOR(int, strnunvis, char *dst, SIZE_T dlen, const char *src) {9352 void *ctx;9353 COMMON_INTERCEPTOR_ENTER(ctx, strnunvis, dst, dlen, src);9354 if (src)9355 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);9356 int ret = REAL(strnunvis)(dst, dlen, src);9357 if (ret != -1)9358 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);9359 return ret;9360}9361INTERCEPTOR(int, strunvisx, char *dst, const char *src, int flag) {9362 void *ctx;9363 COMMON_INTERCEPTOR_ENTER(ctx, strunvisx, dst, src, flag);9364 if (src)9365 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);9366 int ret = REAL(strunvisx)(dst, src, flag);9367 if (ret != -1)9368 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);9369 return ret;9370}9371INTERCEPTOR(int, strnunvisx, char *dst, SIZE_T dlen, const char *src,9372 int flag) {9373 void *ctx;9374 COMMON_INTERCEPTOR_ENTER(ctx, strnunvisx, dst, dlen, src, flag);9375 if (src)9376 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);9377 int ret = REAL(strnunvisx)(dst, dlen, src, flag);9378 if (ret != -1)9379 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);9380 return ret;9381}9382#define INIT_VIS \9383 COMMON_INTERCEPT_FUNCTION(vis); \9384 COMMON_INTERCEPT_FUNCTION(nvis); \9385 COMMON_INTERCEPT_FUNCTION(strvis); \9386 COMMON_INTERCEPT_FUNCTION(stravis); \9387 COMMON_INTERCEPT_FUNCTION(strnvis); \9388 COMMON_INTERCEPT_FUNCTION(strvisx); \9389 COMMON_INTERCEPT_FUNCTION(strnvisx); \9390 COMMON_INTERCEPT_FUNCTION(strenvisx); \9391 COMMON_INTERCEPT_FUNCTION(svis); \9392 COMMON_INTERCEPT_FUNCTION(snvis); \9393 COMMON_INTERCEPT_FUNCTION(strsvis); \9394 COMMON_INTERCEPT_FUNCTION(strsnvis); \9395 COMMON_INTERCEPT_FUNCTION(strsvisx); \9396 COMMON_INTERCEPT_FUNCTION(strsnvisx); \9397 COMMON_INTERCEPT_FUNCTION(strsenvisx); \9398 COMMON_INTERCEPT_FUNCTION(unvis); \9399 COMMON_INTERCEPT_FUNCTION(strunvis); \9400 COMMON_INTERCEPT_FUNCTION(strnunvis); \9401 COMMON_INTERCEPT_FUNCTION(strunvisx); \9402 COMMON_INTERCEPT_FUNCTION(strnunvisx)9403#else9404#define INIT_VIS9405#endif9406 9407#if SANITIZER_INTERCEPT_CDB9408INTERCEPTOR(struct __sanitizer_cdbr *, cdbr_open, const char *path, int flags) {9409 void *ctx;9410 COMMON_INTERCEPTOR_ENTER(ctx, cdbr_open, path, flags);9411 if (path)9412 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);9413 struct __sanitizer_cdbr *cdbr = REAL(cdbr_open)(path, flags);9414 if (cdbr)9415 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbr, sizeof(*cdbr));9416 return cdbr;9417}9418 9419INTERCEPTOR(struct __sanitizer_cdbr *, cdbr_open_mem, void *base, SIZE_T size,9420 int flags, void (*unmap)(void *, void *, SIZE_T), void *cookie) {9421 void *ctx;9422 COMMON_INTERCEPTOR_ENTER(ctx, cdbr_open_mem, base, size, flags, unmap,9423 cookie);9424 if (base && size)9425 COMMON_INTERCEPTOR_READ_RANGE(ctx, base, size);9426 struct __sanitizer_cdbr *cdbr =9427 REAL(cdbr_open_mem)(base, size, flags, unmap, cookie);9428 if (cdbr)9429 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbr, sizeof(*cdbr));9430 return cdbr;9431}9432 9433INTERCEPTOR(u32, cdbr_entries, struct __sanitizer_cdbr *cdbr) {9434 void *ctx;9435 COMMON_INTERCEPTOR_ENTER(ctx, cdbr_entries, cdbr);9436 if (cdbr)9437 COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr));9438 return REAL(cdbr_entries)(cdbr);9439}9440 9441INTERCEPTOR(int, cdbr_get, struct __sanitizer_cdbr *cdbr, u32 index,9442 const void **data, SIZE_T *datalen) {9443 void *ctx;9444 COMMON_INTERCEPTOR_ENTER(ctx, cdbr_get, cdbr, index, data, datalen);9445 if (cdbr)9446 COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr));9447 int ret = REAL(cdbr_get)(cdbr, index, data, datalen);9448 if (!ret) {9449 if (data)9450 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, sizeof(*data));9451 if (datalen)9452 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, datalen, sizeof(*datalen));9453 if (data && datalen)9454 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *data, *datalen);9455 }9456 return ret;9457}9458 9459INTERCEPTOR(int, cdbr_find, struct __sanitizer_cdbr *cdbr, const void *key,9460 SIZE_T keylen, const void **data, SIZE_T *datalen) {9461 void *ctx;9462 COMMON_INTERCEPTOR_ENTER(ctx, cdbr_find, cdbr, key, keylen, data, datalen);9463 if (cdbr)9464 COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr));9465 if (key)9466 COMMON_INTERCEPTOR_READ_RANGE(ctx, key, keylen);9467 int ret = REAL(cdbr_find)(cdbr, key, keylen, data, datalen);9468 if (!ret) {9469 if (data)9470 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, sizeof(*data));9471 if (datalen)9472 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, datalen, sizeof(*datalen));9473 if (data && datalen)9474 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *data, *datalen);9475 }9476 return ret;9477}9478 9479INTERCEPTOR(void, cdbr_close, struct __sanitizer_cdbr *cdbr) {9480 void *ctx;9481 COMMON_INTERCEPTOR_ENTER(ctx, cdbr_close, cdbr);9482 if (cdbr)9483 COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr));9484 REAL(cdbr_close)(cdbr);9485}9486 9487INTERCEPTOR(struct __sanitizer_cdbw *, cdbw_open) {9488 void *ctx;9489 COMMON_INTERCEPTOR_ENTER(ctx, cdbw_open);9490 struct __sanitizer_cdbw *ret = REAL(cdbw_open)();9491 if (ret)9492 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret));9493 return ret;9494}9495 9496INTERCEPTOR(int, cdbw_put, struct __sanitizer_cdbw *cdbw, const void *key,9497 SIZE_T keylen, const void *data, SIZE_T datalen) {9498 void *ctx;9499 COMMON_INTERCEPTOR_ENTER(ctx, cdbw_put, cdbw, key, keylen, data, datalen);9500 if (cdbw)9501 COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw));9502 if (data && datalen)9503 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, datalen);9504 if (key && keylen)9505 COMMON_INTERCEPTOR_READ_RANGE(ctx, key, keylen);9506 int ret = REAL(cdbw_put)(cdbw, key, keylen, data, datalen);9507 if (!ret && cdbw)9508 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw));9509 return ret;9510}9511 9512INTERCEPTOR(int, cdbw_put_data, struct __sanitizer_cdbw *cdbw, const void *data,9513 SIZE_T datalen, u32 *index) {9514 void *ctx;9515 COMMON_INTERCEPTOR_ENTER(ctx, cdbw_put_data, cdbw, data, datalen, index);9516 if (cdbw)9517 COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw));9518 if (data && datalen)9519 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, datalen);9520 int ret = REAL(cdbw_put_data)(cdbw, data, datalen, index);9521 if (!ret) {9522 if (index)9523 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, index, sizeof(*index));9524 if (cdbw)9525 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw));9526 }9527 return ret;9528}9529 9530INTERCEPTOR(int, cdbw_put_key, struct __sanitizer_cdbw *cdbw, const void *key,9531 SIZE_T keylen, u32 index) {9532 void *ctx;9533 COMMON_INTERCEPTOR_ENTER(ctx, cdbw_put_key, cdbw, key, keylen, index);9534 if (cdbw)9535 COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw));9536 if (key && keylen)9537 COMMON_INTERCEPTOR_READ_RANGE(ctx, key, keylen);9538 int ret = REAL(cdbw_put_key)(cdbw, key, keylen, index);9539 if (!ret && cdbw)9540 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw));9541 return ret;9542}9543 9544INTERCEPTOR(int, cdbw_output, struct __sanitizer_cdbw *cdbw, int output,9545 const char descr[16], u32 (*seedgen)(void)) {9546 void *ctx;9547 COMMON_INTERCEPTOR_ENTER(ctx, cdbw_output, cdbw, output, descr, seedgen);9548 COMMON_INTERCEPTOR_FD_ACCESS(ctx, output);9549 if (cdbw)9550 COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw));9551 if (descr)9552 COMMON_INTERCEPTOR_READ_RANGE(ctx, descr, internal_strnlen(descr, 16));9553 if (seedgen)9554 COMMON_INTERCEPTOR_READ_RANGE(ctx, (void *)seedgen, sizeof(seedgen));9555 int ret = REAL(cdbw_output)(cdbw, output, descr, seedgen);9556 if (!ret) {9557 if (cdbw)9558 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw));9559 if (output >= 0)9560 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, output);9561 }9562 return ret;9563}9564 9565INTERCEPTOR(void, cdbw_close, struct __sanitizer_cdbw *cdbw) {9566 void *ctx;9567 COMMON_INTERCEPTOR_ENTER(ctx, cdbw_close, cdbw);9568 if (cdbw)9569 COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw));9570 REAL(cdbw_close)(cdbw);9571}9572 9573#define INIT_CDB \9574 COMMON_INTERCEPT_FUNCTION(cdbr_open); \9575 COMMON_INTERCEPT_FUNCTION(cdbr_open_mem); \9576 COMMON_INTERCEPT_FUNCTION(cdbr_entries); \9577 COMMON_INTERCEPT_FUNCTION(cdbr_get); \9578 COMMON_INTERCEPT_FUNCTION(cdbr_find); \9579 COMMON_INTERCEPT_FUNCTION(cdbr_close); \9580 COMMON_INTERCEPT_FUNCTION(cdbw_open); \9581 COMMON_INTERCEPT_FUNCTION(cdbw_put); \9582 COMMON_INTERCEPT_FUNCTION(cdbw_put_data); \9583 COMMON_INTERCEPT_FUNCTION(cdbw_put_key); \9584 COMMON_INTERCEPT_FUNCTION(cdbw_output); \9585 COMMON_INTERCEPT_FUNCTION(cdbw_close)9586#else9587#define INIT_CDB9588#endif9589 9590#if SANITIZER_INTERCEPT_GETFSENT9591INTERCEPTOR(void *, getfsent) {9592 void *ctx;9593 COMMON_INTERCEPTOR_ENTER(ctx, getfsent);9594 void *ret = REAL(getfsent)();9595 if (ret)9596 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, struct_fstab_sz);9597 return ret;9598}9599 9600INTERCEPTOR(void *, getfsspec, const char *spec) {9601 void *ctx;9602 COMMON_INTERCEPTOR_ENTER(ctx, getfsspec, spec);9603 if (spec)9604 COMMON_INTERCEPTOR_READ_RANGE(ctx, spec, internal_strlen(spec) + 1);9605 void *ret = REAL(getfsspec)(spec);9606 if (ret)9607 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, struct_fstab_sz);9608 return ret;9609}9610 9611INTERCEPTOR(void *, getfsfile, const char *file) {9612 void *ctx;9613 COMMON_INTERCEPTOR_ENTER(ctx, getfsfile, file);9614 if (file)9615 COMMON_INTERCEPTOR_READ_RANGE(ctx, file, internal_strlen(file) + 1);9616 void *ret = REAL(getfsfile)(file);9617 if (ret)9618 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, struct_fstab_sz);9619 return ret;9620}9621 9622#define INIT_GETFSENT \9623 COMMON_INTERCEPT_FUNCTION(getfsent); \9624 COMMON_INTERCEPT_FUNCTION(getfsspec); \9625 COMMON_INTERCEPT_FUNCTION(getfsfile);9626#else9627#define INIT_GETFSENT9628#endif9629 9630#if SANITIZER_INTERCEPT_ARC4RANDOM9631INTERCEPTOR(void, arc4random_buf, void *buf, SIZE_T len) {9632 void *ctx;9633 COMMON_INTERCEPTOR_ENTER(ctx, arc4random_buf, buf, len);9634 REAL(arc4random_buf)(buf, len);9635 if (buf && len)9636 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, len);9637}9638 9639INTERCEPTOR(void, arc4random_addrandom, u8 *dat, int datlen) {9640 void *ctx;9641 COMMON_INTERCEPTOR_ENTER(ctx, arc4random_addrandom, dat, datlen);9642 if (dat && datlen)9643 COMMON_INTERCEPTOR_READ_RANGE(ctx, dat, datlen);9644 REAL(arc4random_addrandom)(dat, datlen);9645}9646 9647#define INIT_ARC4RANDOM \9648 COMMON_INTERCEPT_FUNCTION(arc4random_buf); \9649 COMMON_INTERCEPT_FUNCTION(arc4random_addrandom);9650#else9651#define INIT_ARC4RANDOM9652#endif9653 9654#if SANITIZER_INTERCEPT_POPEN9655INTERCEPTOR(__sanitizer_FILE *, popen, const char *command, const char *type) {9656 void *ctx;9657 COMMON_INTERCEPTOR_ENTER(ctx, popen, command, type);9658 if (command)9659 COMMON_INTERCEPTOR_READ_RANGE(ctx, command, internal_strlen(command) + 1);9660 if (type)9661 COMMON_INTERCEPTOR_READ_RANGE(ctx, type, internal_strlen(type) + 1);9662 __sanitizer_FILE *res = REAL(popen)(command, type);9663 COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, nullptr);9664 if (res) unpoison_file(res);9665 return res;9666}9667#define INIT_POPEN COMMON_INTERCEPT_FUNCTION(popen)9668#else9669#define INIT_POPEN9670#endif9671 9672#if SANITIZER_INTERCEPT_POPENVE9673INTERCEPTOR(__sanitizer_FILE *, popenve, const char *path,9674 char *const *argv, char *const *envp, const char *type) {9675 void *ctx;9676 COMMON_INTERCEPTOR_ENTER(ctx, popenve, path, argv, envp, type);9677 if (path)9678 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);9679 if (argv) {9680 for (char *const *pa = argv; ; ++pa) {9681 COMMON_INTERCEPTOR_READ_RANGE(ctx, pa, sizeof(char **));9682 if (!*pa)9683 break;9684 COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, internal_strlen(*pa) + 1);9685 }9686 }9687 if (envp) {9688 for (char *const *pa = envp; ; ++pa) {9689 COMMON_INTERCEPTOR_READ_RANGE(ctx, pa, sizeof(char **));9690 if (!*pa)9691 break;9692 COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, internal_strlen(*pa) + 1);9693 }9694 }9695 if (type)9696 COMMON_INTERCEPTOR_READ_RANGE(ctx, type, internal_strlen(type) + 1);9697 __sanitizer_FILE *res = REAL(popenve)(path, argv, envp, type);9698 COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, nullptr);9699 if (res) unpoison_file(res);9700 return res;9701}9702#define INIT_POPENVE COMMON_INTERCEPT_FUNCTION(popenve)9703#else9704#define INIT_POPENVE9705#endif9706 9707#if SANITIZER_INTERCEPT_PCLOSE9708INTERCEPTOR(int, pclose, __sanitizer_FILE *fp) {9709 void *ctx;9710 COMMON_INTERCEPTOR_ENTER(ctx, pclose, fp);9711 COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);9712 const FileMetadata *m = GetInterceptorMetadata(fp);9713 int res = REAL(pclose)(fp);9714 if (m) {9715 COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);9716 DeleteInterceptorMetadata(fp);9717 }9718 return res;9719}9720#define INIT_PCLOSE COMMON_INTERCEPT_FUNCTION(pclose);9721#else9722#define INIT_PCLOSE9723#endif9724 9725#if SANITIZER_INTERCEPT_FUNOPEN9726typedef int (*funopen_readfn)(void *cookie, char *buf, int len);9727typedef int (*funopen_writefn)(void *cookie, const char *buf, int len);9728typedef OFF_T (*funopen_seekfn)(void *cookie, OFF_T offset, int whence);9729typedef int (*funopen_closefn)(void *cookie);9730 9731struct WrappedFunopenCookie {9732 void *real_cookie;9733 funopen_readfn real_read;9734 funopen_writefn real_write;9735 funopen_seekfn real_seek;9736 funopen_closefn real_close;9737};9738 9739static int wrapped_funopen_read(void *cookie, char *buf, int len) {9740 COMMON_INTERCEPTOR_UNPOISON_PARAM(3);9741 WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie;9742 funopen_readfn real_read = wrapped_cookie->real_read;9743 return real_read(wrapped_cookie->real_cookie, buf, len);9744}9745 9746static int wrapped_funopen_write(void *cookie, const char *buf, int len) {9747 COMMON_INTERCEPTOR_UNPOISON_PARAM(3);9748 WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie;9749 funopen_writefn real_write = wrapped_cookie->real_write;9750 return real_write(wrapped_cookie->real_cookie, buf, len);9751}9752 9753static OFF_T wrapped_funopen_seek(void *cookie, OFF_T offset, int whence) {9754 COMMON_INTERCEPTOR_UNPOISON_PARAM(3);9755 WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie;9756 funopen_seekfn real_seek = wrapped_cookie->real_seek;9757 return real_seek(wrapped_cookie->real_cookie, offset, whence);9758}9759 9760static int wrapped_funopen_close(void *cookie) {9761 COMMON_INTERCEPTOR_UNPOISON_PARAM(1);9762 WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie;9763 funopen_closefn real_close = wrapped_cookie->real_close;9764 int res = real_close(wrapped_cookie->real_cookie);9765 InternalFree(wrapped_cookie);9766 return res;9767}9768 9769INTERCEPTOR(__sanitizer_FILE *, funopen, void *cookie, funopen_readfn readfn,9770 funopen_writefn writefn, funopen_seekfn seekfn,9771 funopen_closefn closefn) {9772 void *ctx;9773 COMMON_INTERCEPTOR_ENTER(ctx, funopen, cookie, readfn, writefn, seekfn,9774 closefn);9775 9776 WrappedFunopenCookie *wrapped_cookie =9777 (WrappedFunopenCookie *)InternalAlloc(sizeof(WrappedFunopenCookie));9778 wrapped_cookie->real_cookie = cookie;9779 wrapped_cookie->real_read = readfn;9780 wrapped_cookie->real_write = writefn;9781 wrapped_cookie->real_seek = seekfn;9782 wrapped_cookie->real_close = closefn;9783 9784 __sanitizer_FILE *res =9785 REAL(funopen)(wrapped_cookie,9786 readfn ? wrapped_funopen_read : nullptr,9787 writefn ? wrapped_funopen_write : nullptr,9788 seekfn ? wrapped_funopen_seek : nullptr,9789 closefn ? wrapped_funopen_close : nullptr);9790 if (res)9791 unpoison_file(res);9792 return res;9793}9794#define INIT_FUNOPEN COMMON_INTERCEPT_FUNCTION(funopen)9795#else9796#define INIT_FUNOPEN9797#endif9798 9799#if SANITIZER_INTERCEPT_FUNOPEN29800typedef SSIZE_T (*funopen2_readfn)(void *cookie, void *buf, SIZE_T len);9801typedef SSIZE_T (*funopen2_writefn)(void *cookie, const void *buf, SIZE_T len);9802typedef OFF_T (*funopen2_seekfn)(void *cookie, OFF_T offset, int whence);9803typedef int (*funopen2_flushfn)(void *cookie);9804typedef int (*funopen2_closefn)(void *cookie);9805 9806struct WrappedFunopen2Cookie {9807 void *real_cookie;9808 funopen2_readfn real_read;9809 funopen2_writefn real_write;9810 funopen2_seekfn real_seek;9811 funopen2_flushfn real_flush;9812 funopen2_closefn real_close;9813};9814 9815static SSIZE_T wrapped_funopen2_read(void *cookie, void *buf, SIZE_T len) {9816 COMMON_INTERCEPTOR_UNPOISON_PARAM(3);9817 WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;9818 funopen2_readfn real_read = wrapped_cookie->real_read;9819 return real_read(wrapped_cookie->real_cookie, buf, len);9820}9821 9822static SSIZE_T wrapped_funopen2_write(void *cookie, const void *buf,9823 SIZE_T len) {9824 COMMON_INTERCEPTOR_UNPOISON_PARAM(3);9825 WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;9826 funopen2_writefn real_write = wrapped_cookie->real_write;9827 return real_write(wrapped_cookie->real_cookie, buf, len);9828}9829 9830static OFF_T wrapped_funopen2_seek(void *cookie, OFF_T offset, int whence) {9831 COMMON_INTERCEPTOR_UNPOISON_PARAM(3);9832 WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;9833 funopen2_seekfn real_seek = wrapped_cookie->real_seek;9834 return real_seek(wrapped_cookie->real_cookie, offset, whence);9835}9836 9837static int wrapped_funopen2_flush(void *cookie) {9838 COMMON_INTERCEPTOR_UNPOISON_PARAM(1);9839 WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;9840 funopen2_flushfn real_flush = wrapped_cookie->real_flush;9841 return real_flush(wrapped_cookie->real_cookie);9842}9843 9844static int wrapped_funopen2_close(void *cookie) {9845 COMMON_INTERCEPTOR_UNPOISON_PARAM(1);9846 WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;9847 funopen2_closefn real_close = wrapped_cookie->real_close;9848 int res = real_close(wrapped_cookie->real_cookie);9849 InternalFree(wrapped_cookie);9850 return res;9851}9852 9853INTERCEPTOR(__sanitizer_FILE *, funopen2, void *cookie, funopen2_readfn readfn,9854 funopen2_writefn writefn, funopen2_seekfn seekfn,9855 funopen2_flushfn flushfn, funopen2_closefn closefn) {9856 void *ctx;9857 COMMON_INTERCEPTOR_ENTER(ctx, funopen2, cookie, readfn, writefn, seekfn,9858 flushfn, closefn);9859 9860 WrappedFunopen2Cookie *wrapped_cookie =9861 (WrappedFunopen2Cookie *)InternalAlloc(sizeof(WrappedFunopen2Cookie));9862 wrapped_cookie->real_cookie = cookie;9863 wrapped_cookie->real_read = readfn;9864 wrapped_cookie->real_write = writefn;9865 wrapped_cookie->real_seek = seekfn;9866 wrapped_cookie->real_flush = flushfn;9867 wrapped_cookie->real_close = closefn;9868 9869 __sanitizer_FILE *res =9870 REAL(funopen2)(wrapped_cookie,9871 readfn ? wrapped_funopen2_read : nullptr,9872 writefn ? wrapped_funopen2_write : nullptr,9873 seekfn ? wrapped_funopen2_seek : nullptr,9874 flushfn ? wrapped_funopen2_flush : nullptr,9875 closefn ? wrapped_funopen2_close : nullptr);9876 if (res)9877 unpoison_file(res);9878 return res;9879}9880#define INIT_FUNOPEN2 COMMON_INTERCEPT_FUNCTION(funopen2)9881#else9882#define INIT_FUNOPEN29883#endif9884 9885#if SANITIZER_INTERCEPT_FDEVNAME9886INTERCEPTOR(char *, fdevname, int fd) {9887 void *ctx;9888 COMMON_INTERCEPTOR_ENTER(ctx, fdevname, fd);9889 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);9890 char *name = REAL(fdevname)(fd);9891 if (name) {9892 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, internal_strlen(name) + 1);9893 if (fd > 0)9894 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);9895 }9896 return name;9897}9898 9899INTERCEPTOR(char *, fdevname_r, int fd, char *buf, SIZE_T len) {9900 void *ctx;9901 COMMON_INTERCEPTOR_ENTER(ctx, fdevname_r, fd, buf, len);9902 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);9903 char *name = REAL(fdevname_r)(fd, buf, len);9904 if (name && buf && len > 0) {9905 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, internal_strlen(buf) + 1);9906 if (fd > 0)9907 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);9908 }9909 return name;9910}9911 9912#define INIT_FDEVNAME \9913 COMMON_INTERCEPT_FUNCTION(fdevname); \9914 COMMON_INTERCEPT_FUNCTION(fdevname_r);9915#else9916#define INIT_FDEVNAME9917#endif9918 9919#if SANITIZER_INTERCEPT_GETUSERSHELL9920INTERCEPTOR(char *, getusershell,) {9921 void *ctx;9922 COMMON_INTERCEPTOR_ENTER(ctx, getusershell,);9923 char *res = REAL(getusershell)();9924 if (res)9925 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);9926 return res;9927}9928 9929#define INIT_GETUSERSHELL COMMON_INTERCEPT_FUNCTION(getusershell);9930#else9931#define INIT_GETUSERSHELL9932#endif9933 9934#if SANITIZER_INTERCEPT_SL_INIT9935INTERCEPTOR(void *, sl_init) {9936 void *ctx;9937 COMMON_INTERCEPTOR_ENTER(ctx, sl_init);9938 void *res = REAL(sl_init)();9939 if (res)9940 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, __sanitizer::struct_StringList_sz);9941 return res;9942}9943 9944INTERCEPTOR(int, sl_add, void *sl, char *item) {9945 void *ctx;9946 COMMON_INTERCEPTOR_ENTER(ctx, sl_add, sl, item);9947 if (sl)9948 COMMON_INTERCEPTOR_READ_RANGE(ctx, sl, __sanitizer::struct_StringList_sz);9949 if (item)9950 COMMON_INTERCEPTOR_READ_RANGE(ctx, item, internal_strlen(item) + 1);9951 int res = REAL(sl_add)(sl, item);9952 if (!res)9953 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sl, __sanitizer::struct_StringList_sz);9954 return res;9955}9956 9957INTERCEPTOR(char *, sl_find, void *sl, const char *item) {9958 void *ctx;9959 COMMON_INTERCEPTOR_ENTER(ctx, sl_find, sl, item);9960 if (sl)9961 COMMON_INTERCEPTOR_READ_RANGE(ctx, sl, __sanitizer::struct_StringList_sz);9962 if (item)9963 COMMON_INTERCEPTOR_READ_RANGE(ctx, item, internal_strlen(item) + 1);9964 char *res = REAL(sl_find)(sl, item);9965 if (res)9966 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);9967 return res;9968}9969 9970INTERCEPTOR(void, sl_free, void *sl, int freeall) {9971 void *ctx;9972 COMMON_INTERCEPTOR_ENTER(ctx, sl_free, sl, freeall);9973 if (sl)9974 COMMON_INTERCEPTOR_READ_RANGE(ctx, sl, __sanitizer::struct_StringList_sz);9975 REAL(sl_free)(sl, freeall);9976}9977 9978#define INIT_SL_INIT \9979 COMMON_INTERCEPT_FUNCTION(sl_init); \9980 COMMON_INTERCEPT_FUNCTION(sl_add); \9981 COMMON_INTERCEPT_FUNCTION(sl_find); \9982 COMMON_INTERCEPT_FUNCTION(sl_free);9983#else9984#define INIT_SL_INIT9985#endif9986 9987#if SANITIZER_INTERCEPT_GETRANDOM9988INTERCEPTOR(SSIZE_T, getrandom, void *buf, SIZE_T buflen, unsigned int flags) {9989 void *ctx;9990 COMMON_INTERCEPTOR_ENTER(ctx, getrandom, buf, buflen, flags);9991 // If GRND_NONBLOCK is set in the flags, it is non blocking.9992 static const int grnd_nonblock = 1;9993 SSIZE_T n;9994 if ((flags & grnd_nonblock))9995 n = REAL(getrandom)(buf, buflen, flags);9996 else9997 n = COMMON_INTERCEPTOR_BLOCK_REAL(getrandom)(buf, buflen, flags);9998 if (n > 0) {9999 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, n);10000 }10001 return n;10002}10003#define INIT_GETRANDOM COMMON_INTERCEPT_FUNCTION(getrandom)10004#else10005#define INIT_GETRANDOM10006#endif10007 10008#if SANITIZER_INTERCEPT_GETENTROPY10009INTERCEPTOR(int, getentropy, void *buf, SIZE_T buflen) {10010 void *ctx;10011 COMMON_INTERCEPTOR_ENTER(ctx, getentropy, buf, buflen);10012 int r = REAL(getentropy)(buf, buflen);10013 if (r == 0) {10014 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);10015 }10016 return r;10017}10018#define INIT_GETENTROPY COMMON_INTERCEPT_FUNCTION(getentropy)10019#else10020#define INIT_GETENTROPY10021#endif10022 10023#if SANITIZER_INTERCEPT_QSORT_R10024typedef int (*qsort_r_compar_f)(const void *, const void *, void *);10025struct qsort_r_compar_params {10026 SIZE_T size;10027 qsort_r_compar_f compar;10028 void *arg;10029};10030static int wrapped_qsort_r_compar(const void *a, const void *b, void *arg) {10031 qsort_r_compar_params *params = (qsort_r_compar_params *)arg;10032 COMMON_INTERCEPTOR_UNPOISON_PARAM(3);10033 COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, params->size);10034 COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, params->size);10035 return params->compar(a, b, params->arg);10036}10037 10038INTERCEPTOR(void, qsort_r, void *base, SIZE_T nmemb, SIZE_T size,10039 qsort_r_compar_f compar, void *arg) {10040 void *ctx;10041 COMMON_INTERCEPTOR_ENTER(ctx, qsort_r, base, nmemb, size, compar, arg);10042 // Run the comparator over all array elements to detect any memory issues.10043 if (nmemb > 1) {10044 for (SIZE_T i = 0; i < nmemb - 1; ++i) {10045 void *p = (void *)((char *)base + i * size);10046 void *q = (void *)((char *)base + (i + 1) * size);10047 COMMON_INTERCEPTOR_UNPOISON_PARAM(3);10048 compar(p, q, arg);10049 }10050 }10051 qsort_r_compar_params params = {size, compar, arg};10052 REAL(qsort_r)(base, nmemb, size, wrapped_qsort_r_compar, ¶ms);10053 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, base, nmemb * size);10054}10055# define INIT_QSORT_R COMMON_INTERCEPT_FUNCTION(qsort_r)10056#else10057# define INIT_QSORT_R10058#endif10059 10060#if SANITIZER_INTERCEPT_QSORT && SANITIZER_INTERCEPT_QSORT_R10061INTERCEPTOR(void, qsort, void *base, SIZE_T nmemb, SIZE_T size,10062 qsort_r_compar_f compar) {10063 void *ctx;10064 COMMON_INTERCEPTOR_ENTER(ctx, qsort, base, nmemb, size, compar);10065 WRAP(qsort_r)(base, nmemb, size, compar, nullptr);10066}10067# define INIT_QSORT COMMON_INTERCEPT_FUNCTION(qsort)10068#elif SANITIZER_INTERCEPT_QSORT && !SANITIZER_INTERCEPT_QSORT_R10069// Glibc qsort uses a temporary buffer allocated either on stack or on heap.10070// Poisoned memory from there may get copied into the comparator arguments,10071// where it needs to be dealt with. But even that is not enough - the results of10072// the sort may be copied into the input/output array based on the results of10073// the comparator calls, but directly from the temp memory, bypassing the10074// unpoisoning done in wrapped_qsort_compar. We deal with this by, again,10075// unpoisoning the entire array after the sort is done.10076//10077// We can not check that the entire array is initialized at the beginning. IMHO,10078// it's fine for parts of the sorted objects to contain uninitialized memory,10079// ex. as padding in structs.10080typedef int (*qsort_compar_f)(const void *, const void *);10081static THREADLOCAL qsort_compar_f qsort_compar;10082static THREADLOCAL SIZE_T qsort_size;10083static int wrapped_qsort_compar(const void *a, const void *b) {10084 COMMON_INTERCEPTOR_UNPOISON_PARAM(2);10085 COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, qsort_size);10086 COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, qsort_size);10087 return qsort_compar(a, b);10088}10089 10090INTERCEPTOR(void, qsort, void *base, SIZE_T nmemb, SIZE_T size,10091 qsort_compar_f compar) {10092 void *ctx;10093 COMMON_INTERCEPTOR_ENTER(ctx, qsort, base, nmemb, size, compar);10094 // Run the comparator over all array elements to detect any memory issues.10095 if (nmemb > 1) {10096 for (SIZE_T i = 0; i < nmemb - 1; ++i) {10097 void *p = (void *)((char *)base + i * size);10098 void *q = (void *)((char *)base + (i + 1) * size);10099 COMMON_INTERCEPTOR_UNPOISON_PARAM(2);10100 compar(p, q);10101 }10102 }10103 qsort_compar_f old_compar = qsort_compar;10104 SIZE_T old_size = qsort_size;10105 // Handle qsort() implementations that recurse using an10106 // interposable function call:10107 bool already_wrapped = compar == wrapped_qsort_compar;10108 if (already_wrapped) {10109 // This case should only happen if the qsort() implementation calls itself10110 // using a preemptible function call (e.g. the FreeBSD libc version).10111 // Check that the size and comparator arguments are as expected.10112 CHECK_NE(compar, qsort_compar);10113 CHECK_EQ(qsort_size, size);10114 } else {10115 qsort_compar = compar;10116 qsort_size = size;10117 }10118 REAL(qsort)(base, nmemb, size, wrapped_qsort_compar);10119 if (!already_wrapped) {10120 qsort_compar = old_compar;10121 qsort_size = old_size;10122 }10123 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, base, nmemb * size);10124}10125# define INIT_QSORT COMMON_INTERCEPT_FUNCTION(qsort)10126#else10127# define INIT_QSORT10128#endif10129 10130#if SANITIZER_INTERCEPT_BSEARCH10131typedef int (*bsearch_compar_f)(const void *, const void *);10132struct bsearch_compar_params {10133 const void *key;10134 bsearch_compar_f compar;10135};10136 10137static int wrapped_bsearch_compar(const void *key, const void *b) {10138 const bsearch_compar_params *params = (const bsearch_compar_params *)key;10139 COMMON_INTERCEPTOR_UNPOISON_PARAM(2);10140 return params->compar(params->key, b);10141}10142 10143INTERCEPTOR(void *, bsearch, const void *key, const void *base, SIZE_T nmemb,10144 SIZE_T size, bsearch_compar_f compar) {10145 void *ctx;10146 COMMON_INTERCEPTOR_ENTER(ctx, bsearch, key, base, nmemb, size, compar);10147 bsearch_compar_params params = {key, compar};10148 return REAL(bsearch)(¶ms, base, nmemb, size, wrapped_bsearch_compar);10149}10150# define INIT_BSEARCH COMMON_INTERCEPT_FUNCTION(bsearch)10151#else10152# define INIT_BSEARCH10153#endif10154 10155#if SANITIZER_INTERCEPT_SIGALTSTACK10156INTERCEPTOR(int, sigaltstack, void *ss, void *oss) {10157 void *ctx;10158 COMMON_INTERCEPTOR_ENTER(ctx, sigaltstack, ss, oss);10159 int r = REAL(sigaltstack)(ss, oss);10160 if (r == 0 && oss != nullptr) {10161 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oss, struct_stack_t_sz);10162 }10163 return r;10164}10165#define INIT_SIGALTSTACK COMMON_INTERCEPT_FUNCTION(sigaltstack)10166#else10167#define INIT_SIGALTSTACK10168#endif10169 10170#if SANITIZER_INTERCEPT_PROCCTL10171INTERCEPTOR(int, procctl, int idtype, u64 id, int cmd, uptr data) {10172 void *ctx;10173 COMMON_INTERCEPTOR_ENTER(ctx, procctl, idtype, id, cmd, data);10174 static const int PROC_REAP_ACQUIRE = 2;10175 static const int PROC_REAP_RELEASE = 3;10176 static const int PROC_REAP_STATUS = 4;10177 static const int PROC_REAP_GETPIDS = 5;10178 static const int PROC_REAP_KILL = 6;10179 if (cmd < PROC_REAP_ACQUIRE || cmd > PROC_REAP_KILL) {10180 COMMON_INTERCEPTOR_READ_RANGE(ctx, (void *)data, sizeof(int));10181 } else {10182 // reap_acquire/reap_release bears no arguments.10183 if (cmd > PROC_REAP_RELEASE) {10184 unsigned int reapsz;10185 switch (cmd) {10186 case PROC_REAP_STATUS:10187 reapsz = struct_procctl_reaper_status_sz;10188 break;10189 case PROC_REAP_GETPIDS:10190 reapsz = struct_procctl_reaper_pids_sz;10191 break;10192 case PROC_REAP_KILL:10193 reapsz = struct_procctl_reaper_kill_sz;10194 break;10195 }10196 COMMON_INTERCEPTOR_READ_RANGE(ctx, (void *)data, reapsz);10197 }10198 }10199 return REAL(procctl)(idtype, id, cmd, data);10200}10201#define INIT_PROCCTL COMMON_INTERCEPT_FUNCTION(procctl)10202#else10203#define INIT_PROCCTL10204#endif10205 10206#if SANITIZER_INTERCEPT_UNAME10207INTERCEPTOR(int, uname, struct utsname *utsname) {10208#if SANITIZER_LINUX10209 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)10210 return internal_uname(utsname);10211#endif10212 void *ctx;10213 COMMON_INTERCEPTOR_ENTER(ctx, uname, utsname);10214 int res = REAL(uname)(utsname);10215 if (!res)10216 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, utsname,10217 __sanitizer::struct_utsname_sz);10218 return res;10219}10220#define INIT_UNAME COMMON_INTERCEPT_FUNCTION(uname)10221#else10222#define INIT_UNAME10223#endif10224 10225#if SANITIZER_INTERCEPT___XUNAME10226// FreeBSD's <sys/utsname.h> define uname() as10227// static __inline int uname(struct utsname *name) {10228// return __xuname(SYS_NMLN, (void*)name);10229// }10230INTERCEPTOR(int, __xuname, int size, void *utsname) {10231 void *ctx;10232 COMMON_INTERCEPTOR_ENTER(ctx, __xuname, size, utsname);10233 int res = REAL(__xuname)(size, utsname);10234 if (!res)10235 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, utsname,10236 __sanitizer::struct_utsname_sz);10237 return res;10238}10239#define INIT___XUNAME COMMON_INTERCEPT_FUNCTION(__xuname)10240#else10241#define INIT___XUNAME10242#endif10243 10244#if SANITIZER_INTERCEPT_ARGP_PARSE10245INTERCEPTOR(int, argp_parse, const struct argp *argp, int argc, char **argv,10246 unsigned flags, int *arg_index, void *input) {10247 void *ctx;10248 COMMON_INTERCEPTOR_ENTER(ctx, argp_parse, argp, argc, argv, flags, arg_index,10249 input);10250 for (int i = 0; i < argc; i++)10251 COMMON_INTERCEPTOR_READ_RANGE(ctx, argv[i], internal_strlen(argv[i]) + 1);10252 int res = REAL(argp_parse)(argp, argc, argv, flags, arg_index, input);10253 if (!res && arg_index)10254 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, arg_index, sizeof(int));10255 return res;10256}10257 10258#define INIT_ARGP_PARSE COMMON_INTERCEPT_FUNCTION(argp_parse);10259#else10260#define INIT_ARGP_PARSE10261#endif10262 10263#if SANITIZER_INTERCEPT_CPUSET_GETAFFINITY10264INTERCEPTOR(int, cpuset_getaffinity, int level, int which, __int64_t id, SIZE_T cpusetsize, __sanitizer_cpuset_t *mask) {10265 void *ctx;10266 COMMON_INTERCEPTOR_ENTER(ctx, cpuset_getaffinity, level, which, id, cpusetsize, mask);10267 int res = REAL(cpuset_getaffinity)(level, which, id, cpusetsize, mask);10268 if (mask && !res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mask, cpusetsize);10269 return res;10270}10271#define INIT_CPUSET_GETAFFINITY COMMON_INTERCEPT_FUNCTION(cpuset_getaffinity);10272#else10273#define INIT_CPUSET_GETAFFINITY10274#endif10275 10276#if SANITIZER_INTERCEPT_PREADV210277INTERCEPTOR(SSIZE_T, preadv2, int fd, __sanitizer_iovec *iov, int iovcnt,10278 OFF_T offset, int flags) {10279 void *ctx;10280 COMMON_INTERCEPTOR_ENTER(ctx, preadv2, fd, iov, iovcnt, offset, flags);10281 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);10282 SSIZE_T res = REAL(preadv2)(fd, iov, iovcnt, offset, flags);10283 if (res > 0) write_iovec(ctx, iov, iovcnt, res);10284 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);10285 return res;10286}10287#define INIT_PREADV2 COMMON_INTERCEPT_FUNCTION(preadv2)10288#else10289#define INIT_PREADV210290#endif10291 10292#if SANITIZER_INTERCEPT_PWRITEV210293INTERCEPTOR(SSIZE_T, pwritev2, int fd, __sanitizer_iovec *iov, int iovcnt,10294 OFF_T offset, int flags) {10295 void *ctx;10296 COMMON_INTERCEPTOR_ENTER(ctx, pwritev2, fd, iov, iovcnt, offset, flags);10297 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);10298 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);10299 SSIZE_T res = REAL(pwritev2)(fd, iov, iovcnt, offset, flags);10300 if (res > 0) read_iovec(ctx, iov, iovcnt, res);10301 return res;10302}10303#define INIT_PWRITEV2 COMMON_INTERCEPT_FUNCTION(pwritev2)10304#else10305#define INIT_PWRITEV210306#endif10307 10308#if SANITIZER_INTERCEPT_FREADLINK10309INTERCEPTOR(SSIZE_T, freadlink, int fd, char *buf, SIZE_T bufsiz) {10310 void *ctx;10311 COMMON_INTERCEPTOR_ENTER(ctx, freadlink, fd, buf, bufsiz);10312 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);10313 SSIZE_T res = REAL(freadlink)(fd, buf, bufsiz);10314 if (res > 0)10315 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res);10316 if (res >= 0 && fd > 0)10317 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);10318 return res;10319}10320# define INIT_FREADLINK COMMON_INTERCEPT_FUNCTION(freadlink)10321#else10322# define INIT_FREADLINK10323#endif10324 10325#if SANITIZER_INTERCEPT_GETSERVENT_R || SANITIZER_INTERCEPT_GETSERVBYNAME_R || \10326 SANITIZER_INTERCEPT_GETSERVBYPORT_R10327 10328UNUSED static void HandleGetServentReentrantResult(10329 void *ctx, int res, struct __sanitizer_servent *result_buf, char *buf,10330 SIZE_T buflen, struct __sanitizer_servent **result) {10331 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (char *)result, sizeof(void *));10332 if (res)10333 return;10334 if (*result) {10335 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (char *)*result,10336 sizeof(__sanitizer_servent));10337 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);10338 }10339}10340 10341#endif10342 10343#if SANITIZER_INTERCEPT_GETSERVENT_R10344INTERCEPTOR(int, getservent_r, struct __sanitizer_servent *result_buf,10345 char *buf, SIZE_T buflen, struct __sanitizer_servent **result) {10346 void *ctx;10347 COMMON_INTERCEPTOR_ENTER(ctx, getservent_r, result_buf, buf, buflen, result);10348 int res = REAL(getservent_r)(result_buf, buf, buflen, result);10349 HandleGetServentReentrantResult(ctx, res, result_buf, buf, buflen, result);10350 return res;10351}10352# define INIT_GETSERVENT_R COMMON_INTERCEPT_FUNCTION(getservent_r)10353#else10354# define INIT_GETSERVENT_R10355#endif10356 10357#if SANITIZER_INTERCEPT_GETSERVBYNAME_R10358INTERCEPTOR(int, getservbyname_r, const char *name, const char *proto,10359 struct __sanitizer_servent *result_buf, char *buf, SIZE_T buflen,10360 struct __sanitizer_servent **result) {10361 void *ctx;10362 COMMON_INTERCEPTOR_ENTER(ctx, getservbyname_r, name, proto, result_buf, buf,10363 buflen, result);10364 COMMON_INTERCEPTOR_READ_STRING(ctx, name, internal_strlen(name));10365 int res = REAL(getservbyname_r)(name, proto, result_buf, buf, buflen, result);10366 HandleGetServentReentrantResult(ctx, res, result_buf, buf, buflen, result);10367 return res;10368}10369# define INIT_GETSERVBYNAME_R COMMON_INTERCEPT_FUNCTION(getservbyname_r)10370#else10371# define INIT_GETSERVBYNAME_R10372#endif10373 10374#if SANITIZER_INTERCEPT_GETSERVBYPORT_R10375INTERCEPTOR(int, getservbyport_r, int port, const char *proto,10376 struct __sanitizer_servent *result_buf, char *buf, SIZE_T buflen,10377 struct __sanitizer_servent **result) {10378 void *ctx;10379 COMMON_INTERCEPTOR_ENTER(ctx, getservbyport_r, port, proto, result_buf, buf,10380 buflen, result);10381 int res = REAL(getservbyport_r)(port, proto, result_buf, buf, buflen, result);10382 HandleGetServentReentrantResult(ctx, res, result_buf, buf, buflen, result);10383 return res;10384}10385# define INIT_GETSERVBYPORT_R COMMON_INTERCEPT_FUNCTION(getservbyport_r)10386#else10387# define INIT_GETSERVBYPORT_R10388#endif10389 10390#include "sanitizer_common_interceptors_netbsd_compat.inc"10391 10392namespace __sanitizer {10393void InitializeMemintrinsicInterceptors();10394} // namespace __sanitizer10395 10396static void InitializeCommonInterceptors() {10397#if SI_POSIX10398 static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1];10399 interceptor_metadata_map = new ((void *)&metadata_mem) MetadataHashMap();10400#endif10401 10402 __sanitizer::InitializeMemintrinsicInterceptors();10403 10404 INIT_MMAP;10405 INIT_MMAP64;10406 INIT_TEXTDOMAIN;10407 INIT_STRLEN;10408 INIT_STRNLEN;10409 INIT_STRNDUP;10410 INIT___STRNDUP;10411 INIT_STRCMP;10412 INIT_STRNCMP;10413 INIT_STRCASECMP;10414 INIT_STRNCASECMP;10415 INIT_STRSTR;10416 INIT_STRCASESTR;10417 INIT_STRCHR;10418 INIT_STRCHRNUL;10419 INIT_STRRCHR;10420 INIT_STRSPN;10421 INIT_STRTOK;10422 INIT_STRPBRK;10423 INIT_STRXFRM;10424 INIT___STRXFRM_L;10425 INIT_MEMCHR;10426 INIT_MEMCMP;10427 INIT_BCMP;10428 INIT_MEMRCHR;10429 INIT_MEMMEM;10430 INIT_READ;10431 INIT_FREAD;10432 INIT_PREAD;10433 INIT_PREAD64;10434 INIT_READV;10435 INIT_PREADV;10436 INIT_PREADV64;10437 INIT_WRITE;10438 INIT_FWRITE;10439 INIT_PWRITE;10440 INIT_PWRITE64;10441 INIT_WRITEV;10442 INIT_PWRITEV;10443 INIT_PWRITEV64;10444 INIT_FGETS;10445 INIT_FPUTS;10446 INIT_PUTS;10447 INIT_PRCTL;10448 INIT_LOCALTIME_AND_FRIENDS;10449 INIT_STRPTIME;10450 INIT_SCANF;10451 INIT_ISOC99_SCANF;10452 INIT_PRINTF;10453 INIT_PRINTF_L;10454 INIT_ISOC99_PRINTF;10455 INIT_SETPROCTITLE;10456 INIT_FREXP;10457 INIT_FREXPF;10458 INIT_FREXPL;10459 INIT_GETPWNAM_AND_FRIENDS;10460 INIT_GETPWNAM_R_AND_FRIENDS;10461 INIT_GETPWENT;10462 INIT_FGETPWENT;10463 INIT_GETPWENT_R;10464 INIT_FGETPWENT_R;10465 INIT_FGETGRENT_R;10466 INIT_SETPWENT;10467 INIT_CLOCK_GETTIME;10468 INIT_CLOCK_GETCPUCLOCKID;10469 INIT_TIMER_CREATE;10470 INIT_GETITIMER;10471 INIT_TIME;10472 INIT_TIMESPEC_GET;10473 INIT_GLOB;10474 INIT_GLOB64;10475 INIT___B64_TO;10476 INIT_DN_COMP_EXPAND;10477 INIT_POSIX_SPAWN;10478 INIT_WAIT;10479 INIT_WAIT4;10480 INIT_INET;10481 INIT_PTHREAD_GETSCHEDPARAM;10482 INIT_GETADDRINFO;10483 INIT_GETNAMEINFO;10484 INIT_GETSOCKNAME;10485 INIT_GETHOSTBYNAME;10486 INIT_GETHOSTBYNAME2;10487 INIT_GETHOSTBYNAME_R;10488 INIT_GETHOSTBYNAME2_R;10489 INIT_GETHOSTBYADDR_R;10490 INIT_GETHOSTENT_R;10491 INIT_GETSOCKOPT;10492 INIT_ACCEPT;10493 INIT_ACCEPT4;10494 INIT_PACCEPT;10495 INIT_MODF;10496 INIT_RECVMSG;10497 INIT_SENDMSG;10498 INIT_RECVMMSG;10499 INIT_SENDMMSG;10500 INIT_SYSMSG;10501 INIT_GETPEERNAME;10502 INIT_IOCTL;10503 INIT_INET_ATON;10504 INIT_SYSINFO;10505 INIT_READDIR;10506 INIT_READDIR64;10507 INIT_PTRACE;10508 INIT_SETLOCALE;10509 INIT_GETCWD;10510 INIT_GET_CURRENT_DIR_NAME;10511 INIT_STRTOIMAX;10512 INIT_STRTOIMAX_C23;10513 INIT_MBSTOWCS;10514 INIT_MBSNRTOWCS;10515 INIT_WCSTOMBS;10516 INIT_WCSNRTOMBS;10517 INIT_WCRTOMB;10518 INIT_WCTOMB;10519 INIT_TCGETATTR;10520 INIT_REALPATH;10521 INIT_CANONICALIZE_FILE_NAME;10522 INIT_CONFSTR;10523 INIT_SCHED_GETAFFINITY;10524 INIT_SCHED_GETPARAM;10525 INIT_STRERROR;10526 INIT_STRERROR_R;10527 INIT_XPG_STRERROR_R;10528 INIT_SCANDIR;10529 INIT_SCANDIR64;10530 INIT_GETGROUPS;10531 INIT_POLL;10532 INIT_PPOLL;10533 INIT_WORDEXP;10534 INIT_SIGWAIT;10535 INIT_SIGWAITINFO;10536 INIT_SIGTIMEDWAIT;10537 INIT_SIGSETOPS;10538 INIT_SIGSET_LOGICOPS;10539 INIT_SIGPENDING;10540 INIT_SIGPROCMASK;10541 INIT_PTHREAD_SIGMASK;10542 INIT_BACKTRACE;10543 INIT__EXIT;10544 INIT___LIBC_THR_SETCANCELSTATE;10545 INIT_GETMNTENT;10546 INIT_GETMNTENT_R;10547 INIT_STATFS;10548 INIT_STATFS64;10549 INIT_STATVFS;10550 INIT_STATVFS64;10551 INIT_INITGROUPS;10552 INIT_ETHER_NTOA_ATON;10553 INIT_ETHER_HOST;10554 INIT_ETHER_R;10555 INIT_SHMCTL;10556 INIT_RANDOM_R;10557 INIT_PTHREAD_ATTR_GET;10558 INIT_PTHREAD_ATTR_GET_SCHED;10559 INIT_PTHREAD_ATTR_GETINHERITSCHED;10560 INIT_PTHREAD_ATTR_GETAFFINITY_NP;10561 INIT_PTHREAD_GETAFFINITY_NP;10562 INIT_PTHREAD_MUTEXATTR_GETPSHARED;10563 INIT_PTHREAD_MUTEXATTR_GETTYPE;10564 INIT_PTHREAD_MUTEXATTR_GETPROTOCOL;10565 INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING;10566 INIT_PTHREAD_MUTEXATTR_GETROBUST;10567 INIT_PTHREAD_MUTEXATTR_GETROBUST_NP;10568 INIT_PTHREAD_RWLOCKATTR_GETPSHARED;10569 INIT_PTHREAD_RWLOCKATTR_GETKIND_NP;10570 INIT_PTHREAD_CONDATTR_GETPSHARED;10571 INIT_PTHREAD_CONDATTR_GETCLOCK;10572 INIT_PTHREAD_BARRIERATTR_GETPSHARED;10573 INIT_TMPNAM;10574 INIT_TMPNAM_R;10575 INIT_PTSNAME;10576 INIT_PTSNAME_R;10577 INIT_TTYNAME;10578 INIT_TTYNAME_R;10579 INIT_TEMPNAM;10580 INIT_PTHREAD_SETNAME_NP;10581 INIT_PTHREAD_GETNAME_NP;10582 INIT_SINCOS;10583 INIT_REMQUO;10584 INIT_REMQUOL;10585 INIT_LGAMMA;10586 INIT_LGAMMAL;10587 INIT_LGAMMA_R;10588 INIT_LGAMMAL_R;10589 INIT_DRAND48_R;10590 INIT_RAND_R;10591 INIT_GETLINE;10592 INIT_ICONV;10593 INIT_TIMES;10594 INIT_TLS_GET_ADDR;10595 INIT_LISTXATTR;10596 INIT_GETXATTR;10597 INIT_GETRESID;10598 INIT_GETIFADDRS;10599 INIT_IF_INDEXTONAME;10600 INIT_CAPGET;10601 INIT_FTIME;10602 INIT_XDR;10603 INIT_XDRREC_LINUX;10604 INIT_TSEARCH;10605 INIT_LIBIO_INTERNALS;10606 INIT_FOPEN;10607 INIT_FOPEN64;10608 INIT_FLOPEN;10609 INIT_OPEN_MEMSTREAM;10610 INIT_OBSTACK;10611 INIT_FFLUSH;10612 INIT_FCLOSE;10613 INIT_DLOPEN_DLCLOSE;10614 INIT_GETPASS;10615 INIT_TIMERFD;10616 INIT_MLOCKX;10617 INIT_FOPENCOOKIE;10618 INIT_SEM;10619 INIT_PTHREAD_SETCANCEL;10620 INIT_MINCORE;10621 INIT_PROCESS_VM_READV;10622 INIT_CTERMID;10623 INIT_CTERMID_R;10624 INIT_RECV_RECVFROM;10625 INIT_SEND_SENDTO;10626 INIT_STAT;10627 INIT_STAT64;10628 INIT_EVENTFD_READ_WRITE;10629 INIT_LSTAT;10630 INIT_LSTAT64;10631 INIT___XSTAT;10632 INIT___XSTAT64;10633 INIT___LXSTAT;10634 INIT___LXSTAT64;10635 // FIXME: add other *stat interceptors.10636 INIT_UTMP;10637 INIT_UTMPX;10638 INIT_GETLOADAVG;10639 INIT_WCSLEN;10640 INIT_WCSCAT;10641 INIT_WCSDUP;10642 INIT_WCSXFRM;10643 INIT___WCSXFRM_L;10644 INIT_ACCT;10645 INIT_USER_FROM_UID;10646 INIT_UID_FROM_USER;10647 INIT_GROUP_FROM_GID;10648 INIT_GID_FROM_GROUP;10649 INIT_ACCESS;10650 INIT_FACCESSAT;10651 INIT_GETGROUPLIST;10652 INIT_GETGROUPMEMBERSHIP;10653 INIT_READLINK;10654 INIT_READLINKAT;10655 INIT_NAME_TO_HANDLE_AT;10656 INIT_OPEN_BY_HANDLE_AT;10657 INIT_STRLCPY;10658 INIT_DEVNAME;10659 INIT_DEVNAME_R;10660 INIT_FGETLN;10661 INIT_STRMODE;10662 INIT_TTYENT;10663 INIT_PROTOENT;10664 INIT_PROTOENT_R;10665 INIT_NETENT;10666 INIT_GETMNTINFO;10667 INIT_MI_VECTOR_HASH;10668 INIT_SETVBUF;10669 INIT_GETVFSSTAT;10670 INIT_REGEX;10671 INIT_REGEXSUB;10672 INIT_FTS;10673 INIT_SYSCTL;10674 INIT_ASYSCTL;10675 INIT_SYSCTLGETMIBINFO;10676 INIT_NL_LANGINFO;10677 INIT_MODCTL;10678 INIT_STRTONUM;10679 INIT_FPARSELN;10680 INIT_STATVFS1;10681 INIT_STRTOI;10682 INIT_CAPSICUM;10683 INIT_SHA1;10684 INIT_MD4;10685 INIT_RMD160;10686 INIT_FSEEK;10687 INIT_MD2;10688 INIT_VIS;10689 INIT_CDB;10690 INIT_GETFSENT;10691 INIT_ARC4RANDOM;10692 INIT_POPEN;10693 INIT_POPENVE;10694 INIT_PCLOSE;10695 INIT_FUNOPEN;10696 INIT_FUNOPEN2;10697 INIT_FDEVNAME;10698 INIT_GETUSERSHELL;10699 INIT_SL_INIT;10700 INIT_GETRANDOM;10701 INIT_GETENTROPY;10702 INIT_QSORT;10703 INIT_QSORT_R;10704 INIT_BSEARCH;10705 INIT_SIGALTSTACK;10706 INIT_PROCCTL10707 INIT_UNAME;10708 INIT___XUNAME;10709 INIT_ARGP_PARSE;10710 INIT_CPUSET_GETAFFINITY;10711 INIT_PREADV2;10712 INIT_PWRITEV2;10713 INIT_FREADLINK;10714 10715 INIT___PRINTF_CHK;10716 INIT_GETSERVENT_R;10717 INIT_GETSERVBYNAME_R;10718 INIT_GETSERVBYPORT_R;10719}10720