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