10fca6ea1SDimitry Andric //===--- rtsan_interceptors.cpp - Realtime Sanitizer ------------*- C++ -*-===// 20fca6ea1SDimitry Andric // 30fca6ea1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40fca6ea1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50fca6ea1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60fca6ea1SDimitry Andric // 70fca6ea1SDimitry Andric //===----------------------------------------------------------------------===// 80fca6ea1SDimitry Andric // 90fca6ea1SDimitry Andric //===----------------------------------------------------------------------===// 100fca6ea1SDimitry Andric 110fca6ea1SDimitry Andric #include "rtsan/rtsan_interceptors.h" 120fca6ea1SDimitry Andric 130fca6ea1SDimitry Andric #include "interception/interception.h" 140fca6ea1SDimitry Andric #include "sanitizer_common/sanitizer_allocator_dlsym.h" 150fca6ea1SDimitry Andric #include "sanitizer_common/sanitizer_allocator_internal.h" 160fca6ea1SDimitry Andric #include "sanitizer_common/sanitizer_platform.h" 170fca6ea1SDimitry Andric #include "sanitizer_common/sanitizer_platform_interceptors.h" 180fca6ea1SDimitry Andric 190fca6ea1SDimitry Andric #include "interception/interception.h" 200fca6ea1SDimitry Andric #include "rtsan/rtsan.h" 210fca6ea1SDimitry Andric #include "rtsan/rtsan_context.h" 220fca6ea1SDimitry Andric 230fca6ea1SDimitry Andric #if SANITIZER_APPLE 24*52418fc2SDimitry Andric 25*52418fc2SDimitry Andric #if TARGET_OS_MAC 26*52418fc2SDimitry Andric // On MacOS OSSpinLockLock is deprecated and no longer present in the headers, 27*52418fc2SDimitry Andric // but the symbol still exists on the system. Forward declare here so we 28*52418fc2SDimitry Andric // don't get compilation errors. 29*52418fc2SDimitry Andric #include <stdint.h> 30*52418fc2SDimitry Andric extern "C" { 31*52418fc2SDimitry Andric typedef int32_t OSSpinLock; 32*52418fc2SDimitry Andric void OSSpinLockLock(volatile OSSpinLock *__lock); 33*52418fc2SDimitry Andric } 34*52418fc2SDimitry Andric #endif 35*52418fc2SDimitry Andric 360fca6ea1SDimitry Andric #include <libkern/OSAtomic.h> 370fca6ea1SDimitry Andric #include <os/lock.h> 380fca6ea1SDimitry Andric #endif 390fca6ea1SDimitry Andric 400fca6ea1SDimitry Andric #if SANITIZER_INTERCEPT_MEMALIGN || SANITIZER_INTERCEPT_PVALLOC 410fca6ea1SDimitry Andric #include <malloc.h> 420fca6ea1SDimitry Andric #endif 430fca6ea1SDimitry Andric 440fca6ea1SDimitry Andric #include <fcntl.h> 450fca6ea1SDimitry Andric #include <pthread.h> 460fca6ea1SDimitry Andric #include <stdarg.h> 470fca6ea1SDimitry Andric #include <stdio.h> 480fca6ea1SDimitry Andric #include <sys/socket.h> 490fca6ea1SDimitry Andric #include <time.h> 500fca6ea1SDimitry Andric #include <unistd.h> 510fca6ea1SDimitry Andric 520fca6ea1SDimitry Andric using namespace __sanitizer; 530fca6ea1SDimitry Andric 540fca6ea1SDimitry Andric using __rtsan::rtsan_init_is_running; 550fca6ea1SDimitry Andric using __rtsan::rtsan_initialized; 560fca6ea1SDimitry Andric 570fca6ea1SDimitry Andric namespace { 580fca6ea1SDimitry Andric struct DlsymAlloc : public DlSymAllocator<DlsymAlloc> { 590fca6ea1SDimitry Andric static bool UseImpl() { return !rtsan_initialized; } 600fca6ea1SDimitry Andric }; 610fca6ea1SDimitry Andric } // namespace 620fca6ea1SDimitry Andric 630fca6ea1SDimitry Andric void ExpectNotRealtime(const char *intercepted_function_name) { 640fca6ea1SDimitry Andric __rtsan::GetContextForThisThread().ExpectNotRealtime( 650fca6ea1SDimitry Andric intercepted_function_name); 660fca6ea1SDimitry Andric } 670fca6ea1SDimitry Andric 680fca6ea1SDimitry Andric // Filesystem 690fca6ea1SDimitry Andric 700fca6ea1SDimitry Andric INTERCEPTOR(int, open, const char *path, int oflag, ...) { 710fca6ea1SDimitry Andric // TODO Establish whether we should intercept here if the flag contains 720fca6ea1SDimitry Andric // O_NONBLOCK 730fca6ea1SDimitry Andric ExpectNotRealtime("open"); 740fca6ea1SDimitry Andric 750fca6ea1SDimitry Andric va_list args; 760fca6ea1SDimitry Andric va_start(args, oflag); 770fca6ea1SDimitry Andric const mode_t mode = va_arg(args, int); 780fca6ea1SDimitry Andric va_end(args); 790fca6ea1SDimitry Andric 800fca6ea1SDimitry Andric const int result = REAL(open)(path, oflag, mode); 810fca6ea1SDimitry Andric return result; 820fca6ea1SDimitry Andric } 830fca6ea1SDimitry Andric 840fca6ea1SDimitry Andric INTERCEPTOR(int, openat, int fd, const char *path, int oflag, ...) { 850fca6ea1SDimitry Andric // TODO Establish whether we should intercept here if the flag contains 860fca6ea1SDimitry Andric // O_NONBLOCK 870fca6ea1SDimitry Andric ExpectNotRealtime("openat"); 880fca6ea1SDimitry Andric 890fca6ea1SDimitry Andric va_list args; 900fca6ea1SDimitry Andric va_start(args, oflag); 910fca6ea1SDimitry Andric mode_t mode = va_arg(args, int); 920fca6ea1SDimitry Andric va_end(args); 930fca6ea1SDimitry Andric 940fca6ea1SDimitry Andric const int result = REAL(openat)(fd, path, oflag, mode); 950fca6ea1SDimitry Andric return result; 960fca6ea1SDimitry Andric } 970fca6ea1SDimitry Andric 980fca6ea1SDimitry Andric INTERCEPTOR(int, creat, const char *path, mode_t mode) { 990fca6ea1SDimitry Andric // TODO Establish whether we should intercept here if the flag contains 1000fca6ea1SDimitry Andric // O_NONBLOCK 1010fca6ea1SDimitry Andric ExpectNotRealtime("creat"); 1020fca6ea1SDimitry Andric const int result = REAL(creat)(path, mode); 1030fca6ea1SDimitry Andric return result; 1040fca6ea1SDimitry Andric } 1050fca6ea1SDimitry Andric 1060fca6ea1SDimitry Andric INTERCEPTOR(int, fcntl, int filedes, int cmd, ...) { 1070fca6ea1SDimitry Andric ExpectNotRealtime("fcntl"); 1080fca6ea1SDimitry Andric 1090fca6ea1SDimitry Andric va_list args; 1100fca6ea1SDimitry Andric va_start(args, cmd); 1110fca6ea1SDimitry Andric 1120fca6ea1SDimitry Andric // Following precedent here. The linux source (fcntl.c, do_fcntl) accepts the 1130fca6ea1SDimitry Andric // final argument in a variable that will hold the largest of the possible 1140fca6ea1SDimitry Andric // argument types (pointers and ints are typical in fcntl) It is then assumed 1150fca6ea1SDimitry Andric // that the implementation of fcntl will cast it properly depending on cmd. 1160fca6ea1SDimitry Andric // 1170fca6ea1SDimitry Andric // This is also similar to what is done in 1180fca6ea1SDimitry Andric // sanitizer_common/sanitizer_common_syscalls.inc 1190fca6ea1SDimitry Andric const unsigned long arg = va_arg(args, unsigned long); 1200fca6ea1SDimitry Andric int result = REAL(fcntl)(filedes, cmd, arg); 1210fca6ea1SDimitry Andric 1220fca6ea1SDimitry Andric va_end(args); 1230fca6ea1SDimitry Andric 1240fca6ea1SDimitry Andric return result; 1250fca6ea1SDimitry Andric } 1260fca6ea1SDimitry Andric 1270fca6ea1SDimitry Andric INTERCEPTOR(int, close, int filedes) { 1280fca6ea1SDimitry Andric ExpectNotRealtime("close"); 1290fca6ea1SDimitry Andric return REAL(close)(filedes); 1300fca6ea1SDimitry Andric } 1310fca6ea1SDimitry Andric 1320fca6ea1SDimitry Andric INTERCEPTOR(FILE *, fopen, const char *path, const char *mode) { 1330fca6ea1SDimitry Andric ExpectNotRealtime("fopen"); 1340fca6ea1SDimitry Andric return REAL(fopen)(path, mode); 1350fca6ea1SDimitry Andric } 1360fca6ea1SDimitry Andric 1370fca6ea1SDimitry Andric INTERCEPTOR(size_t, fread, void *ptr, size_t size, size_t nitems, 1380fca6ea1SDimitry Andric FILE *stream) { 1390fca6ea1SDimitry Andric ExpectNotRealtime("fread"); 1400fca6ea1SDimitry Andric return REAL(fread)(ptr, size, nitems, stream); 1410fca6ea1SDimitry Andric } 1420fca6ea1SDimitry Andric 1430fca6ea1SDimitry Andric INTERCEPTOR(size_t, fwrite, const void *ptr, size_t size, size_t nitems, 1440fca6ea1SDimitry Andric FILE *stream) { 1450fca6ea1SDimitry Andric ExpectNotRealtime("fwrite"); 1460fca6ea1SDimitry Andric return REAL(fwrite)(ptr, size, nitems, stream); 1470fca6ea1SDimitry Andric } 1480fca6ea1SDimitry Andric 1490fca6ea1SDimitry Andric INTERCEPTOR(int, fclose, FILE *stream) { 1500fca6ea1SDimitry Andric ExpectNotRealtime("fclose"); 1510fca6ea1SDimitry Andric return REAL(fclose)(stream); 1520fca6ea1SDimitry Andric } 1530fca6ea1SDimitry Andric 1540fca6ea1SDimitry Andric INTERCEPTOR(int, fputs, const char *s, FILE *stream) { 1550fca6ea1SDimitry Andric ExpectNotRealtime("fputs"); 1560fca6ea1SDimitry Andric return REAL(fputs)(s, stream); 1570fca6ea1SDimitry Andric } 1580fca6ea1SDimitry Andric 1590fca6ea1SDimitry Andric // Streams 1600fca6ea1SDimitry Andric INTERCEPTOR(int, puts, const char *s) { 1610fca6ea1SDimitry Andric ExpectNotRealtime("puts"); 1620fca6ea1SDimitry Andric return REAL(puts)(s); 1630fca6ea1SDimitry Andric } 1640fca6ea1SDimitry Andric 1650fca6ea1SDimitry Andric // Concurrency 1660fca6ea1SDimitry Andric #if SANITIZER_APPLE 1670fca6ea1SDimitry Andric #pragma clang diagnostic push 1680fca6ea1SDimitry Andric // OSSpinLockLock is deprecated, but still in use in libc++ 1690fca6ea1SDimitry Andric #pragma clang diagnostic ignored "-Wdeprecated-declarations" 1700fca6ea1SDimitry Andric INTERCEPTOR(void, OSSpinLockLock, volatile OSSpinLock *lock) { 1710fca6ea1SDimitry Andric ExpectNotRealtime("OSSpinLockLock"); 1720fca6ea1SDimitry Andric return REAL(OSSpinLockLock)(lock); 1730fca6ea1SDimitry Andric } 1740fca6ea1SDimitry Andric #pragma clang diagnostic pop 1750fca6ea1SDimitry Andric 1760fca6ea1SDimitry Andric INTERCEPTOR(void, os_unfair_lock_lock, os_unfair_lock_t lock) { 1770fca6ea1SDimitry Andric ExpectNotRealtime("os_unfair_lock_lock"); 1780fca6ea1SDimitry Andric return REAL(os_unfair_lock_lock)(lock); 1790fca6ea1SDimitry Andric } 1800fca6ea1SDimitry Andric #elif SANITIZER_LINUX 1810fca6ea1SDimitry Andric INTERCEPTOR(int, pthread_spin_lock, pthread_spinlock_t *spinlock) { 1820fca6ea1SDimitry Andric ExpectNotRealtime("pthread_spin_lock"); 1830fca6ea1SDimitry Andric return REAL(pthread_spin_lock)(spinlock); 1840fca6ea1SDimitry Andric } 1850fca6ea1SDimitry Andric #endif 1860fca6ea1SDimitry Andric 1870fca6ea1SDimitry Andric INTERCEPTOR(int, pthread_create, pthread_t *thread, const pthread_attr_t *attr, 1880fca6ea1SDimitry Andric void *(*start_routine)(void *), void *arg) { 1890fca6ea1SDimitry Andric ExpectNotRealtime("pthread_create"); 1900fca6ea1SDimitry Andric return REAL(pthread_create)(thread, attr, start_routine, arg); 1910fca6ea1SDimitry Andric } 1920fca6ea1SDimitry Andric 1930fca6ea1SDimitry Andric INTERCEPTOR(int, pthread_mutex_lock, pthread_mutex_t *mutex) { 1940fca6ea1SDimitry Andric ExpectNotRealtime("pthread_mutex_lock"); 1950fca6ea1SDimitry Andric return REAL(pthread_mutex_lock)(mutex); 1960fca6ea1SDimitry Andric } 1970fca6ea1SDimitry Andric 1980fca6ea1SDimitry Andric INTERCEPTOR(int, pthread_mutex_unlock, pthread_mutex_t *mutex) { 1990fca6ea1SDimitry Andric ExpectNotRealtime("pthread_mutex_unlock"); 2000fca6ea1SDimitry Andric return REAL(pthread_mutex_unlock)(mutex); 2010fca6ea1SDimitry Andric } 2020fca6ea1SDimitry Andric 2030fca6ea1SDimitry Andric INTERCEPTOR(int, pthread_join, pthread_t thread, void **value_ptr) { 2040fca6ea1SDimitry Andric ExpectNotRealtime("pthread_join"); 2050fca6ea1SDimitry Andric return REAL(pthread_join)(thread, value_ptr); 2060fca6ea1SDimitry Andric } 2070fca6ea1SDimitry Andric 2080fca6ea1SDimitry Andric INTERCEPTOR(int, pthread_cond_signal, pthread_cond_t *cond) { 2090fca6ea1SDimitry Andric ExpectNotRealtime("pthread_cond_signal"); 2100fca6ea1SDimitry Andric return REAL(pthread_cond_signal)(cond); 2110fca6ea1SDimitry Andric } 2120fca6ea1SDimitry Andric 2130fca6ea1SDimitry Andric INTERCEPTOR(int, pthread_cond_broadcast, pthread_cond_t *cond) { 2140fca6ea1SDimitry Andric ExpectNotRealtime("pthread_cond_broadcast"); 2150fca6ea1SDimitry Andric return REAL(pthread_cond_broadcast)(cond); 2160fca6ea1SDimitry Andric } 2170fca6ea1SDimitry Andric 2180fca6ea1SDimitry Andric INTERCEPTOR(int, pthread_cond_wait, pthread_cond_t *cond, 2190fca6ea1SDimitry Andric pthread_mutex_t *mutex) { 2200fca6ea1SDimitry Andric ExpectNotRealtime("pthread_cond_wait"); 2210fca6ea1SDimitry Andric return REAL(pthread_cond_wait)(cond, mutex); 2220fca6ea1SDimitry Andric } 2230fca6ea1SDimitry Andric 2240fca6ea1SDimitry Andric INTERCEPTOR(int, pthread_cond_timedwait, pthread_cond_t *cond, 2250fca6ea1SDimitry Andric pthread_mutex_t *mutex, const timespec *ts) { 2260fca6ea1SDimitry Andric ExpectNotRealtime("pthread_cond_timedwait"); 2270fca6ea1SDimitry Andric return REAL(pthread_cond_timedwait)(cond, mutex, ts); 2280fca6ea1SDimitry Andric } 2290fca6ea1SDimitry Andric 2300fca6ea1SDimitry Andric INTERCEPTOR(int, pthread_rwlock_rdlock, pthread_rwlock_t *lock) { 2310fca6ea1SDimitry Andric ExpectNotRealtime("pthread_rwlock_rdlock"); 2320fca6ea1SDimitry Andric return REAL(pthread_rwlock_rdlock)(lock); 2330fca6ea1SDimitry Andric } 2340fca6ea1SDimitry Andric 2350fca6ea1SDimitry Andric INTERCEPTOR(int, pthread_rwlock_unlock, pthread_rwlock_t *lock) { 2360fca6ea1SDimitry Andric ExpectNotRealtime("pthread_rwlock_unlock"); 2370fca6ea1SDimitry Andric return REAL(pthread_rwlock_unlock)(lock); 2380fca6ea1SDimitry Andric } 2390fca6ea1SDimitry Andric 2400fca6ea1SDimitry Andric INTERCEPTOR(int, pthread_rwlock_wrlock, pthread_rwlock_t *lock) { 2410fca6ea1SDimitry Andric ExpectNotRealtime("pthread_rwlock_wrlock"); 2420fca6ea1SDimitry Andric return REAL(pthread_rwlock_wrlock)(lock); 2430fca6ea1SDimitry Andric } 2440fca6ea1SDimitry Andric 2450fca6ea1SDimitry Andric // Sleeping 2460fca6ea1SDimitry Andric 2470fca6ea1SDimitry Andric INTERCEPTOR(unsigned int, sleep, unsigned int s) { 2480fca6ea1SDimitry Andric ExpectNotRealtime("sleep"); 2490fca6ea1SDimitry Andric return REAL(sleep)(s); 2500fca6ea1SDimitry Andric } 2510fca6ea1SDimitry Andric 2520fca6ea1SDimitry Andric INTERCEPTOR(int, usleep, useconds_t u) { 2530fca6ea1SDimitry Andric ExpectNotRealtime("usleep"); 2540fca6ea1SDimitry Andric return REAL(usleep)(u); 2550fca6ea1SDimitry Andric } 2560fca6ea1SDimitry Andric 2570fca6ea1SDimitry Andric INTERCEPTOR(int, nanosleep, const struct timespec *rqtp, 2580fca6ea1SDimitry Andric struct timespec *rmtp) { 2590fca6ea1SDimitry Andric ExpectNotRealtime("nanosleep"); 2600fca6ea1SDimitry Andric return REAL(nanosleep)(rqtp, rmtp); 2610fca6ea1SDimitry Andric } 2620fca6ea1SDimitry Andric 2630fca6ea1SDimitry Andric // Memory 2640fca6ea1SDimitry Andric 2650fca6ea1SDimitry Andric INTERCEPTOR(void *, calloc, SIZE_T num, SIZE_T size) { 2660fca6ea1SDimitry Andric if (DlsymAlloc::Use()) 2670fca6ea1SDimitry Andric return DlsymAlloc::Callocate(num, size); 2680fca6ea1SDimitry Andric 2690fca6ea1SDimitry Andric ExpectNotRealtime("calloc"); 2700fca6ea1SDimitry Andric return REAL(calloc)(num, size); 2710fca6ea1SDimitry Andric } 2720fca6ea1SDimitry Andric 2730fca6ea1SDimitry Andric INTERCEPTOR(void, free, void *ptr) { 2740fca6ea1SDimitry Andric if (DlsymAlloc::PointerIsMine(ptr)) 2750fca6ea1SDimitry Andric return DlsymAlloc::Free(ptr); 2760fca6ea1SDimitry Andric 2770fca6ea1SDimitry Andric if (ptr != NULL) { 2780fca6ea1SDimitry Andric ExpectNotRealtime("free"); 2790fca6ea1SDimitry Andric } 2800fca6ea1SDimitry Andric return REAL(free)(ptr); 2810fca6ea1SDimitry Andric } 2820fca6ea1SDimitry Andric 2830fca6ea1SDimitry Andric INTERCEPTOR(void *, malloc, SIZE_T size) { 2840fca6ea1SDimitry Andric if (DlsymAlloc::Use()) 2850fca6ea1SDimitry Andric return DlsymAlloc::Allocate(size); 2860fca6ea1SDimitry Andric 2870fca6ea1SDimitry Andric ExpectNotRealtime("malloc"); 2880fca6ea1SDimitry Andric return REAL(malloc)(size); 2890fca6ea1SDimitry Andric } 2900fca6ea1SDimitry Andric 2910fca6ea1SDimitry Andric INTERCEPTOR(void *, realloc, void *ptr, SIZE_T size) { 2920fca6ea1SDimitry Andric if (DlsymAlloc::Use() || DlsymAlloc::PointerIsMine(ptr)) 2930fca6ea1SDimitry Andric return DlsymAlloc::Realloc(ptr, size); 2940fca6ea1SDimitry Andric 2950fca6ea1SDimitry Andric ExpectNotRealtime("realloc"); 2960fca6ea1SDimitry Andric return REAL(realloc)(ptr, size); 2970fca6ea1SDimitry Andric } 2980fca6ea1SDimitry Andric 2990fca6ea1SDimitry Andric INTERCEPTOR(void *, reallocf, void *ptr, SIZE_T size) { 3000fca6ea1SDimitry Andric ExpectNotRealtime("reallocf"); 3010fca6ea1SDimitry Andric return REAL(reallocf)(ptr, size); 3020fca6ea1SDimitry Andric } 3030fca6ea1SDimitry Andric 3040fca6ea1SDimitry Andric INTERCEPTOR(void *, valloc, SIZE_T size) { 3050fca6ea1SDimitry Andric ExpectNotRealtime("valloc"); 3060fca6ea1SDimitry Andric return REAL(valloc)(size); 3070fca6ea1SDimitry Andric } 3080fca6ea1SDimitry Andric 3090fca6ea1SDimitry Andric #if SANITIZER_INTERCEPT_ALIGNED_ALLOC 3100fca6ea1SDimitry Andric INTERCEPTOR(void *, aligned_alloc, SIZE_T alignment, SIZE_T size) { 3110fca6ea1SDimitry Andric ExpectNotRealtime("aligned_alloc"); 3120fca6ea1SDimitry Andric return REAL(aligned_alloc)(alignment, size); 3130fca6ea1SDimitry Andric } 3140fca6ea1SDimitry Andric #define RTSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC INTERCEPT_FUNCTION(aligned_alloc) 3150fca6ea1SDimitry Andric #else 3160fca6ea1SDimitry Andric #define RTSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC 3170fca6ea1SDimitry Andric #endif 3180fca6ea1SDimitry Andric 3190fca6ea1SDimitry Andric INTERCEPTOR(int, posix_memalign, void **memptr, size_t alignment, size_t size) { 3200fca6ea1SDimitry Andric ExpectNotRealtime("posix_memalign"); 3210fca6ea1SDimitry Andric return REAL(posix_memalign)(memptr, alignment, size); 3220fca6ea1SDimitry Andric } 3230fca6ea1SDimitry Andric 3240fca6ea1SDimitry Andric #if SANITIZER_INTERCEPT_MEMALIGN 3250fca6ea1SDimitry Andric INTERCEPTOR(void *, memalign, size_t alignment, size_t size) { 3260fca6ea1SDimitry Andric ExpectNotRealtime("memalign"); 3270fca6ea1SDimitry Andric return REAL(memalign)(alignment, size); 3280fca6ea1SDimitry Andric } 3290fca6ea1SDimitry Andric #endif 3300fca6ea1SDimitry Andric 3310fca6ea1SDimitry Andric #if SANITIZER_INTERCEPT_PVALLOC 3320fca6ea1SDimitry Andric INTERCEPTOR(void *, pvalloc, size_t size) { 3330fca6ea1SDimitry Andric ExpectNotRealtime("pvalloc"); 3340fca6ea1SDimitry Andric return REAL(pvalloc)(size); 3350fca6ea1SDimitry Andric } 3360fca6ea1SDimitry Andric #endif 3370fca6ea1SDimitry Andric 3380fca6ea1SDimitry Andric // Sockets 3390fca6ea1SDimitry Andric INTERCEPTOR(int, socket, int domain, int type, int protocol) { 3400fca6ea1SDimitry Andric ExpectNotRealtime("socket"); 3410fca6ea1SDimitry Andric return REAL(socket)(domain, type, protocol); 3420fca6ea1SDimitry Andric } 3430fca6ea1SDimitry Andric 3440fca6ea1SDimitry Andric INTERCEPTOR(ssize_t, send, int sockfd, const void *buf, size_t len, int flags) { 3450fca6ea1SDimitry Andric ExpectNotRealtime("send"); 3460fca6ea1SDimitry Andric return REAL(send)(sockfd, buf, len, flags); 3470fca6ea1SDimitry Andric } 3480fca6ea1SDimitry Andric 3490fca6ea1SDimitry Andric INTERCEPTOR(ssize_t, sendmsg, int socket, const struct msghdr *message, 3500fca6ea1SDimitry Andric int flags) { 3510fca6ea1SDimitry Andric ExpectNotRealtime("sendmsg"); 3520fca6ea1SDimitry Andric return REAL(sendmsg)(socket, message, flags); 3530fca6ea1SDimitry Andric } 3540fca6ea1SDimitry Andric 3550fca6ea1SDimitry Andric INTERCEPTOR(ssize_t, sendto, int socket, const void *buffer, size_t length, 3560fca6ea1SDimitry Andric int flags, const struct sockaddr *dest_addr, socklen_t dest_len) { 3570fca6ea1SDimitry Andric ExpectNotRealtime("sendto"); 3580fca6ea1SDimitry Andric return REAL(sendto)(socket, buffer, length, flags, dest_addr, dest_len); 3590fca6ea1SDimitry Andric } 3600fca6ea1SDimitry Andric 3610fca6ea1SDimitry Andric INTERCEPTOR(ssize_t, recv, int socket, void *buffer, size_t length, int flags) { 3620fca6ea1SDimitry Andric ExpectNotRealtime("recv"); 3630fca6ea1SDimitry Andric return REAL(recv)(socket, buffer, length, flags); 3640fca6ea1SDimitry Andric } 3650fca6ea1SDimitry Andric 3660fca6ea1SDimitry Andric INTERCEPTOR(ssize_t, recvfrom, int socket, void *buffer, size_t length, 3670fca6ea1SDimitry Andric int flags, struct sockaddr *address, socklen_t *address_len) { 3680fca6ea1SDimitry Andric ExpectNotRealtime("recvfrom"); 3690fca6ea1SDimitry Andric return REAL(recvfrom)(socket, buffer, length, flags, address, address_len); 3700fca6ea1SDimitry Andric } 3710fca6ea1SDimitry Andric 3720fca6ea1SDimitry Andric INTERCEPTOR(ssize_t, recvmsg, int socket, struct msghdr *message, int flags) { 3730fca6ea1SDimitry Andric ExpectNotRealtime("recvmsg"); 3740fca6ea1SDimitry Andric return REAL(recvmsg)(socket, message, flags); 3750fca6ea1SDimitry Andric } 3760fca6ea1SDimitry Andric 3770fca6ea1SDimitry Andric INTERCEPTOR(int, shutdown, int socket, int how) { 3780fca6ea1SDimitry Andric ExpectNotRealtime("shutdown"); 3790fca6ea1SDimitry Andric return REAL(shutdown)(socket, how); 3800fca6ea1SDimitry Andric } 3810fca6ea1SDimitry Andric 3820fca6ea1SDimitry Andric // Preinit 3830fca6ea1SDimitry Andric void __rtsan::InitializeInterceptors() { 3840fca6ea1SDimitry Andric INTERCEPT_FUNCTION(calloc); 3850fca6ea1SDimitry Andric INTERCEPT_FUNCTION(free); 3860fca6ea1SDimitry Andric INTERCEPT_FUNCTION(malloc); 3870fca6ea1SDimitry Andric INTERCEPT_FUNCTION(realloc); 3880fca6ea1SDimitry Andric INTERCEPT_FUNCTION(reallocf); 3890fca6ea1SDimitry Andric INTERCEPT_FUNCTION(valloc); 3900fca6ea1SDimitry Andric RTSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC; 3910fca6ea1SDimitry Andric INTERCEPT_FUNCTION(posix_memalign); 3920fca6ea1SDimitry Andric #if SANITIZER_INTERCEPT_MEMALIGN 3930fca6ea1SDimitry Andric INTERCEPT_FUNCTION(memalign); 3940fca6ea1SDimitry Andric #endif 3950fca6ea1SDimitry Andric #if SANITIZER_INTERCEPT_PVALLOC 3960fca6ea1SDimitry Andric INTERCEPT_FUNCTION(pvalloc); 3970fca6ea1SDimitry Andric #endif 3980fca6ea1SDimitry Andric 3990fca6ea1SDimitry Andric INTERCEPT_FUNCTION(open); 4000fca6ea1SDimitry Andric INTERCEPT_FUNCTION(openat); 4010fca6ea1SDimitry Andric INTERCEPT_FUNCTION(close); 4020fca6ea1SDimitry Andric INTERCEPT_FUNCTION(fopen); 4030fca6ea1SDimitry Andric INTERCEPT_FUNCTION(fread); 4040fca6ea1SDimitry Andric INTERCEPT_FUNCTION(fwrite); 4050fca6ea1SDimitry Andric INTERCEPT_FUNCTION(fclose); 4060fca6ea1SDimitry Andric INTERCEPT_FUNCTION(fcntl); 4070fca6ea1SDimitry Andric INTERCEPT_FUNCTION(creat); 4080fca6ea1SDimitry Andric INTERCEPT_FUNCTION(puts); 4090fca6ea1SDimitry Andric INTERCEPT_FUNCTION(fputs); 4100fca6ea1SDimitry Andric 4110fca6ea1SDimitry Andric #if SANITIZER_APPLE 4120fca6ea1SDimitry Andric INTERCEPT_FUNCTION(OSSpinLockLock); 4130fca6ea1SDimitry Andric INTERCEPT_FUNCTION(os_unfair_lock_lock); 4140fca6ea1SDimitry Andric #elif SANITIZER_LINUX 4150fca6ea1SDimitry Andric INTERCEPT_FUNCTION(pthread_spin_lock); 4160fca6ea1SDimitry Andric #endif 4170fca6ea1SDimitry Andric 4180fca6ea1SDimitry Andric INTERCEPT_FUNCTION(pthread_create); 4190fca6ea1SDimitry Andric INTERCEPT_FUNCTION(pthread_mutex_lock); 4200fca6ea1SDimitry Andric INTERCEPT_FUNCTION(pthread_mutex_unlock); 4210fca6ea1SDimitry Andric INTERCEPT_FUNCTION(pthread_join); 4220fca6ea1SDimitry Andric INTERCEPT_FUNCTION(pthread_cond_signal); 4230fca6ea1SDimitry Andric INTERCEPT_FUNCTION(pthread_cond_broadcast); 4240fca6ea1SDimitry Andric INTERCEPT_FUNCTION(pthread_cond_wait); 4250fca6ea1SDimitry Andric INTERCEPT_FUNCTION(pthread_cond_timedwait); 4260fca6ea1SDimitry Andric INTERCEPT_FUNCTION(pthread_rwlock_rdlock); 4270fca6ea1SDimitry Andric INTERCEPT_FUNCTION(pthread_rwlock_unlock); 4280fca6ea1SDimitry Andric INTERCEPT_FUNCTION(pthread_rwlock_wrlock); 4290fca6ea1SDimitry Andric 4300fca6ea1SDimitry Andric INTERCEPT_FUNCTION(sleep); 4310fca6ea1SDimitry Andric INTERCEPT_FUNCTION(usleep); 4320fca6ea1SDimitry Andric INTERCEPT_FUNCTION(nanosleep); 4330fca6ea1SDimitry Andric 4340fca6ea1SDimitry Andric INTERCEPT_FUNCTION(socket); 4350fca6ea1SDimitry Andric INTERCEPT_FUNCTION(send); 4360fca6ea1SDimitry Andric INTERCEPT_FUNCTION(sendmsg); 4370fca6ea1SDimitry Andric INTERCEPT_FUNCTION(sendto); 4380fca6ea1SDimitry Andric INTERCEPT_FUNCTION(recv); 4390fca6ea1SDimitry Andric INTERCEPT_FUNCTION(recvmsg); 4400fca6ea1SDimitry Andric INTERCEPT_FUNCTION(recvfrom); 4410fca6ea1SDimitry Andric INTERCEPT_FUNCTION(shutdown); 4420fca6ea1SDimitry Andric } 443