xref: /llvm-project/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp (revision 23763a1200edfe209d1e334d1d1ff71b2a992b3a)
1 //===--- rtsan_interceptors.cpp - Realtime Sanitizer ------------*- 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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 //===----------------------------------------------------------------------===//
10 
11 #include "sanitizer_common/sanitizer_platform.h"
12 #if SANITIZER_POSIX
13 
14 #include "rtsan/rtsan_interceptors.h"
15 
16 #include "interception/interception.h"
17 #include "sanitizer_common/sanitizer_allocator_dlsym.h"
18 #include "sanitizer_common/sanitizer_platform_interceptors.h"
19 
20 #include "interception/interception.h"
21 #include "rtsan/rtsan.h"
22 
23 #if SANITIZER_APPLE
24 
25 #if TARGET_OS_MAC
26 // On MacOS OSSpinLockLock is deprecated and no longer present in the headers,
27 // but the symbol still exists on the system. Forward declare here so we
28 // don't get compilation errors.
29 #include <stdint.h>
30 extern "C" {
31 typedef int32_t OSSpinLock;
32 void OSSpinLockLock(volatile OSSpinLock *__lock);
33 }
34 #endif // TARGET_OS_MAC
35 
36 #include <libkern/OSAtomic.h>
37 #include <os/lock.h>
38 #endif // SANITIZER_APPLE
39 
40 #if SANITIZER_INTERCEPT_MEMALIGN || SANITIZER_INTERCEPT_PVALLOC
41 #include <malloc.h>
42 #endif
43 
44 #include <fcntl.h>
45 #include <poll.h>
46 #include <pthread.h>
47 #include <stdarg.h>
48 #include <stdio.h>
49 #if SANITIZER_LINUX
50 #include <linux/mman.h>
51 #include <sys/inotify.h>
52 #endif
53 #include <sys/select.h>
54 #include <sys/socket.h>
55 #include <sys/stat.h>
56 #include <time.h>
57 #include <unistd.h>
58 
59 using namespace __sanitizer;
60 
61 namespace {
62 struct DlsymAlloc : public DlSymAllocator<DlsymAlloc> {
63   static bool UseImpl() { return !__rtsan_is_initialized(); }
64 };
65 } // namespace
66 
67 // Filesystem
68 
69 INTERCEPTOR(int, open, const char *path, int oflag, ...) {
70   // We do not early exit if O_NONBLOCK is set.
71   // O_NONBLOCK **does not prevent the syscall** it simply sets the FD to be in
72   // nonblocking mode, which is a different concept than our
73   // [[clang::nonblocking]], and is not rt-safe. This behavior was confirmed
74   // using Instruments on Darwin with a simple test program
75   __rtsan_notify_intercepted_call("open");
76 
77   if (OpenReadsVaArgs(oflag)) {
78     va_list args;
79     va_start(args, oflag);
80     const mode_t mode = va_arg(args, int);
81     va_end(args);
82     return REAL(open)(path, oflag, mode);
83   }
84 
85   return REAL(open)(path, oflag);
86 }
87 
88 #if SANITIZER_INTERCEPT_OPEN64
89 INTERCEPTOR(int, open64, const char *path, int oflag, ...) {
90   // See comment above about O_NONBLOCK
91   __rtsan_notify_intercepted_call("open64");
92 
93   if (OpenReadsVaArgs(oflag)) {
94     va_list args;
95     va_start(args, oflag);
96     const mode_t mode = va_arg(args, int);
97     va_end(args);
98     return REAL(open64)(path, oflag, mode);
99   }
100 
101   return REAL(open64)(path, oflag);
102 }
103 #define RTSAN_MAYBE_INTERCEPT_OPEN64 INTERCEPT_FUNCTION(open64)
104 #else
105 #define RTSAN_MAYBE_INTERCEPT_OPEN64
106 #endif // SANITIZER_INTERCEPT_OPEN64
107 
108 INTERCEPTOR(int, openat, int fd, const char *path, int oflag, ...) {
109   // See comment above about O_NONBLOCK
110   __rtsan_notify_intercepted_call("openat");
111 
112   if (OpenReadsVaArgs(oflag)) {
113     va_list args;
114     va_start(args, oflag);
115     const mode_t mode = va_arg(args, int);
116     va_end(args);
117     return REAL(openat)(fd, path, oflag, mode);
118   }
119 
120   return REAL(openat)(fd, path, oflag);
121 }
122 
123 #if SANITIZER_INTERCEPT_OPENAT64
124 INTERCEPTOR(int, openat64, int fd, const char *path, int oflag, ...) {
125   // See comment above about O_NONBLOCK
126   __rtsan_notify_intercepted_call("openat64");
127 
128   if (OpenReadsVaArgs(oflag)) {
129     va_list args;
130     va_start(args, oflag);
131     const mode_t mode = va_arg(args, int);
132     va_end(args);
133     return REAL(openat64)(fd, path, oflag, mode);
134   }
135 
136   return REAL(openat64)(fd, path, oflag);
137 }
138 #define RTSAN_MAYBE_INTERCEPT_OPENAT64 INTERCEPT_FUNCTION(openat64)
139 #else
140 #define RTSAN_MAYBE_INTERCEPT_OPENAT64
141 #endif // SANITIZER_INTERCEPT_OPENAT64
142 
143 INTERCEPTOR(int, creat, const char *path, mode_t mode) {
144   // See comment above about O_NONBLOCK
145   __rtsan_notify_intercepted_call("creat");
146   const int result = REAL(creat)(path, mode);
147   return result;
148 }
149 
150 #if SANITIZER_INTERCEPT_CREAT64
151 INTERCEPTOR(int, creat64, const char *path, mode_t mode) {
152   // See comment above about O_NONBLOCK
153   __rtsan_notify_intercepted_call("creat64");
154   const int result = REAL(creat64)(path, mode);
155   return result;
156 }
157 #define RTSAN_MAYBE_INTERCEPT_CREAT64 INTERCEPT_FUNCTION(creat64)
158 #else
159 #define RTSAN_MAYBE_INTERCEPT_CREAT64
160 #endif // SANITIZER_INTERCEPT_CREAT64
161 
162 INTERCEPTOR(int, fcntl, int filedes, int cmd, ...) {
163   __rtsan_notify_intercepted_call("fcntl");
164 
165   // Following precedent here. The linux source (fcntl.c, do_fcntl) accepts the
166   // final argument in a variable that will hold the largest of the possible
167   // argument types. It is then assumed that the implementation of fcntl will
168   // cast it properly depending on cmd.
169   //
170   // The two types we expect for possible args are `struct flock*` and `int`
171   // we will cast to `intptr_t` which should hold both comfortably.
172   // Why `intptr_t`? It should fit both types, and it follows the freeBSD
173   // approach linked below.
174   using arg_type = intptr_t;
175   static_assert(sizeof(arg_type) >= sizeof(struct flock *));
176   static_assert(sizeof(arg_type) >= sizeof(int));
177 
178   // Some cmds will not actually have an argument passed in this va_list.
179   // Calling va_arg when no arg exists is UB, however all currently
180   // supported architectures will give us a result in all three cases
181   // (no arg/int arg/struct flock* arg)
182   // va_arg() will generally read the next argument register or the
183   // stack. If we ever support an arch like CHERI with bounds checking, we
184   // may have to re-evaluate this approach.
185   //
186   // More discussion, and other examples following this approach
187   // https://discourse.llvm.org/t/how-to-write-an-interceptor-for-fcntl/81203
188   // https://reviews.freebsd.org/D46403
189   // https://github.com/bminor/glibc/blob/c444cc1d8335243c5c4e636d6a26c472df85522c/sysdeps/unix/sysv/linux/fcntl64.c#L37-L46
190 
191   va_list args;
192   va_start(args, cmd);
193   const arg_type arg = va_arg(args, arg_type);
194   va_end(args);
195 
196   return REAL(fcntl)(filedes, cmd, arg);
197 }
198 
199 INTERCEPTOR(int, ioctl, int filedes, unsigned long request, ...) {
200   __rtsan_notify_intercepted_call("ioctl");
201 
202   // See fcntl for discussion on why we use intptr_t
203   // And why we read from va_args on all request types
204   using arg_type = intptr_t;
205   static_assert(sizeof(arg_type) >= sizeof(struct ifreq *));
206   static_assert(sizeof(arg_type) >= sizeof(int));
207 
208   va_list args;
209   va_start(args, request);
210   arg_type arg = va_arg(args, arg_type);
211   va_end(args);
212 
213   return REAL(ioctl)(filedes, request, arg);
214 }
215 
216 #if SANITIZER_INTERCEPT_FCNTL64
217 INTERCEPTOR(int, fcntl64, int filedes, int cmd, ...) {
218   __rtsan_notify_intercepted_call("fcntl64");
219 
220   va_list args;
221   va_start(args, cmd);
222 
223   // Following precedent here. The linux source (fcntl.c, do_fcntl) accepts the
224   // final argument in a variable that will hold the largest of the possible
225   // argument types (pointers and ints are typical in fcntl) It is then assumed
226   // that the implementation of fcntl will cast it properly depending on cmd.
227   //
228   // This is also similar to what is done in
229   // sanitizer_common/sanitizer_common_syscalls.inc
230   const unsigned long arg = va_arg(args, unsigned long);
231   int result = REAL(fcntl64)(filedes, cmd, arg);
232 
233   va_end(args);
234 
235   return result;
236 }
237 #define RTSAN_MAYBE_INTERCEPT_FCNTL64 INTERCEPT_FUNCTION(fcntl64)
238 #else
239 #define RTSAN_MAYBE_INTERCEPT_FCNTL64
240 #endif // SANITIZER_INTERCEPT_FCNTL64
241 
242 INTERCEPTOR(int, close, int filedes) {
243   __rtsan_notify_intercepted_call("close");
244   return REAL(close)(filedes);
245 }
246 
247 INTERCEPTOR(FILE *, fopen, const char *path, const char *mode) {
248   __rtsan_notify_intercepted_call("fopen");
249   return REAL(fopen)(path, mode);
250 }
251 
252 INTERCEPTOR(FILE *, freopen, const char *path, const char *mode, FILE *stream) {
253   __rtsan_notify_intercepted_call("freopen");
254   return REAL(freopen)(path, mode, stream);
255 }
256 
257 // Streams
258 
259 #if SANITIZER_INTERCEPT_FOPEN64
260 INTERCEPTOR(FILE *, fopen64, const char *path, const char *mode) {
261   __rtsan_notify_intercepted_call("fopen64");
262   return REAL(fopen64)(path, mode);
263 }
264 
265 INTERCEPTOR(FILE *, freopen64, const char *path, const char *mode,
266             FILE *stream) {
267   __rtsan_notify_intercepted_call("freopen64");
268   return REAL(freopen64)(path, mode, stream);
269 }
270 #define RTSAN_MAYBE_INTERCEPT_FOPEN64 INTERCEPT_FUNCTION(fopen64);
271 #define RTSAN_MAYBE_INTERCEPT_FREOPEN64 INTERCEPT_FUNCTION(freopen64);
272 #else
273 #define RTSAN_MAYBE_INTERCEPT_FOPEN64
274 #define RTSAN_MAYBE_INTERCEPT_FREOPEN64
275 #endif // SANITIZER_INTERCEPT_FOPEN64
276 
277 INTERCEPTOR(size_t, fread, void *ptr, size_t size, size_t nitems,
278             FILE *stream) {
279   __rtsan_notify_intercepted_call("fread");
280   return REAL(fread)(ptr, size, nitems, stream);
281 }
282 
283 INTERCEPTOR(size_t, fwrite, const void *ptr, size_t size, size_t nitems,
284             FILE *stream) {
285   __rtsan_notify_intercepted_call("fwrite");
286   return REAL(fwrite)(ptr, size, nitems, stream);
287 }
288 
289 INTERCEPTOR(int, fclose, FILE *stream) {
290   __rtsan_notify_intercepted_call("fclose");
291   return REAL(fclose)(stream);
292 }
293 
294 INTERCEPTOR(int, fputs, const char *s, FILE *stream) {
295   __rtsan_notify_intercepted_call("fputs");
296   return REAL(fputs)(s, stream);
297 }
298 
299 INTERCEPTOR(int, fflush, FILE *stream) {
300   __rtsan_notify_intercepted_call("fflush");
301   return REAL(fflush)(stream);
302 }
303 
304 #if SANITIZER_APPLE
305 INTERCEPTOR(int, fpurge, FILE *stream) {
306   __rtsan_notify_intercepted_call("fpurge");
307   return REAL(fpurge)(stream);
308 }
309 #define RTSAN_MAYBE_INTERCEPT_FPURGE INTERCEPT_FUNCTION(fpurge)
310 #else
311 #define RTSAN_MAYBE_INTERCEPT_FPURGE
312 #endif
313 
314 INTERCEPTOR(FILE *, fdopen, int fd, const char *mode) {
315   __rtsan_notify_intercepted_call("fdopen");
316   return REAL(fdopen)(fd, mode);
317 }
318 
319 #if SANITIZER_INTERCEPT_FOPENCOOKIE
320 INTERCEPTOR(FILE *, fopencookie, void *cookie, const char *mode,
321             cookie_io_functions_t funcs) {
322   __rtsan_notify_intercepted_call("fopencookie");
323   return REAL(fopencookie)(cookie, mode, funcs);
324 }
325 #define RTSAN_MAYBE_INTERCEPT_FOPENCOOKIE INTERCEPT_FUNCTION(fopencookie)
326 #else
327 #define RTSAN_MAYBE_INTERCEPT_FOPENCOOKIE
328 #endif
329 
330 #if SANITIZER_INTERCEPT_OPEN_MEMSTREAM
331 INTERCEPTOR(FILE *, open_memstream, char **buf, size_t *size) {
332   __rtsan_notify_intercepted_call("open_memstream");
333   return REAL(open_memstream)(buf, size);
334 }
335 
336 INTERCEPTOR(FILE *, fmemopen, void *buf, size_t size, const char *mode) {
337   __rtsan_notify_intercepted_call("fmemopen");
338   return REAL(fmemopen)(buf, size, mode);
339 }
340 #define RTSAN_MAYBE_INTERCEPT_OPEN_MEMSTREAM INTERCEPT_FUNCTION(open_memstream)
341 #define RTSAN_MAYBE_INTERCEPT_FMEMOPEN INTERCEPT_FUNCTION(fmemopen)
342 #else
343 #define RTSAN_MAYBE_INTERCEPT_OPEN_MEMSTREAM
344 #define RTSAN_MAYBE_INTERCEPT_FMEMOPEN
345 #endif
346 
347 #if SANITIZER_INTERCEPT_SETVBUF
348 INTERCEPTOR(void, setbuf, FILE *stream, char *buf) {
349   __rtsan_notify_intercepted_call("setbuf");
350   return REAL(setbuf)(stream, buf);
351 }
352 
353 INTERCEPTOR(int, setvbuf, FILE *stream, char *buf, int mode, size_t size) {
354   __rtsan_notify_intercepted_call("setvbuf");
355   return REAL(setvbuf)(stream, buf, mode, size);
356 }
357 
358 #if SANITIZER_LINUX
359 INTERCEPTOR(void, setlinebuf, FILE *stream) {
360 #else
361 INTERCEPTOR(int, setlinebuf, FILE *stream) {
362 #endif
363   __rtsan_notify_intercepted_call("setlinebuf");
364   return REAL(setlinebuf)(stream);
365 }
366 
367 #if SANITIZER_LINUX
368 INTERCEPTOR(void, setbuffer, FILE *stream, char *buf, size_t size) {
369 #else
370 INTERCEPTOR(void, setbuffer, FILE *stream, char *buf, int size) {
371 #endif
372   __rtsan_notify_intercepted_call("setbuffer");
373   return REAL(setbuffer)(stream, buf, size);
374 }
375 #define RTSAN_MAYBE_INTERCEPT_SETBUF INTERCEPT_FUNCTION(setbuf)
376 #define RTSAN_MAYBE_INTERCEPT_SETVBUF INTERCEPT_FUNCTION(setvbuf)
377 #define RTSAN_MAYBE_INTERCEPT_SETLINEBUF INTERCEPT_FUNCTION(setlinebuf)
378 #define RTSAN_MAYBE_INTERCEPT_SETBUFFER INTERCEPT_FUNCTION(setbuffer)
379 #else
380 #define RTSAN_MAYBE_INTERCEPT_SETBUF
381 #define RTSAN_MAYBE_INTERCEPT_SETVBUF
382 #define RTSAN_MAYBE_INTERCEPT_SETLINEBUF
383 #define RTSAN_MAYBE_INTERCEPT_SETBUFFER
384 #endif
385 
386 #if SANITIZER_INTERCEPT_FSEEK
387 INTERCEPTOR(int, fgetpos, FILE *stream, fpos_t *pos) {
388   __rtsan_notify_intercepted_call("fgetpos");
389   return REAL(fgetpos)(stream, pos);
390 }
391 
392 INTERCEPTOR(int, fseek, FILE *stream, long offset, int whence) {
393   __rtsan_notify_intercepted_call("fseek");
394   return REAL(fseek)(stream, offset, whence);
395 }
396 
397 INTERCEPTOR(int, fseeko, FILE *stream, off_t offset, int whence) {
398   __rtsan_notify_intercepted_call("fseeko");
399   return REAL(fseeko)(stream, offset, whence);
400 }
401 
402 INTERCEPTOR(int, fsetpos, FILE *stream, const fpos_t *pos) {
403   __rtsan_notify_intercepted_call("fsetpos");
404   return REAL(fsetpos)(stream, pos);
405 }
406 
407 INTERCEPTOR(long, ftell, FILE *stream) {
408   __rtsan_notify_intercepted_call("ftell");
409   return REAL(ftell)(stream);
410 }
411 
412 INTERCEPTOR(off_t, ftello, FILE *stream) {
413   __rtsan_notify_intercepted_call("ftello");
414   return REAL(ftello)(stream);
415 }
416 
417 #if SANITIZER_LINUX && !SANITIZER_MUSL
418 INTERCEPTOR(int, fgetpos64, FILE *stream, fpos64_t *pos) {
419   __rtsan_notify_intercepted_call("fgetpos64");
420   return REAL(fgetpos64)(stream, pos);
421 }
422 
423 INTERCEPTOR(int, fseeko64, FILE *stream, off64_t offset, int whence) {
424   __rtsan_notify_intercepted_call("fseeko64");
425   return REAL(fseeko64)(stream, offset, whence);
426 }
427 
428 INTERCEPTOR(int, fsetpos64, FILE *stream, const fpos64_t *pos) {
429   __rtsan_notify_intercepted_call("fsetpos64");
430   return REAL(fsetpos64)(stream, pos);
431 }
432 
433 INTERCEPTOR(off64_t, ftello64, FILE *stream) {
434   __rtsan_notify_intercepted_call("ftello64");
435   return REAL(ftello64)(stream);
436 }
437 #endif
438 
439 INTERCEPTOR(void, rewind, FILE *stream) {
440   __rtsan_notify_intercepted_call("rewind");
441   return REAL(rewind)(stream);
442 }
443 #define RTSAN_MAYBE_INTERCEPT_FGETPOS INTERCEPT_FUNCTION(fgetpos)
444 #define RTSAN_MAYBE_INTERCEPT_FSEEK INTERCEPT_FUNCTION(fseek)
445 #define RTSAN_MAYBE_INTERCEPT_FSEEKO INTERCEPT_FUNCTION(fseeko)
446 #define RTSAN_MAYBE_INTERCEPT_FSETPOS INTERCEPT_FUNCTION(fsetpos)
447 #define RTSAN_MAYBE_INTERCEPT_FTELL INTERCEPT_FUNCTION(ftell)
448 #define RTSAN_MAYBE_INTERCEPT_FTELLO INTERCEPT_FUNCTION(ftello)
449 #define RTSAN_MAYBE_INTERCEPT_REWIND INTERCEPT_FUNCTION(rewind)
450 #if SANITIZER_LINUX && !SANITIZER_MUSL
451 #define RTSAN_MAYBE_INTERCEPT_FGETPOS64 INTERCEPT_FUNCTION(fgetpos64)
452 #define RTSAN_MAYBE_INTERCEPT_FSEEKO64 INTERCEPT_FUNCTION(fseeko64)
453 #define RTSAN_MAYBE_INTERCEPT_FSETPOS64 INTERCEPT_FUNCTION(fsetpos64)
454 #define RTSAN_MAYBE_INTERCEPT_FTELLO64 INTERCEPT_FUNCTION(ftello64)
455 #else
456 #define RTSAN_MAYBE_INTERCEPT_FGETPOS64
457 #define RTSAN_MAYBE_INTERCEPT_FSEEKO64
458 #define RTSAN_MAYBE_INTERCEPT_FSETPOS64
459 #define RTSAN_MAYBE_INTERCEPT_FTELLO64
460 #endif
461 #else
462 #define RTSAN_MAYBE_INTERCEPT_FGETPOS
463 #define RTSAN_MAYBE_INTERCEPT_FSEEK
464 #define RTSAN_MAYBE_INTERCEPT_FSEEKO
465 #define RTSAN_MAYBE_INTERCEPT_FSETPOS
466 #define RTSAN_MAYBE_INTERCEPT_FTELL
467 #define RTSAN_MAYBE_INTERCEPT_FTELLO
468 #define RTSAN_MAYBE_INTERCEPT_REWIND
469 #define RTSAN_MAYBE_INTERCEPT_FGETPOS64
470 #define RTSAN_MAYBE_INTERCEPT_FSEEKO64
471 #define RTSAN_MAYBE_INTERCEPT_FSETPOS64
472 #define RTSAN_MAYBE_INTERCEPT_FTELLO64
473 #endif
474 
475 INTERCEPTOR(int, puts, const char *s) {
476   __rtsan_notify_intercepted_call("puts");
477   return REAL(puts)(s);
478 }
479 
480 INTERCEPTOR(ssize_t, read, int fd, void *buf, size_t count) {
481   __rtsan_notify_intercepted_call("read");
482   return REAL(read)(fd, buf, count);
483 }
484 
485 INTERCEPTOR(ssize_t, write, int fd, const void *buf, size_t count) {
486   __rtsan_notify_intercepted_call("write");
487   return REAL(write)(fd, buf, count);
488 }
489 
490 INTERCEPTOR(ssize_t, pread, int fd, void *buf, size_t count, off_t offset) {
491   __rtsan_notify_intercepted_call("pread");
492   return REAL(pread)(fd, buf, count, offset);
493 }
494 
495 #if SANITIZER_INTERCEPT_PREAD64
496 INTERCEPTOR(ssize_t, pread64, int fd, void *buf, size_t count, off_t offset) {
497   __rtsan_notify_intercepted_call("pread64");
498   return REAL(pread64)(fd, buf, count, offset);
499 }
500 #define RTSAN_MAYBE_INTERCEPT_PREAD64 INTERCEPT_FUNCTION(pread64)
501 #else
502 #define RTSAN_MAYBE_INTERCEPT_PREAD64
503 #endif // SANITIZER_INTERCEPT_PREAD64
504 
505 INTERCEPTOR(ssize_t, readv, int fd, const struct iovec *iov, int iovcnt) {
506   __rtsan_notify_intercepted_call("readv");
507   return REAL(readv)(fd, iov, iovcnt);
508 }
509 
510 INTERCEPTOR(ssize_t, pwrite, int fd, const void *buf, size_t count,
511             off_t offset) {
512   __rtsan_notify_intercepted_call("pwrite");
513   return REAL(pwrite)(fd, buf, count, offset);
514 }
515 
516 #if SANITIZER_INTERCEPT_PWRITE64
517 INTERCEPTOR(ssize_t, pwrite64, int fd, const void *buf, size_t count,
518             off_t offset) {
519   __rtsan_notify_intercepted_call("pwrite64");
520   return REAL(pwrite64)(fd, buf, count, offset);
521 }
522 #define RTSAN_MAYBE_INTERCEPT_PWRITE64 INTERCEPT_FUNCTION(pwrite64)
523 #else
524 #define RTSAN_MAYBE_INTERCEPT_PWRITE64
525 #endif // SANITIZER_INTERCEPT_PWRITE64
526 
527 #if SANITIZER_INTERCEPT_PREADV
528 INTERCEPTOR(ssize_t, preadv, int fd, const struct iovec *iov, int count,
529             off_t offset) {
530   __rtsan_notify_intercepted_call("preadv");
531   return REAL(preadv)(fd, iov, count, offset);
532 }
533 #define RTSAN_MAYBE_INTERCEPT_PREADV INTERCEPT_FUNCTION(preadv)
534 #else
535 #define RTSAN_MAYBE_INTERCEPT_PREADV
536 #endif
537 
538 #if SANITIZER_INTERCEPT_PREADV64
539 INTERCEPTOR(ssize_t, preadv64, int fd, const struct iovec *iov, int count,
540             off_t offset) {
541   __rtsan_notify_intercepted_call("preadv64");
542   return REAL(preadv)(fd, iov, count, offset);
543 }
544 #define RTSAN_MAYBE_INTERCEPT_PREADV64 INTERCEPT_FUNCTION(preadv64)
545 #else
546 #define RTSAN_MAYBE_INTERCEPT_PREADV64
547 #endif
548 
549 #if SANITIZER_INTERCEPT_PWRITEV
550 INTERCEPTOR(ssize_t, pwritev, int fd, const struct iovec *iov, int count,
551             off_t offset) {
552   __rtsan_notify_intercepted_call("pwritev");
553   return REAL(pwritev)(fd, iov, count, offset);
554 }
555 #define RTSAN_MAYBE_INTERCEPT_PWRITEV INTERCEPT_FUNCTION(pwritev)
556 #else
557 #define RTSAN_MAYBE_INTERCEPT_PWRITEV
558 #endif
559 
560 #if SANITIZER_INTERCEPT_PWRITEV64
561 INTERCEPTOR(ssize_t, pwritev64, int fd, const struct iovec *iov, int count,
562             off_t offset) {
563   __rtsan_notify_intercepted_call("pwritev64");
564   return REAL(pwritev64)(fd, iov, count, offset);
565 }
566 #define RTSAN_MAYBE_INTERCEPT_PWRITEV64 INTERCEPT_FUNCTION(pwritev64)
567 #else
568 #define RTSAN_MAYBE_INTERCEPT_PWRITEV64
569 #endif
570 
571 INTERCEPTOR(ssize_t, writev, int fd, const struct iovec *iov, int iovcnt) {
572   __rtsan_notify_intercepted_call("writev");
573   return REAL(writev)(fd, iov, iovcnt);
574 }
575 
576 INTERCEPTOR(off_t, lseek, int fd, off_t offset, int whence) {
577   __rtsan_notify_intercepted_call("lseek");
578   return REAL(lseek)(fd, offset, whence);
579 }
580 
581 #if SANITIZER_INTERCEPT_LSEEK64
582 INTERCEPTOR(off64_t, lseek64, int fd, off64_t offset, int whence) {
583   __rtsan_notify_intercepted_call("lseek64");
584   return REAL(lseek64)(fd, offset, whence);
585 }
586 #define RTSAN_MAYBE_INTERCEPT_LSEEK64 INTERCEPT_FUNCTION(lseek64)
587 #else
588 #define RTSAN_MAYBE_INTERCEPT_LSEEK64
589 #endif // SANITIZER_INTERCEPT_LSEEK64
590 
591 INTERCEPTOR(int, dup, int oldfd) {
592   __rtsan_notify_intercepted_call("dup");
593   return REAL(dup)(oldfd);
594 }
595 
596 INTERCEPTOR(int, dup2, int oldfd, int newfd) {
597   __rtsan_notify_intercepted_call("dup2");
598   return REAL(dup2)(oldfd, newfd);
599 }
600 
601 INTERCEPTOR(int, chmod, const char *path, mode_t mode) {
602   __rtsan_notify_intercepted_call("chmod");
603   return REAL(chmod)(path, mode);
604 }
605 
606 INTERCEPTOR(int, fchmod, int fd, mode_t mode) {
607   __rtsan_notify_intercepted_call("fchmod");
608   return REAL(fchmod)(fd, mode);
609 }
610 
611 INTERCEPTOR(int, mkdir, const char *path, mode_t mode) {
612   __rtsan_notify_intercepted_call("mkdir");
613   return REAL(mkdir)(path, mode);
614 }
615 
616 INTERCEPTOR(int, rmdir, const char *path) {
617   __rtsan_notify_intercepted_call("rmdir");
618   return REAL(rmdir)(path);
619 }
620 
621 INTERCEPTOR(mode_t, umask, mode_t cmask) {
622   __rtsan_notify_intercepted_call("umask");
623   return REAL(umask)(cmask);
624 }
625 
626 // Concurrency
627 #if SANITIZER_APPLE
628 #pragma clang diagnostic push
629 // OSSpinLockLock is deprecated, but still in use in libc++
630 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
631 INTERCEPTOR(void, OSSpinLockLock, volatile OSSpinLock *lock) {
632   __rtsan_notify_intercepted_call("OSSpinLockLock");
633   return REAL(OSSpinLockLock)(lock);
634 }
635 #pragma clang diagnostic pop
636 #define RTSAN_MAYBE_INTERCEPT_OSSPINLOCKLOCK INTERCEPT_FUNCTION(OSSpinLockLock)
637 #else
638 #define RTSAN_MAYBE_INTERCEPT_OSSPINLOCKLOCK
639 #endif // SANITIZER_APPLE
640 
641 #if SANITIZER_APPLE
642 INTERCEPTOR(void, os_unfair_lock_lock, os_unfair_lock_t lock) {
643   __rtsan_notify_intercepted_call("os_unfair_lock_lock");
644   return REAL(os_unfair_lock_lock)(lock);
645 }
646 #define RTSAN_MAYBE_INTERCEPT_OS_UNFAIR_LOCK_LOCK                              \
647   INTERCEPT_FUNCTION(os_unfair_lock_lock)
648 #else
649 #define RTSAN_MAYBE_INTERCEPT_OS_UNFAIR_LOCK_LOCK
650 #endif // SANITIZER_APPLE
651 
652 #if SANITIZER_LINUX
653 INTERCEPTOR(int, pthread_spin_lock, pthread_spinlock_t *spinlock) {
654   __rtsan_notify_intercepted_call("pthread_spin_lock");
655   return REAL(pthread_spin_lock)(spinlock);
656 }
657 #define RTSAN_MAYBE_INTERCEPT_PTHREAD_SPIN_LOCK                                \
658   INTERCEPT_FUNCTION(pthread_spin_lock)
659 #else
660 #define RTSAN_MAYBE_INTERCEPT_PTHREAD_SPIN_LOCK
661 #endif // SANITIZER_LINUX
662 
663 INTERCEPTOR(int, pthread_create, pthread_t *thread, const pthread_attr_t *attr,
664             void *(*start_routine)(void *), void *arg) {
665   __rtsan_notify_intercepted_call("pthread_create");
666   return REAL(pthread_create)(thread, attr, start_routine, arg);
667 }
668 
669 INTERCEPTOR(int, pthread_mutex_lock, pthread_mutex_t *mutex) {
670   __rtsan_notify_intercepted_call("pthread_mutex_lock");
671   return REAL(pthread_mutex_lock)(mutex);
672 }
673 
674 INTERCEPTOR(int, pthread_mutex_unlock, pthread_mutex_t *mutex) {
675   __rtsan_notify_intercepted_call("pthread_mutex_unlock");
676   return REAL(pthread_mutex_unlock)(mutex);
677 }
678 
679 INTERCEPTOR(int, pthread_join, pthread_t thread, void **value_ptr) {
680   __rtsan_notify_intercepted_call("pthread_join");
681   return REAL(pthread_join)(thread, value_ptr);
682 }
683 
684 INTERCEPTOR(int, pthread_cond_signal, pthread_cond_t *cond) {
685   __rtsan_notify_intercepted_call("pthread_cond_signal");
686   return REAL(pthread_cond_signal)(cond);
687 }
688 
689 INTERCEPTOR(int, pthread_cond_broadcast, pthread_cond_t *cond) {
690   __rtsan_notify_intercepted_call("pthread_cond_broadcast");
691   return REAL(pthread_cond_broadcast)(cond);
692 }
693 
694 INTERCEPTOR(int, pthread_cond_wait, pthread_cond_t *cond,
695             pthread_mutex_t *mutex) {
696   __rtsan_notify_intercepted_call("pthread_cond_wait");
697   return REAL(pthread_cond_wait)(cond, mutex);
698 }
699 
700 INTERCEPTOR(int, pthread_cond_timedwait, pthread_cond_t *cond,
701             pthread_mutex_t *mutex, const timespec *ts) {
702   __rtsan_notify_intercepted_call("pthread_cond_timedwait");
703   return REAL(pthread_cond_timedwait)(cond, mutex, ts);
704 }
705 
706 INTERCEPTOR(int, pthread_rwlock_rdlock, pthread_rwlock_t *lock) {
707   __rtsan_notify_intercepted_call("pthread_rwlock_rdlock");
708   return REAL(pthread_rwlock_rdlock)(lock);
709 }
710 
711 INTERCEPTOR(int, pthread_rwlock_unlock, pthread_rwlock_t *lock) {
712   __rtsan_notify_intercepted_call("pthread_rwlock_unlock");
713   return REAL(pthread_rwlock_unlock)(lock);
714 }
715 
716 INTERCEPTOR(int, pthread_rwlock_wrlock, pthread_rwlock_t *lock) {
717   __rtsan_notify_intercepted_call("pthread_rwlock_wrlock");
718   return REAL(pthread_rwlock_wrlock)(lock);
719 }
720 
721 // Sleeping
722 
723 INTERCEPTOR(unsigned int, sleep, unsigned int s) {
724   __rtsan_notify_intercepted_call("sleep");
725   return REAL(sleep)(s);
726 }
727 
728 INTERCEPTOR(int, usleep, useconds_t u) {
729   __rtsan_notify_intercepted_call("usleep");
730   return REAL(usleep)(u);
731 }
732 
733 INTERCEPTOR(int, nanosleep, const struct timespec *rqtp,
734             struct timespec *rmtp) {
735   __rtsan_notify_intercepted_call("nanosleep");
736   return REAL(nanosleep)(rqtp, rmtp);
737 }
738 
739 INTERCEPTOR(int, sched_yield, void) {
740   __rtsan_notify_intercepted_call("sched_yield");
741   return REAL(sched_yield)();
742 }
743 
744 #if SANITIZER_LINUX
745 INTERCEPTOR(int, sched_getaffinity, pid_t pid, size_t len, cpu_set_t *set) {
746   __rtsan_notify_intercepted_call("sched_getaffinity");
747   return REAL(sched_getaffinity)(pid, len, set);
748 }
749 
750 INTERCEPTOR(int, sched_setaffinity, pid_t pid, size_t len,
751             const cpu_set_t *set) {
752   __rtsan_notify_intercepted_call("sched_setaffinity");
753   return REAL(sched_setaffinity)(pid, len, set);
754 }
755 #define RTSAN_MAYBE_INTERCEPT_SCHED_GETAFFINITY                                \
756   INTERCEPT_FUNCTION(sched_getaffinity)
757 #define RTSAN_MAYBE_INTERCEPT_SCHED_SETAFFINITY                                \
758   INTERCEPT_FUNCTION(sched_setaffinity)
759 #else
760 #define RTSAN_MAYBE_INTERCEPT_SCHED_GETAFFINITY
761 #define RTSAN_MAYBE_INTERCEPT_SCHED_SETAFFINITY
762 #endif
763 
764 // Memory
765 
766 INTERCEPTOR(void *, calloc, SIZE_T num, SIZE_T size) {
767   if (DlsymAlloc::Use())
768     return DlsymAlloc::Callocate(num, size);
769 
770   __rtsan_notify_intercepted_call("calloc");
771   return REAL(calloc)(num, size);
772 }
773 
774 INTERCEPTOR(void, free, void *ptr) {
775   if (DlsymAlloc::PointerIsMine(ptr))
776     return DlsymAlloc::Free(ptr);
777 
778   // According to the C and C++ standard, freeing a nullptr is guaranteed to be
779   // a no-op (and thus real-time safe). This can be confirmed for looking at
780   // __libc_free in the glibc source.
781   if (ptr != nullptr)
782     __rtsan_notify_intercepted_call("free");
783 
784   return REAL(free)(ptr);
785 }
786 
787 INTERCEPTOR(void *, malloc, SIZE_T size) {
788   if (DlsymAlloc::Use())
789     return DlsymAlloc::Allocate(size);
790 
791   __rtsan_notify_intercepted_call("malloc");
792   return REAL(malloc)(size);
793 }
794 
795 INTERCEPTOR(void *, realloc, void *ptr, SIZE_T size) {
796   if (DlsymAlloc::Use() || DlsymAlloc::PointerIsMine(ptr))
797     return DlsymAlloc::Realloc(ptr, size);
798 
799   __rtsan_notify_intercepted_call("realloc");
800   return REAL(realloc)(ptr, size);
801 }
802 
803 INTERCEPTOR(void *, reallocf, void *ptr, SIZE_T size) {
804   __rtsan_notify_intercepted_call("reallocf");
805   return REAL(reallocf)(ptr, size);
806 }
807 
808 INTERCEPTOR(void *, valloc, SIZE_T size) {
809   __rtsan_notify_intercepted_call("valloc");
810   return REAL(valloc)(size);
811 }
812 
813 #if SANITIZER_INTERCEPT_ALIGNED_ALLOC
814 
815 // In some cases, when targeting older Darwin versions, this warning may pop up.
816 // Because we are providing a wrapper, the client is responsible to check
817 // whether aligned_alloc is available, not us. We still succeed linking on an
818 // old OS, because we are using a weak symbol (see aligned_alloc in
819 // sanitizer_platform_interceptors.h)
820 #pragma clang diagnostic push
821 #pragma clang diagnostic ignored "-Wunguarded-availability-new"
822 INTERCEPTOR(void *, aligned_alloc, SIZE_T alignment, SIZE_T size) {
823   __rtsan_notify_intercepted_call("aligned_alloc");
824   return REAL(aligned_alloc)(alignment, size);
825 }
826 #pragma clang diagnostic pop
827 #define RTSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC INTERCEPT_FUNCTION(aligned_alloc)
828 #else
829 #define RTSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC
830 #endif
831 
832 INTERCEPTOR(int, posix_memalign, void **memptr, size_t alignment, size_t size) {
833   __rtsan_notify_intercepted_call("posix_memalign");
834   return REAL(posix_memalign)(memptr, alignment, size);
835 }
836 
837 #if SANITIZER_INTERCEPT_MEMALIGN
838 INTERCEPTOR(void *, memalign, size_t alignment, size_t size) {
839   __rtsan_notify_intercepted_call("memalign");
840   return REAL(memalign)(alignment, size);
841 }
842 #define RTSAN_MAYBE_INTERCEPT_MEMALIGN INTERCEPT_FUNCTION(memalign)
843 #else
844 #define RTSAN_MAYBE_INTERCEPT_MEMALIGN
845 #endif
846 
847 #if SANITIZER_INTERCEPT_PVALLOC
848 INTERCEPTOR(void *, pvalloc, size_t size) {
849   __rtsan_notify_intercepted_call("pvalloc");
850   return REAL(pvalloc)(size);
851 }
852 #define RTSAN_MAYBE_INTERCEPT_PVALLOC INTERCEPT_FUNCTION(pvalloc)
853 #else
854 #define RTSAN_MAYBE_INTERCEPT_PVALLOC
855 #endif
856 
857 INTERCEPTOR(void *, mmap, void *addr, size_t length, int prot, int flags,
858             int fd, off_t offset) {
859   __rtsan_notify_intercepted_call("mmap");
860   return REAL(mmap)(addr, length, prot, flags, fd, offset);
861 }
862 
863 #if SANITIZER_INTERCEPT_MMAP64
864 INTERCEPTOR(void *, mmap64, void *addr, size_t length, int prot, int flags,
865             int fd, off64_t offset) {
866   __rtsan_notify_intercepted_call("mmap64");
867   return REAL(mmap64)(addr, length, prot, flags, fd, offset);
868 }
869 #define RTSAN_MAYBE_INTERCEPT_MMAP64 INTERCEPT_FUNCTION(mmap64)
870 #else
871 #define RTSAN_MAYBE_INTERCEPT_MMAP64
872 #endif // SANITIZER_INTERCEPT_MMAP64
873 
874 #if SANITIZER_LINUX
875 // Note that even if rtsan is ported to netbsd, it has a slighty different
876 // and non-variadic signature
877 INTERCEPTOR(void *, mremap, void *oaddr, size_t olength, size_t nlength,
878             int flags, ...) {
879   __rtsan_notify_intercepted_call("mremap");
880 
881   // the last optional argument is only used in this case
882   // as the new page region will be assigned to. Is ignored otherwise.
883   if (flags & MREMAP_FIXED) {
884     va_list args;
885 
886     va_start(args, flags);
887     void *naddr = va_arg(args, void *);
888     va_end(args);
889 
890     return REAL(mremap)(oaddr, olength, nlength, flags, naddr);
891   }
892 
893   return REAL(mremap)(oaddr, olength, nlength, flags);
894 }
895 #define RTSAN_MAYBE_INTERCEPT_MREMAP INTERCEPT_FUNCTION(mremap)
896 #else
897 #define RTSAN_MAYBE_INTERCEPT_MREMAP
898 #endif
899 
900 INTERCEPTOR(int, munmap, void *addr, size_t length) {
901   __rtsan_notify_intercepted_call("munmap");
902   return REAL(munmap)(addr, length);
903 }
904 
905 #if !SANITIZER_APPLE
906 INTERCEPTOR(int, madvise, void *addr, size_t length, int flag) {
907   __rtsan_notify_intercepted_call("madvise");
908   return REAL(madvise)(addr, length, flag);
909 }
910 
911 INTERCEPTOR(int, posix_madvise, void *addr, size_t length, int flag) {
912   __rtsan_notify_intercepted_call("posix_madvise");
913   return REAL(posix_madvise)(addr, length, flag);
914 }
915 #define RTSAN_MAYBE_INTERCEPT_MADVISE INTERCEPT_FUNCTION(madvise)
916 #define RTSAN_MAYBE_INTERCEPT_POSIX_MADVISE INTERCEPT_FUNCTION(posix_madvise)
917 #else
918 #define RTSAN_MAYBE_INTERCEPT_MADVISE
919 #define RTSAN_MAYBE_INTERCEPT_POSIX_MADVISE
920 #endif
921 
922 INTERCEPTOR(int, mprotect, void *addr, size_t length, int prot) {
923   __rtsan_notify_intercepted_call("mprotect");
924   return REAL(mprotect)(addr, length, prot);
925 }
926 
927 INTERCEPTOR(int, msync, void *addr, size_t length, int flag) {
928   __rtsan_notify_intercepted_call("msync");
929   return REAL(msync)(addr, length, flag);
930 }
931 
932 #if SANITIZER_APPLE
933 INTERCEPTOR(int, mincore, const void *addr, size_t length, char *vec) {
934 #else
935 INTERCEPTOR(int, mincore, void *addr, size_t length, unsigned char *vec) {
936 #endif
937   __rtsan_notify_intercepted_call("mincore");
938   return REAL(mincore)(addr, length, vec);
939 }
940 
941 INTERCEPTOR(int, shm_open, const char *name, int oflag, mode_t mode) {
942   __rtsan_notify_intercepted_call("shm_open");
943   return REAL(shm_open)(name, oflag, mode);
944 }
945 
946 INTERCEPTOR(int, shm_unlink, const char *name) {
947   __rtsan_notify_intercepted_call("shm_unlink");
948   return REAL(shm_unlink)(name);
949 }
950 
951 // Sockets
952 INTERCEPTOR(int, getaddrinfo, const char *node, const char *service,
953             const struct addrinfo *hints, struct addrinfo **res) {
954   __rtsan_notify_intercepted_call("getaddrinfo");
955   return REAL(getaddrinfo)(node, service, hints, res);
956 }
957 
958 INTERCEPTOR(int, getnameinfo, const struct sockaddr *sa, socklen_t salen,
959             char *host, socklen_t hostlen, char *serv, socklen_t servlen,
960             int flags) {
961   __rtsan_notify_intercepted_call("getnameinfo");
962   return REAL(getnameinfo)(sa, salen, host, hostlen, serv, servlen, flags);
963 }
964 
965 #if SANITIZER_INTERCEPT_GETSOCKNAME
966 INTERCEPTOR(int, getsockname, int socket, struct sockaddr *sa,
967             socklen_t *salen) {
968   __rtsan_notify_intercepted_call("getsockname");
969   return REAL(getsockname)(socket, sa, salen);
970 }
971 #define RTSAN_MAYBE_INTERCEPT_GETSOCKNAME INTERCEPT_FUNCTION(getsockname)
972 #else
973 #define RTSAN_MAYBE_INTERCEPT_GETSOCKNAME
974 #endif
975 
976 #if SANITIZER_INTERCEPT_GETPEERNAME
977 INTERCEPTOR(int, getpeername, int socket, struct sockaddr *sa,
978             socklen_t *salen) {
979   __rtsan_notify_intercepted_call("getpeername");
980   return REAL(getpeername)(socket, sa, salen);
981 }
982 #define RTSAN_MAYBE_INTERCEPT_GETPEERNAME INTERCEPT_FUNCTION(getpeername)
983 #else
984 #define RTSAN_MAYBE_INTERCEPT_GETPEERNAME
985 #endif
986 
987 INTERCEPTOR(int, bind, int socket, const struct sockaddr *address,
988             socklen_t address_len) {
989   __rtsan_notify_intercepted_call("bind");
990   return REAL(bind)(socket, address, address_len);
991 }
992 
993 INTERCEPTOR(int, listen, int socket, int backlog) {
994   __rtsan_notify_intercepted_call("listen");
995   return REAL(listen)(socket, backlog);
996 }
997 
998 INTERCEPTOR(int, accept, int socket, struct sockaddr *address,
999             socklen_t *address_len) {
1000   __rtsan_notify_intercepted_call("accept");
1001   return REAL(accept)(socket, address, address_len);
1002 }
1003 
1004 INTERCEPTOR(int, connect, int socket, const struct sockaddr *address,
1005             socklen_t address_len) {
1006   __rtsan_notify_intercepted_call("connect");
1007   return REAL(connect)(socket, address, address_len);
1008 }
1009 
1010 INTERCEPTOR(int, socket, int domain, int type, int protocol) {
1011   __rtsan_notify_intercepted_call("socket");
1012   return REAL(socket)(domain, type, protocol);
1013 }
1014 
1015 INTERCEPTOR(ssize_t, send, int sockfd, const void *buf, size_t len, int flags) {
1016   __rtsan_notify_intercepted_call("send");
1017   return REAL(send)(sockfd, buf, len, flags);
1018 }
1019 
1020 INTERCEPTOR(ssize_t, sendmsg, int socket, const struct msghdr *message,
1021             int flags) {
1022   __rtsan_notify_intercepted_call("sendmsg");
1023   return REAL(sendmsg)(socket, message, flags);
1024 }
1025 
1026 #if SANITIZER_INTERCEPT_SENDMMSG
1027 #if SANITIZER_MUSL
1028 INTERCEPTOR(int, sendmmsg, int socket, struct mmsghdr *message,
1029             unsigned int len, unsigned int flags) {
1030 #else
1031 INTERCEPTOR(int, sendmmsg, int socket, struct mmsghdr *message,
1032             unsigned int len, int flags) {
1033 #endif
1034   __rtsan_notify_intercepted_call("sendmmsg");
1035   return REAL(sendmmsg)(socket, message, len, flags);
1036 }
1037 #define RTSAN_MAYBE_INTERCEPT_SENDMMSG INTERCEPT_FUNCTION(sendmmsg)
1038 #else
1039 #define RTSAN_MAYBE_INTERCEPT_SENDMMSG
1040 #endif
1041 
1042 INTERCEPTOR(ssize_t, sendto, int socket, const void *buffer, size_t length,
1043             int flags, const struct sockaddr *dest_addr, socklen_t dest_len) {
1044   __rtsan_notify_intercepted_call("sendto");
1045   return REAL(sendto)(socket, buffer, length, flags, dest_addr, dest_len);
1046 }
1047 
1048 INTERCEPTOR(ssize_t, recv, int socket, void *buffer, size_t length, int flags) {
1049   __rtsan_notify_intercepted_call("recv");
1050   return REAL(recv)(socket, buffer, length, flags);
1051 }
1052 
1053 INTERCEPTOR(ssize_t, recvfrom, int socket, void *buffer, size_t length,
1054             int flags, struct sockaddr *address, socklen_t *address_len) {
1055   __rtsan_notify_intercepted_call("recvfrom");
1056   return REAL(recvfrom)(socket, buffer, length, flags, address, address_len);
1057 }
1058 
1059 INTERCEPTOR(ssize_t, recvmsg, int socket, struct msghdr *message, int flags) {
1060   __rtsan_notify_intercepted_call("recvmsg");
1061   return REAL(recvmsg)(socket, message, flags);
1062 }
1063 
1064 #if SANITIZER_INTERCEPT_RECVMMSG
1065 #if SANITIZER_MUSL
1066 INTERCEPTOR(int, recvmmsg, int socket, struct mmsghdr *message,
1067             unsigned int len, unsigned int flags, struct timespec *timeout) {
1068 #elif defined(__GLIBC_MINOR__) && __GLIBC_MINOR__ < 21
1069 INTERCEPTOR(int, recvmmsg, int socket, struct mmsghdr *message,
1070             unsigned int len, int flags, const struct timespec *timeout) {
1071 #else
1072 INTERCEPTOR(int, recvmmsg, int socket, struct mmsghdr *message,
1073             unsigned int len, int flags, struct timespec *timeout) {
1074 #endif // defined(__GLIBC_MINOR) && __GLIBC_MINOR__ < 21
1075   __rtsan_notify_intercepted_call("recvmmsg");
1076   return REAL(recvmmsg)(socket, message, len, flags, timeout);
1077 }
1078 #define RTSAN_MAYBE_INTERCEPT_RECVMMSG INTERCEPT_FUNCTION(recvmmsg)
1079 #else
1080 #define RTSAN_MAYBE_INTERCEPT_RECVMMSG
1081 #endif
1082 
1083 INTERCEPTOR(int, shutdown, int socket, int how) {
1084   __rtsan_notify_intercepted_call("shutdown");
1085   return REAL(shutdown)(socket, how);
1086 }
1087 
1088 #if SANITIZER_INTERCEPT_ACCEPT4
1089 INTERCEPTOR(int, accept4, int socket, struct sockaddr *address,
1090             socklen_t *address_len, int flags) {
1091   __rtsan_notify_intercepted_call("accept4");
1092   return REAL(accept4)(socket, address, address_len, flags);
1093 }
1094 #define RTSAN_MAYBE_INTERCEPT_ACCEPT4 INTERCEPT_FUNCTION(accept4)
1095 #else
1096 #define RTSAN_MAYBE_INTERCEPT_ACCEPT4
1097 #endif
1098 
1099 #if SANITIZER_INTERCEPT_GETSOCKOPT
1100 INTERCEPTOR(int, getsockopt, int socket, int level, int option, void *value,
1101             socklen_t *len) {
1102   __rtsan_notify_intercepted_call("getsockopt");
1103   return REAL(getsockopt)(socket, level, option, value, len);
1104 }
1105 
1106 INTERCEPTOR(int, setsockopt, int socket, int level, int option,
1107             const void *value, socklen_t len) {
1108   __rtsan_notify_intercepted_call("setsockopt");
1109   return REAL(setsockopt)(socket, level, option, value, len);
1110 }
1111 #define RTSAN_MAYBE_INTERCEPT_GETSOCKOPT INTERCEPT_FUNCTION(getsockopt)
1112 #define RTSAN_MAYBE_INTERCEPT_SETSOCKOPT INTERCEPT_FUNCTION(setsockopt)
1113 #else
1114 #define RTSAN_MAYBE_INTERCEPT_GETSOCKOPT
1115 #define RTSAN_MAYBE_INTERCEPT_SETSOCKOPT
1116 #endif
1117 
1118 INTERCEPTOR(int, socketpair, int domain, int type, int protocol, int pair[2]) {
1119   __rtsan_notify_intercepted_call("socketpair");
1120   return REAL(socketpair)(domain, type, protocol, pair);
1121 }
1122 
1123 // I/O Multiplexing
1124 
1125 INTERCEPTOR(int, poll, struct pollfd *fds, nfds_t nfds, int timeout) {
1126   __rtsan_notify_intercepted_call("poll");
1127   return REAL(poll)(fds, nfds, timeout);
1128 }
1129 
1130 #if !SANITIZER_APPLE
1131 // FIXME: This should work on all unix systems, even Mac, but currently
1132 // it is showing some weird error while linking
1133 // error: declaration of 'select' has a different language linkage
1134 INTERCEPTOR(int, select, int nfds, fd_set *readfds, fd_set *writefds,
1135             fd_set *exceptfds, struct timeval *timeout) {
1136   __rtsan_notify_intercepted_call("select");
1137   return REAL(select)(nfds, readfds, writefds, exceptfds, timeout);
1138 }
1139 #define RTSAN_MAYBE_INTERCEPT_SELECT INTERCEPT_FUNCTION(select)
1140 #else
1141 #define RTSAN_MAYBE_INTERCEPT_SELECT
1142 #endif // !SANITIZER_APPLE
1143 
1144 INTERCEPTOR(int, pselect, int nfds, fd_set *readfds, fd_set *writefds,
1145             fd_set *exceptfds, const struct timespec *timeout,
1146             const sigset_t *sigmask) {
1147   __rtsan_notify_intercepted_call("pselect");
1148   return REAL(pselect)(nfds, readfds, writefds, exceptfds, timeout, sigmask);
1149 }
1150 
1151 #if SANITIZER_INTERCEPT_EPOLL
1152 INTERCEPTOR(int, epoll_create, int size) {
1153   __rtsan_notify_intercepted_call("epoll_create");
1154   return REAL(epoll_create)(size);
1155 }
1156 
1157 INTERCEPTOR(int, epoll_create1, int flags) {
1158   __rtsan_notify_intercepted_call("epoll_create1");
1159   return REAL(epoll_create1)(flags);
1160 }
1161 
1162 INTERCEPTOR(int, epoll_ctl, int epfd, int op, int fd,
1163             struct epoll_event *event) {
1164   __rtsan_notify_intercepted_call("epoll_ctl");
1165   return REAL(epoll_ctl)(epfd, op, fd, event);
1166 }
1167 
1168 INTERCEPTOR(int, epoll_wait, int epfd, struct epoll_event *events,
1169             int maxevents, int timeout) {
1170   __rtsan_notify_intercepted_call("epoll_wait");
1171   return REAL(epoll_wait)(epfd, events, maxevents, timeout);
1172 }
1173 
1174 INTERCEPTOR(int, epoll_pwait, int epfd, struct epoll_event *events,
1175             int maxevents, int timeout, const sigset_t *sigmask) {
1176   __rtsan_notify_intercepted_call("epoll_pwait");
1177   return REAL(epoll_pwait)(epfd, events, maxevents, timeout, sigmask);
1178 }
1179 #define RTSAN_MAYBE_INTERCEPT_EPOLL_CREATE INTERCEPT_FUNCTION(epoll_create)
1180 #define RTSAN_MAYBE_INTERCEPT_EPOLL_CREATE1 INTERCEPT_FUNCTION(epoll_create1)
1181 #define RTSAN_MAYBE_INTERCEPT_EPOLL_CTL INTERCEPT_FUNCTION(epoll_ctl)
1182 #define RTSAN_MAYBE_INTERCEPT_EPOLL_WAIT INTERCEPT_FUNCTION(epoll_wait)
1183 #define RTSAN_MAYBE_INTERCEPT_EPOLL_PWAIT INTERCEPT_FUNCTION(epoll_pwait)
1184 #else
1185 #define RTSAN_MAYBE_INTERCEPT_EPOLL_CREATE
1186 #define RTSAN_MAYBE_INTERCEPT_EPOLL_CREATE1
1187 #define RTSAN_MAYBE_INTERCEPT_EPOLL_CTL
1188 #define RTSAN_MAYBE_INTERCEPT_EPOLL_WAIT
1189 #define RTSAN_MAYBE_INTERCEPT_EPOLL_PWAIT
1190 #endif // SANITIZER_INTERCEPT_EPOLL
1191 
1192 #if SANITIZER_INTERCEPT_PPOLL
1193 INTERCEPTOR(int, ppoll, struct pollfd *fds, nfds_t n, const struct timespec *ts,
1194             const sigset_t *set) {
1195   __rtsan_notify_intercepted_call("ppoll");
1196   return REAL(ppoll)(fds, n, ts, set);
1197 }
1198 #define RTSAN_MAYBE_INTERCEPT_PPOLL INTERCEPT_FUNCTION(ppoll)
1199 #else
1200 #define RTSAN_MAYBE_INTERCEPT_PPOLL
1201 #endif
1202 
1203 #if SANITIZER_INTERCEPT_KQUEUE
1204 INTERCEPTOR(int, kqueue, void) {
1205   __rtsan_notify_intercepted_call("kqueue");
1206   return REAL(kqueue)();
1207 }
1208 
1209 INTERCEPTOR(int, kevent, int kq, const struct kevent *changelist, int nchanges,
1210             struct kevent *eventlist, int nevents,
1211             const struct timespec *timeout) {
1212   __rtsan_notify_intercepted_call("kevent");
1213   return REAL(kevent)(kq, changelist, nchanges, eventlist, nevents, timeout);
1214 }
1215 
1216 INTERCEPTOR(int, kevent64, int kq, const struct kevent64_s *changelist,
1217             int nchanges, struct kevent64_s *eventlist, int nevents,
1218             unsigned int flags, const struct timespec *timeout) {
1219   __rtsan_notify_intercepted_call("kevent64");
1220   return REAL(kevent64)(kq, changelist, nchanges, eventlist, nevents, flags,
1221                         timeout);
1222 }
1223 #define RTSAN_MAYBE_INTERCEPT_KQUEUE INTERCEPT_FUNCTION(kqueue)
1224 #define RTSAN_MAYBE_INTERCEPT_KEVENT INTERCEPT_FUNCTION(kevent)
1225 #define RTSAN_MAYBE_INTERCEPT_KEVENT64 INTERCEPT_FUNCTION(kevent64)
1226 #else
1227 #define RTSAN_MAYBE_INTERCEPT_KQUEUE
1228 #define RTSAN_MAYBE_INTERCEPT_KEVENT
1229 #define RTSAN_MAYBE_INTERCEPT_KEVENT64
1230 #endif // SANITIZER_INTERCEPT_KQUEUE
1231 
1232 #if SANITIZER_LINUX
1233 INTERCEPTOR(int, inotify_init) {
1234   __rtsan_notify_intercepted_call("inotify_init");
1235   return REAL(inotify_init)();
1236 }
1237 
1238 INTERCEPTOR(int, inotify_init1, int flags) {
1239   __rtsan_notify_intercepted_call("inotify_init1");
1240   return REAL(inotify_init1)(flags);
1241 }
1242 
1243 INTERCEPTOR(int, inotify_add_watch, int fd, const char *path, uint32_t mask) {
1244   __rtsan_notify_intercepted_call("inotify_add_watch");
1245   return REAL(inotify_add_watch)(fd, path, mask);
1246 }
1247 
1248 INTERCEPTOR(int, inotify_rm_watch, int fd, int wd) {
1249   __rtsan_notify_intercepted_call("inotify_rm_watch");
1250   return REAL(inotify_rm_watch)(fd, wd);
1251 }
1252 #define RTSAN_MAYBE_INTERCEPT_INOTIFY_INIT INTERCEPT_FUNCTION(inotify_init)
1253 #define RTSAN_MAYBE_INTERCEPT_INOTIFY_INIT1 INTERCEPT_FUNCTION(inotify_init1)
1254 #define RTSAN_MAYBE_INTERCEPT_INOTIFY_ADD_WATCH                                \
1255   INTERCEPT_FUNCTION(inotify_add_watch)
1256 #define RTSAN_MAYBE_INTERCEPT_INOTIFY_RM_WATCH                                 \
1257   INTERCEPT_FUNCTION(inotify_rm_watch)
1258 #else
1259 #define RTSAN_MAYBE_INTERCEPT_INOTIFY_INIT
1260 #define RTSAN_MAYBE_INTERCEPT_INOTIFY_INIT1
1261 #define RTSAN_MAYBE_INTERCEPT_INOTIFY_ADD_WATCH
1262 #define RTSAN_MAYBE_INTERCEPT_INOTIFY_RM_WATCH
1263 #endif
1264 
1265 INTERCEPTOR(int, pipe, int pipefd[2]) {
1266   __rtsan_notify_intercepted_call("pipe");
1267   return REAL(pipe)(pipefd);
1268 }
1269 
1270 #if !SANITIZER_APPLE
1271 INTERCEPTOR(int, pipe2, int pipefd[2], int flags) {
1272   __rtsan_notify_intercepted_call("pipe2");
1273   return REAL(pipe2)(pipefd, flags);
1274 }
1275 #define RTSAN_MAYBE_INTERCEPT_PIPE2 INTERCEPT_FUNCTION(pipe2)
1276 #else
1277 #define RTSAN_MAYBE_INTERCEPT_PIPE2
1278 #endif
1279 
1280 INTERCEPTOR(int, mkfifo, const char *pathname, mode_t mode) {
1281   __rtsan_notify_intercepted_call("mkfifo");
1282   return REAL(mkfifo)(pathname, mode);
1283 }
1284 
1285 INTERCEPTOR(pid_t, fork, void) {
1286   __rtsan_notify_intercepted_call("fork");
1287   return REAL(fork)();
1288 }
1289 
1290 INTERCEPTOR(int, execve, const char *filename, char *const argv[],
1291             char *const envp[]) {
1292   __rtsan_notify_intercepted_call("execve");
1293   return REAL(execve)(filename, argv, envp);
1294 }
1295 
1296 #if SANITIZER_INTERCEPT_PROCESS_VM_READV
1297 INTERCEPTOR(ssize_t, process_vm_readv, pid_t pid, const struct iovec *local_iov,
1298             unsigned long liovcnt, const struct iovec *remote_iov,
1299             unsigned long riovcnt, unsigned long flags) {
1300   __rtsan_notify_intercepted_call("process_vm_readv");
1301   return REAL(process_vm_readv)(pid, local_iov, liovcnt, remote_iov, riovcnt,
1302                                 flags);
1303 }
1304 
1305 INTERCEPTOR(ssize_t, process_vm_writev, pid_t pid,
1306             const struct iovec *local_iov, unsigned long liovcnt,
1307             const struct iovec *remote_iov, unsigned long riovcnt,
1308             unsigned long flags) {
1309   __rtsan_notify_intercepted_call("process_vm_writev");
1310   return REAL(process_vm_writev)(pid, local_iov, liovcnt, remote_iov, riovcnt,
1311                                  flags);
1312 }
1313 #define RTSAN_MAYBE_INTERCEPT_PROCESS_VM_READV                                 \
1314   INTERCEPT_FUNCTION(process_vm_readv)
1315 #define RTSAN_MAYBE_INTERCEPT_PROCESS_VM_WRITEV                                \
1316   INTERCEPT_FUNCTION(process_vm_writev)
1317 #else
1318 #define RTSAN_MAYBE_INTERCEPT_PROCESS_VM_READV
1319 #define RTSAN_MAYBE_INTERCEPT_PROCESS_VM_WRITEV
1320 #endif
1321 
1322 // TODO: the `wait` family of functions is an oddity. In testing, if you
1323 // intercept them, Darwin seemingly ignores them, and linux never returns from
1324 // the test. Revisit this in the future, but hopefully intercepting fork/exec is
1325 // enough to dissuade usage of wait by proxy.
1326 
1327 #if SANITIZER_APPLE
1328 #define INT_TYPE_SYSCALL int
1329 #else
1330 #define INT_TYPE_SYSCALL long
1331 #endif
1332 
1333 #pragma clang diagnostic push
1334 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
1335 INTERCEPTOR(INT_TYPE_SYSCALL, syscall, INT_TYPE_SYSCALL number, ...) {
1336   __rtsan_notify_intercepted_call("syscall");
1337 
1338   va_list args;
1339   va_start(args, number);
1340 
1341   // the goal is to pick something large enough to hold all syscall args
1342   // see fcntl for more discussion and why we always pull all 6 args
1343   using arg_type = unsigned long;
1344   arg_type arg1 = va_arg(args, arg_type);
1345   arg_type arg2 = va_arg(args, arg_type);
1346   arg_type arg3 = va_arg(args, arg_type);
1347   arg_type arg4 = va_arg(args, arg_type);
1348   arg_type arg5 = va_arg(args, arg_type);
1349   arg_type arg6 = va_arg(args, arg_type);
1350 
1351   // these are various examples of things that COULD be passed
1352   static_assert(sizeof(arg_type) >= sizeof(off_t));
1353   static_assert(sizeof(arg_type) >= sizeof(struct flock *));
1354   static_assert(sizeof(arg_type) >= sizeof(const char *));
1355   static_assert(sizeof(arg_type) >= sizeof(int));
1356   static_assert(sizeof(arg_type) >= sizeof(unsigned long));
1357 
1358   va_end(args);
1359 
1360   return REAL(syscall)(number, arg1, arg2, arg3, arg4, arg5, arg6);
1361 }
1362 #pragma clang diagnostic pop
1363 
1364 // Preinit
1365 void __rtsan::InitializeInterceptors() {
1366   INTERCEPT_FUNCTION(calloc);
1367   INTERCEPT_FUNCTION(free);
1368   INTERCEPT_FUNCTION(malloc);
1369   INTERCEPT_FUNCTION(realloc);
1370   INTERCEPT_FUNCTION(reallocf);
1371   INTERCEPT_FUNCTION(valloc);
1372   RTSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC;
1373   INTERCEPT_FUNCTION(posix_memalign);
1374   INTERCEPT_FUNCTION(mmap);
1375   RTSAN_MAYBE_INTERCEPT_MMAP64;
1376   RTSAN_MAYBE_INTERCEPT_MREMAP;
1377   INTERCEPT_FUNCTION(munmap);
1378   RTSAN_MAYBE_INTERCEPT_MADVISE;
1379   RTSAN_MAYBE_INTERCEPT_POSIX_MADVISE;
1380   INTERCEPT_FUNCTION(mprotect);
1381   INTERCEPT_FUNCTION(msync);
1382   INTERCEPT_FUNCTION(mincore);
1383   INTERCEPT_FUNCTION(shm_open);
1384   INTERCEPT_FUNCTION(shm_unlink);
1385   RTSAN_MAYBE_INTERCEPT_MEMALIGN;
1386   RTSAN_MAYBE_INTERCEPT_PVALLOC;
1387 
1388   INTERCEPT_FUNCTION(open);
1389   RTSAN_MAYBE_INTERCEPT_OPEN64;
1390   INTERCEPT_FUNCTION(openat);
1391   RTSAN_MAYBE_INTERCEPT_OPENAT64;
1392   INTERCEPT_FUNCTION(close);
1393   INTERCEPT_FUNCTION(fopen);
1394   RTSAN_MAYBE_INTERCEPT_FOPEN64;
1395   RTSAN_MAYBE_INTERCEPT_FREOPEN64;
1396   INTERCEPT_FUNCTION(fread);
1397   INTERCEPT_FUNCTION(read);
1398   INTERCEPT_FUNCTION(write);
1399   INTERCEPT_FUNCTION(pread);
1400   RTSAN_MAYBE_INTERCEPT_PREAD64;
1401   RTSAN_MAYBE_INTERCEPT_PREADV;
1402   RTSAN_MAYBE_INTERCEPT_PREADV64;
1403   INTERCEPT_FUNCTION(readv);
1404   INTERCEPT_FUNCTION(pwrite);
1405   RTSAN_MAYBE_INTERCEPT_PWRITE64;
1406   RTSAN_MAYBE_INTERCEPT_PWRITEV;
1407   RTSAN_MAYBE_INTERCEPT_PWRITEV64;
1408   INTERCEPT_FUNCTION(writev);
1409   INTERCEPT_FUNCTION(fwrite);
1410   INTERCEPT_FUNCTION(fclose);
1411   INTERCEPT_FUNCTION(fcntl);
1412   RTSAN_MAYBE_INTERCEPT_FCNTL64;
1413   INTERCEPT_FUNCTION(creat);
1414   RTSAN_MAYBE_INTERCEPT_CREAT64;
1415   INTERCEPT_FUNCTION(puts);
1416   INTERCEPT_FUNCTION(fputs);
1417   INTERCEPT_FUNCTION(fflush);
1418   RTSAN_MAYBE_INTERCEPT_FPURGE;
1419   RTSAN_MAYBE_INTERCEPT_PIPE2;
1420   INTERCEPT_FUNCTION(fdopen);
1421   INTERCEPT_FUNCTION(freopen);
1422   RTSAN_MAYBE_INTERCEPT_FOPENCOOKIE;
1423   RTSAN_MAYBE_INTERCEPT_OPEN_MEMSTREAM;
1424   RTSAN_MAYBE_INTERCEPT_FMEMOPEN;
1425   RTSAN_MAYBE_INTERCEPT_SETBUF;
1426   RTSAN_MAYBE_INTERCEPT_SETVBUF;
1427   RTSAN_MAYBE_INTERCEPT_SETLINEBUF;
1428   RTSAN_MAYBE_INTERCEPT_SETBUFFER;
1429   RTSAN_MAYBE_INTERCEPT_FGETPOS;
1430   RTSAN_MAYBE_INTERCEPT_FSEEK;
1431   RTSAN_MAYBE_INTERCEPT_FSEEKO;
1432   RTSAN_MAYBE_INTERCEPT_FSETPOS;
1433   RTSAN_MAYBE_INTERCEPT_FTELL;
1434   RTSAN_MAYBE_INTERCEPT_FTELLO;
1435   RTSAN_MAYBE_INTERCEPT_REWIND;
1436   RTSAN_MAYBE_INTERCEPT_FGETPOS64;
1437   RTSAN_MAYBE_INTERCEPT_FSEEKO64;
1438   RTSAN_MAYBE_INTERCEPT_FSETPOS64;
1439   RTSAN_MAYBE_INTERCEPT_FTELLO64;
1440   INTERCEPT_FUNCTION(lseek);
1441   RTSAN_MAYBE_INTERCEPT_LSEEK64;
1442   INTERCEPT_FUNCTION(dup);
1443   INTERCEPT_FUNCTION(dup2);
1444   INTERCEPT_FUNCTION(chmod);
1445   INTERCEPT_FUNCTION(fchmod);
1446   INTERCEPT_FUNCTION(mkdir);
1447   INTERCEPT_FUNCTION(rmdir);
1448   INTERCEPT_FUNCTION(umask);
1449   INTERCEPT_FUNCTION(ioctl);
1450 
1451   RTSAN_MAYBE_INTERCEPT_OSSPINLOCKLOCK;
1452   RTSAN_MAYBE_INTERCEPT_OS_UNFAIR_LOCK_LOCK;
1453   RTSAN_MAYBE_INTERCEPT_PTHREAD_SPIN_LOCK;
1454 
1455   INTERCEPT_FUNCTION(pthread_create);
1456   INTERCEPT_FUNCTION(pthread_mutex_lock);
1457   INTERCEPT_FUNCTION(pthread_mutex_unlock);
1458   INTERCEPT_FUNCTION(pthread_join);
1459   INTERCEPT_FUNCTION(pthread_cond_signal);
1460   INTERCEPT_FUNCTION(pthread_cond_broadcast);
1461   INTERCEPT_FUNCTION(pthread_cond_wait);
1462   INTERCEPT_FUNCTION(pthread_cond_timedwait);
1463   INTERCEPT_FUNCTION(pthread_rwlock_rdlock);
1464   INTERCEPT_FUNCTION(pthread_rwlock_unlock);
1465   INTERCEPT_FUNCTION(pthread_rwlock_wrlock);
1466 
1467   INTERCEPT_FUNCTION(sleep);
1468   INTERCEPT_FUNCTION(usleep);
1469   INTERCEPT_FUNCTION(nanosleep);
1470   INTERCEPT_FUNCTION(sched_yield);
1471   RTSAN_MAYBE_INTERCEPT_SCHED_GETAFFINITY;
1472   RTSAN_MAYBE_INTERCEPT_SCHED_SETAFFINITY;
1473 
1474   INTERCEPT_FUNCTION(accept);
1475   INTERCEPT_FUNCTION(bind);
1476   INTERCEPT_FUNCTION(connect);
1477   INTERCEPT_FUNCTION(getaddrinfo);
1478   INTERCEPT_FUNCTION(getnameinfo);
1479   INTERCEPT_FUNCTION(listen);
1480   INTERCEPT_FUNCTION(recv);
1481   INTERCEPT_FUNCTION(recvfrom);
1482   INTERCEPT_FUNCTION(recvmsg);
1483   RTSAN_MAYBE_INTERCEPT_RECVMMSG;
1484   INTERCEPT_FUNCTION(send);
1485   INTERCEPT_FUNCTION(sendmsg);
1486   RTSAN_MAYBE_INTERCEPT_SENDMMSG;
1487   INTERCEPT_FUNCTION(sendto);
1488   INTERCEPT_FUNCTION(shutdown);
1489   INTERCEPT_FUNCTION(socket);
1490   RTSAN_MAYBE_INTERCEPT_ACCEPT4;
1491   RTSAN_MAYBE_INTERCEPT_GETSOCKNAME;
1492   RTSAN_MAYBE_INTERCEPT_GETPEERNAME;
1493   RTSAN_MAYBE_INTERCEPT_GETSOCKOPT;
1494   RTSAN_MAYBE_INTERCEPT_SETSOCKOPT;
1495   INTERCEPT_FUNCTION(socketpair);
1496 
1497   RTSAN_MAYBE_INTERCEPT_SELECT;
1498   INTERCEPT_FUNCTION(pselect);
1499   INTERCEPT_FUNCTION(poll);
1500   RTSAN_MAYBE_INTERCEPT_EPOLL_CREATE;
1501   RTSAN_MAYBE_INTERCEPT_EPOLL_CREATE1;
1502   RTSAN_MAYBE_INTERCEPT_EPOLL_CTL;
1503   RTSAN_MAYBE_INTERCEPT_EPOLL_WAIT;
1504   RTSAN_MAYBE_INTERCEPT_EPOLL_PWAIT;
1505   RTSAN_MAYBE_INTERCEPT_PPOLL;
1506   RTSAN_MAYBE_INTERCEPT_KQUEUE;
1507   RTSAN_MAYBE_INTERCEPT_KEVENT;
1508   RTSAN_MAYBE_INTERCEPT_KEVENT64;
1509 
1510   RTSAN_MAYBE_INTERCEPT_INOTIFY_INIT;
1511   RTSAN_MAYBE_INTERCEPT_INOTIFY_INIT1;
1512   RTSAN_MAYBE_INTERCEPT_INOTIFY_ADD_WATCH;
1513   RTSAN_MAYBE_INTERCEPT_INOTIFY_RM_WATCH;
1514 
1515   INTERCEPT_FUNCTION(pipe);
1516   INTERCEPT_FUNCTION(mkfifo);
1517 
1518   INTERCEPT_FUNCTION(fork);
1519   INTERCEPT_FUNCTION(execve);
1520 
1521   RTSAN_MAYBE_INTERCEPT_PROCESS_VM_READV;
1522   RTSAN_MAYBE_INTERCEPT_PROCESS_VM_WRITEV;
1523 
1524   INTERCEPT_FUNCTION(syscall);
1525 }
1526 
1527 #endif // SANITIZER_POSIX
1528