xref: /freebsd-src/contrib/llvm-project/compiler-rt/lib/rtsan/rtsan_interceptors.cpp (revision 52418fc2be8efa5172b90a3a9e617017173612c4)
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