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
47using namespace __sanitizer;
48
49namespace {
50struct DlsymAlloc : public DlSymAllocator<DlsymAlloc> {
51 static bool UseImpl() { return !__rtsan_is_initialized(); }
52};
53} // namespace
54
55// Filesystem
56
57INTERCEPTOR(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(intercepted_function_name: "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
77INTERCEPTOR(int, open64, const char *path, int oflag, ...) {
78 // See comment above about O_NONBLOCK
79 __rtsan_notify_intercepted_call(intercepted_function_name: "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
96INTERCEPTOR(int, openat, int fd, const char *path, int oflag, ...) {
97 // See comment above about O_NONBLOCK
98 __rtsan_notify_intercepted_call(intercepted_function_name: "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
112INTERCEPTOR(int, openat64, int fd, const char *path, int oflag, ...) {
113 // See comment above about O_NONBLOCK
114 __rtsan_notify_intercepted_call(intercepted_function_name: "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
131INTERCEPTOR(int, creat, const char *path, mode_t mode) {
132 // See comment above about O_NONBLOCK
133 __rtsan_notify_intercepted_call(intercepted_function_name: "creat");
134 const int result = REAL(creat)(path, mode);
135 return result;
136}
137
138#if SANITIZER_INTERCEPT_CREAT64
139INTERCEPTOR(int, creat64, const char *path, mode_t mode) {
140 // See comment above about O_NONBLOCK
141 __rtsan_notify_intercepted_call(intercepted_function_name: "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
150INTERCEPTOR(int, fcntl, int filedes, int cmd, ...) {
151 __rtsan_notify_intercepted_call(intercepted_function_name: "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
188INTERCEPTOR(int, ioctl, int filedes, int request, ...) {
189#else
190INTERCEPTOR(int, ioctl, int filedes, unsigned long request, ...) {
191#endif
192 __rtsan_notify_intercepted_call(intercepted_function_name: "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
209INTERCEPTOR(int, fcntl64, int filedes, int cmd, ...) {
210 __rtsan_notify_intercepted_call(intercepted_function_name: "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
234INTERCEPTOR(int, close, int filedes) {
235 __rtsan_notify_intercepted_call(intercepted_function_name: "close");
236 return REAL(close)(filedes);
237}
238
239INTERCEPTOR(int, chdir, const char *path) {
240 __rtsan_notify_intercepted_call(intercepted_function_name: "chdir");
241 return REAL(chdir)(path);
242}
243
244INTERCEPTOR(int, fchdir, int fd) {
245 __rtsan_notify_intercepted_call(intercepted_function_name: "fchdir");
246 return REAL(fchdir)(fd);
247}
248
249#if SANITIZER_INTERCEPT_READLINK
250INTERCEPTOR(ssize_t, readlink, const char *pathname, char *buf, size_t size) {
251 __rtsan_notify_intercepted_call(intercepted_function_name: "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
260INTERCEPTOR(ssize_t, readlinkat, int dirfd, const char *pathname, char *buf,
261 size_t size) {
262 __rtsan_notify_intercepted_call(intercepted_function_name: "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
270INTERCEPTOR(int, unlink, const char *pathname) {
271 __rtsan_notify_intercepted_call(intercepted_function_name: "unlink");
272 return REAL(unlink)(pathname);
273}
274
275INTERCEPTOR(int, unlinkat, int fd, const char *pathname, int flag) {
276 __rtsan_notify_intercepted_call(intercepted_function_name: "unlinkat");
277 return REAL(unlinkat)(fd, pathname, flag);
278}
279
280INTERCEPTOR(int, truncate, const char *pathname, off_t length) {
281 __rtsan_notify_intercepted_call(intercepted_function_name: "truncate");
282 return REAL(truncate)(pathname, length);
283}
284
285INTERCEPTOR(int, ftruncate, int fd, off_t length) {
286 __rtsan_notify_intercepted_call(intercepted_function_name: "ftruncate");
287 return REAL(ftruncate)(fd, length);
288}
289
290#if SANITIZER_LINUX && !SANITIZER_MUSL
291INTERCEPTOR(int, truncate64, const char *pathname, off64_t length) {
292 __rtsan_notify_intercepted_call(intercepted_function_name: "truncate64");
293 return REAL(truncate64)(pathname, length);
294}
295
296INTERCEPTOR(int, ftruncate64, int fd, off64_t length) {
297 __rtsan_notify_intercepted_call(intercepted_function_name: "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
307INTERCEPTOR(int, symlink, const char *target, const char *linkpath) {
308 __rtsan_notify_intercepted_call(intercepted_function_name: "symlink");
309 return REAL(symlink)(target, linkpath);
310}
311
312INTERCEPTOR(int, symlinkat, const char *target, int newdirfd,
313 const char *linkpath) {
314 __rtsan_notify_intercepted_call(intercepted_function_name: "symlinkat");
315 return REAL(symlinkat)(target, newdirfd, linkpath);
316}
317
318// Streams
319
320INTERCEPTOR(FILE *, fopen, const char *path, const char *mode) {
321 __rtsan_notify_intercepted_call(intercepted_function_name: "fopen");
322 return REAL(fopen)(path, mode);
323}
324
325INTERCEPTOR(FILE *, freopen, const char *path, const char *mode, FILE *stream) {
326 __rtsan_notify_intercepted_call(intercepted_function_name: "freopen");
327 return REAL(freopen)(path, mode, stream);
328}
329
330#if SANITIZER_INTERCEPT_FOPEN64
331INTERCEPTOR(FILE *, fopen64, const char *path, const char *mode) {
332 __rtsan_notify_intercepted_call(intercepted_function_name: "fopen64");
333 return REAL(fopen64)(path, mode);
334}
335
336INTERCEPTOR(FILE *, freopen64, const char *path, const char *mode,
337 FILE *stream) {
338 __rtsan_notify_intercepted_call(intercepted_function_name: "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
348INTERCEPTOR(size_t, fread, void *ptr, size_t size, size_t nitems,
349 FILE *stream) {
350 __rtsan_notify_intercepted_call(intercepted_function_name: "fread");
351 return REAL(fread)(ptr, size, nitems, stream);
352}
353
354INTERCEPTOR(size_t, fwrite, const void *ptr, size_t size, size_t nitems,
355 FILE *stream) {
356 __rtsan_notify_intercepted_call(intercepted_function_name: "fwrite");
357 return REAL(fwrite)(ptr, size, nitems, stream);
358}
359
360INTERCEPTOR(int, fclose, FILE *stream) {
361 __rtsan_notify_intercepted_call(intercepted_function_name: "fclose");
362 return REAL(fclose)(stream);
363}
364
365INTERCEPTOR(int, fputs, const char *s, FILE *stream) {
366 __rtsan_notify_intercepted_call(intercepted_function_name: "fputs");
367 return REAL(fputs)(s, stream);
368}
369
370INTERCEPTOR(int, fflush, FILE *stream) {
371 __rtsan_notify_intercepted_call(intercepted_function_name: "fflush");
372 return REAL(fflush)(stream);
373}
374
375#if SANITIZER_APPLE
376INTERCEPTOR(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
385INTERCEPTOR(FILE *, fdopen, int fd, const char *mode) {
386 __rtsan_notify_intercepted_call(intercepted_function_name: "fdopen");
387 return REAL(fdopen)(fd, mode);
388}
389
390#if SANITIZER_INTERCEPT_FOPENCOOKIE
391INTERCEPTOR(FILE *, fopencookie, void *cookie, const char *mode,
392 cookie_io_functions_t funcs) {
393 __rtsan_notify_intercepted_call(intercepted_function_name: "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
402INTERCEPTOR(FILE *, open_memstream, char **buf, size_t *size) {
403 __rtsan_notify_intercepted_call(intercepted_function_name: "open_memstream");
404 return REAL(open_memstream)(buf, size);
405}
406
407INTERCEPTOR(FILE *, fmemopen, void *buf, size_t size, const char *mode) {
408 __rtsan_notify_intercepted_call(intercepted_function_name: "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
419INTERCEPTOR(void, setbuf, FILE *stream, char *buf) {
420 __rtsan_notify_intercepted_call(intercepted_function_name: "setbuf");
421 return REAL(setbuf)(stream, buf);
422}
423
424INTERCEPTOR(int, setvbuf, FILE *stream, char *buf, int mode, size_t size) {
425 __rtsan_notify_intercepted_call(intercepted_function_name: "setvbuf");
426 return REAL(setvbuf)(stream, buf, mode, size);
427}
428
429#if SANITIZER_LINUX
430INTERCEPTOR(void, setlinebuf, FILE *stream) {
431#else
432INTERCEPTOR(int, setlinebuf, FILE *stream) {
433#endif
434 __rtsan_notify_intercepted_call(intercepted_function_name: "setlinebuf");
435 return REAL(setlinebuf)(stream);
436}
437
438#if SANITIZER_LINUX
439INTERCEPTOR(void, setbuffer, FILE *stream, char *buf, size_t size) {
440#else
441INTERCEPTOR(void, setbuffer, FILE *stream, char *buf, int size) {
442#endif
443 __rtsan_notify_intercepted_call(intercepted_function_name: "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
458INTERCEPTOR(int, fgetpos, FILE *stream, fpos_t *pos) {
459 __rtsan_notify_intercepted_call(intercepted_function_name: "fgetpos");
460 return REAL(fgetpos)(stream, pos);
461}
462
463INTERCEPTOR(int, fseek, FILE *stream, long offset, int whence) {
464 __rtsan_notify_intercepted_call(intercepted_function_name: "fseek");
465 return REAL(fseek)(stream, offset, whence);
466}
467
468INTERCEPTOR(int, fseeko, FILE *stream, off_t offset, int whence) {
469 __rtsan_notify_intercepted_call(intercepted_function_name: "fseeko");
470 return REAL(fseeko)(stream, offset, whence);
471}
472
473INTERCEPTOR(int, fsetpos, FILE *stream, const fpos_t *pos) {
474 __rtsan_notify_intercepted_call(intercepted_function_name: "fsetpos");
475 return REAL(fsetpos)(stream, pos);
476}
477
478INTERCEPTOR(long, ftell, FILE *stream) {
479 __rtsan_notify_intercepted_call(intercepted_function_name: "ftell");
480 return REAL(ftell)(stream);
481}
482
483INTERCEPTOR(off_t, ftello, FILE *stream) {
484 __rtsan_notify_intercepted_call(intercepted_function_name: "ftello");
485 return REAL(ftello)(stream);
486}
487
488#if SANITIZER_LINUX && !SANITIZER_MUSL
489INTERCEPTOR(int, fgetpos64, FILE *stream, fpos64_t *pos) {
490 __rtsan_notify_intercepted_call(intercepted_function_name: "fgetpos64");
491 return REAL(fgetpos64)(stream, pos);
492}
493
494INTERCEPTOR(int, fseeko64, FILE *stream, off64_t offset, int whence) {
495 __rtsan_notify_intercepted_call(intercepted_function_name: "fseeko64");
496 return REAL(fseeko64)(stream, offset, whence);
497}
498
499INTERCEPTOR(int, fsetpos64, FILE *stream, const fpos64_t *pos) {
500 __rtsan_notify_intercepted_call(intercepted_function_name: "fsetpos64");
501 return REAL(fsetpos64)(stream, pos);
502}
503
504INTERCEPTOR(off64_t, ftello64, FILE *stream) {
505 __rtsan_notify_intercepted_call(intercepted_function_name: "ftello64");
506 return REAL(ftello64)(stream);
507}
508#endif
509
510INTERCEPTOR(void, rewind, FILE *stream) {
511 __rtsan_notify_intercepted_call(intercepted_function_name: "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
546INTERCEPTOR(int, puts, const char *s) {
547 __rtsan_notify_intercepted_call(intercepted_function_name: "puts");
548 return REAL(puts)(s);
549}
550
551INTERCEPTOR(ssize_t, read, int fd, void *buf, size_t count) {
552 __rtsan_notify_intercepted_call(intercepted_function_name: "read");
553 return REAL(read)(fd, buf, count);
554}
555
556INTERCEPTOR(ssize_t, write, int fd, const void *buf, size_t count) {
557 __rtsan_notify_intercepted_call(intercepted_function_name: "write");
558 return REAL(write)(fd, buf, count);
559}
560
561INTERCEPTOR(ssize_t, pread, int fd, void *buf, size_t count, off_t offset) {
562 __rtsan_notify_intercepted_call(intercepted_function_name: "pread");
563 return REAL(pread)(fd, buf, count, offset);
564}
565
566#if SANITIZER_INTERCEPT_PREAD64
567INTERCEPTOR(ssize_t, pread64, int fd, void *buf, size_t count, off_t offset) {
568 __rtsan_notify_intercepted_call(intercepted_function_name: "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
576INTERCEPTOR(ssize_t, readv, int fd, const struct iovec *iov, int iovcnt) {
577 __rtsan_notify_intercepted_call(intercepted_function_name: "readv");
578 return REAL(readv)(fd, iov, iovcnt);
579}
580
581INTERCEPTOR(ssize_t, pwrite, int fd, const void *buf, size_t count,
582 off_t offset) {
583 __rtsan_notify_intercepted_call(intercepted_function_name: "pwrite");
584 return REAL(pwrite)(fd, buf, count, offset);
585}
586
587#if SANITIZER_INTERCEPT_PWRITE64
588INTERCEPTOR(ssize_t, pwrite64, int fd, const void *buf, size_t count,
589 off_t offset) {
590 __rtsan_notify_intercepted_call(intercepted_function_name: "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
599INTERCEPTOR(ssize_t, preadv, int fd, const struct iovec *iov, int count,
600 off_t offset) {
601 __rtsan_notify_intercepted_call(intercepted_function_name: "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
610INTERCEPTOR(ssize_t, preadv64, int fd, const struct iovec *iov, int count,
611 off_t offset) {
612 __rtsan_notify_intercepted_call(intercepted_function_name: "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
621INTERCEPTOR(ssize_t, pwritev, int fd, const struct iovec *iov, int count,
622 off_t offset) {
623 __rtsan_notify_intercepted_call(intercepted_function_name: "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
632INTERCEPTOR(ssize_t, pwritev64, int fd, const struct iovec *iov, int count,
633 off_t offset) {
634 __rtsan_notify_intercepted_call(intercepted_function_name: "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
642INTERCEPTOR(ssize_t, writev, int fd, const struct iovec *iov, int iovcnt) {
643 __rtsan_notify_intercepted_call(intercepted_function_name: "writev");
644 return REAL(writev)(fd, iov, iovcnt);
645}
646
647INTERCEPTOR(off_t, lseek, int fd, off_t offset, int whence) {
648 __rtsan_notify_intercepted_call(intercepted_function_name: "lseek");
649 return REAL(lseek)(fd, offset, whence);
650}
651
652#if SANITIZER_INTERCEPT_LSEEK64
653INTERCEPTOR(off64_t, lseek64, int fd, off64_t offset, int whence) {
654 __rtsan_notify_intercepted_call(intercepted_function_name: "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
662INTERCEPTOR(int, dup, int oldfd) {
663 __rtsan_notify_intercepted_call(intercepted_function_name: "dup");
664 return REAL(dup)(oldfd);
665}
666
667INTERCEPTOR(int, dup2, int oldfd, int newfd) {
668 __rtsan_notify_intercepted_call(intercepted_function_name: "dup2");
669 return REAL(dup2)(oldfd, newfd);
670}
671
672INTERCEPTOR(int, chmod, const char *path, mode_t mode) {
673 __rtsan_notify_intercepted_call(intercepted_function_name: "chmod");
674 return REAL(chmod)(path, mode);
675}
676
677INTERCEPTOR(int, fchmod, int fd, mode_t mode) {
678 __rtsan_notify_intercepted_call(intercepted_function_name: "fchmod");
679 return REAL(fchmod)(fd, mode);
680}
681
682INTERCEPTOR(int, mkdir, const char *path, mode_t mode) {
683 __rtsan_notify_intercepted_call(intercepted_function_name: "mkdir");
684 return REAL(mkdir)(path, mode);
685}
686
687INTERCEPTOR(int, rmdir, const char *path) {
688 __rtsan_notify_intercepted_call(intercepted_function_name: "rmdir");
689 return REAL(rmdir)(path);
690}
691
692INTERCEPTOR(mode_t, umask, mode_t cmask) {
693 __rtsan_notify_intercepted_call(intercepted_function_name: "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
704INTERCEPTOR(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.
716typedef volatile OSSpinLock *_os_nospin_lock_t;
717
718INTERCEPTOR(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
726INTERCEPTOR(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
738INTERCEPTOR(int, pthread_spin_lock, pthread_spinlock_t *spinlock) {
739 __rtsan_notify_intercepted_call(intercepted_function_name: "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
748INTERCEPTOR(int, pthread_create, pthread_t *thread, const pthread_attr_t *attr,
749 void *(*start_routine)(void *), void *arg) {
750 __rtsan_notify_intercepted_call(intercepted_function_name: "pthread_create");
751 return REAL(pthread_create)(thread, attr, start_routine, arg);
752}
753
754INTERCEPTOR(int, pthread_mutex_lock, pthread_mutex_t *mutex) {
755 __rtsan_notify_intercepted_call(intercepted_function_name: "pthread_mutex_lock");
756 return REAL(pthread_mutex_lock)(mutex);
757}
758
759INTERCEPTOR(int, pthread_mutex_unlock, pthread_mutex_t *mutex) {
760 __rtsan_notify_intercepted_call(intercepted_function_name: "pthread_mutex_unlock");
761 return REAL(pthread_mutex_unlock)(mutex);
762}
763
764INTERCEPTOR(int, pthread_join, pthread_t thread, void **value_ptr) {
765 __rtsan_notify_intercepted_call(intercepted_function_name: "pthread_join");
766 return REAL(pthread_join)(thread, value_ptr);
767}
768
769INTERCEPTOR(int, pthread_cond_signal, pthread_cond_t *cond) {
770 __rtsan_notify_intercepted_call(intercepted_function_name: "pthread_cond_signal");
771 return REAL(pthread_cond_signal)(cond);
772}
773
774INTERCEPTOR(int, pthread_cond_broadcast, pthread_cond_t *cond) {
775 __rtsan_notify_intercepted_call(intercepted_function_name: "pthread_cond_broadcast");
776 return REAL(pthread_cond_broadcast)(cond);
777}
778
779INTERCEPTOR(int, pthread_cond_wait, pthread_cond_t *cond,
780 pthread_mutex_t *mutex) {
781 __rtsan_notify_intercepted_call(intercepted_function_name: "pthread_cond_wait");
782 return REAL(pthread_cond_wait)(cond, mutex);
783}
784
785INTERCEPTOR(int, pthread_cond_timedwait, pthread_cond_t *cond,
786 pthread_mutex_t *mutex, const timespec *ts) {
787 __rtsan_notify_intercepted_call(intercepted_function_name: "pthread_cond_timedwait");
788 return REAL(pthread_cond_timedwait)(cond, mutex, ts);
789}
790
791INTERCEPTOR(int, pthread_rwlock_rdlock, pthread_rwlock_t *lock) {
792 __rtsan_notify_intercepted_call(intercepted_function_name: "pthread_rwlock_rdlock");
793 return REAL(pthread_rwlock_rdlock)(lock);
794}
795
796INTERCEPTOR(int, pthread_rwlock_unlock, pthread_rwlock_t *lock) {
797 __rtsan_notify_intercepted_call(intercepted_function_name: "pthread_rwlock_unlock");
798 return REAL(pthread_rwlock_unlock)(lock);
799}
800
801INTERCEPTOR(int, pthread_rwlock_wrlock, pthread_rwlock_t *lock) {
802 __rtsan_notify_intercepted_call(intercepted_function_name: "pthread_rwlock_wrlock");
803 return REAL(pthread_rwlock_wrlock)(lock);
804}
805
806// Sleeping
807
808INTERCEPTOR(unsigned int, sleep, unsigned int s) {
809 __rtsan_notify_intercepted_call(intercepted_function_name: "sleep");
810 return REAL(sleep)(s);
811}
812
813INTERCEPTOR(int, usleep, useconds_t u) {
814 __rtsan_notify_intercepted_call(intercepted_function_name: "usleep");
815 return REAL(usleep)(u);
816}
817
818INTERCEPTOR(int, nanosleep, const struct timespec *rqtp,
819 struct timespec *rmtp) {
820 __rtsan_notify_intercepted_call(intercepted_function_name: "nanosleep");
821 return REAL(nanosleep)(rqtp, rmtp);
822}
823
824INTERCEPTOR(int, sched_yield, void) {
825 __rtsan_notify_intercepted_call(intercepted_function_name: "sched_yield");
826 return REAL(sched_yield)();
827}
828
829#if SANITIZER_LINUX
830INTERCEPTOR(int, sched_getaffinity, pid_t pid, size_t len, cpu_set_t *set) {
831 __rtsan_notify_intercepted_call(intercepted_function_name: "sched_getaffinity");
832 return REAL(sched_getaffinity)(pid, len, set);
833}
834
835INTERCEPTOR(int, sched_setaffinity, pid_t pid, size_t len,
836 const cpu_set_t *set) {
837 __rtsan_notify_intercepted_call(intercepted_function_name: "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
851INTERCEPTOR(void *, calloc, SIZE_T num, SIZE_T size) {
852 if (DlsymAlloc::Use())
853 return DlsymAlloc::Callocate(nmemb: num, size);
854
855 __rtsan_notify_intercepted_call(intercepted_function_name: "calloc");
856 return REAL(calloc)(num, size);
857}
858
859INTERCEPTOR(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(intercepted_function_name: "free");
868
869 return REAL(free)(ptr);
870}
871
872INTERCEPTOR(void *, malloc, SIZE_T size) {
873 if (DlsymAlloc::Use())
874 return DlsymAlloc::Allocate(size_in_bytes: size);
875
876 __rtsan_notify_intercepted_call(intercepted_function_name: "malloc");
877 return REAL(malloc)(size);
878}
879
880INTERCEPTOR(void *, realloc, void *ptr, SIZE_T size) {
881 if (DlsymAlloc::Use() || DlsymAlloc::PointerIsMine(ptr))
882 return DlsymAlloc::Realloc(ptr, new_size: size);
883
884 __rtsan_notify_intercepted_call(intercepted_function_name: "realloc");
885 return REAL(realloc)(ptr, size);
886}
887
888INTERCEPTOR(void *, reallocf, void *ptr, SIZE_T size) {
889 __rtsan_notify_intercepted_call(intercepted_function_name: "reallocf");
890 return REAL(reallocf)(ptr, size);
891}
892
893INTERCEPTOR(void *, valloc, SIZE_T size) {
894 __rtsan_notify_intercepted_call(intercepted_function_name: "valloc");
895 return REAL(valloc)(size);
896}
897
898#if SANITIZER_INTERCEPT_ALIGNED_ALLOC
899
900// In some cases, when targeting older Darwin versions, this warning may pop up.
901// Because we are providing a wrapper, the client is responsible to check
902// whether aligned_alloc is available, not us. We still succeed linking on an
903// old OS, because we are using a weak symbol (see aligned_alloc in
904// sanitizer_platform_interceptors.h)
905#pragma clang diagnostic push
906#pragma clang diagnostic ignored "-Wunguarded-availability-new"
907INTERCEPTOR(void *, aligned_alloc, SIZE_T alignment, SIZE_T size) {
908 __rtsan_notify_intercepted_call(intercepted_function_name: "aligned_alloc");
909 return REAL(aligned_alloc)(alignment, size);
910}
911#pragma clang diagnostic pop
912#define RTSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC INTERCEPT_FUNCTION(aligned_alloc)
913#else
914#define RTSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC
915#endif
916
917INTERCEPTOR(int, posix_memalign, void **memptr, size_t alignment, size_t size) {
918 __rtsan_notify_intercepted_call(intercepted_function_name: "posix_memalign");
919 return REAL(posix_memalign)(memptr, alignment, size);
920}
921
922#if SANITIZER_INTERCEPT_MEMALIGN
923INTERCEPTOR(void *, memalign, size_t alignment, size_t size) {
924 __rtsan_notify_intercepted_call(intercepted_function_name: "memalign");
925 return REAL(memalign)(alignment, size);
926}
927#define RTSAN_MAYBE_INTERCEPT_MEMALIGN INTERCEPT_FUNCTION(memalign)
928#else
929#define RTSAN_MAYBE_INTERCEPT_MEMALIGN
930#endif
931
932#if SANITIZER_INTERCEPT_PVALLOC
933INTERCEPTOR(void *, pvalloc, size_t size) {
934 __rtsan_notify_intercepted_call(intercepted_function_name: "pvalloc");
935 return REAL(pvalloc)(size);
936}
937#define RTSAN_MAYBE_INTERCEPT_PVALLOC INTERCEPT_FUNCTION(pvalloc)
938#else
939#define RTSAN_MAYBE_INTERCEPT_PVALLOC
940#endif
941
942INTERCEPTOR(void *, mmap, void *addr, size_t length, int prot, int flags,
943 int fd, off_t offset) {
944 __rtsan_notify_intercepted_call(intercepted_function_name: "mmap");
945 return REAL(mmap)(addr, length, prot, flags, fd, offset);
946}
947
948#if SANITIZER_INTERCEPT_MMAP64
949INTERCEPTOR(void *, mmap64, void *addr, size_t length, int prot, int flags,
950 int fd, off64_t offset) {
951 __rtsan_notify_intercepted_call(intercepted_function_name: "mmap64");
952 return REAL(mmap64)(addr, length, prot, flags, fd, offset);
953}
954#define RTSAN_MAYBE_INTERCEPT_MMAP64 INTERCEPT_FUNCTION(mmap64)
955#else
956#define RTSAN_MAYBE_INTERCEPT_MMAP64
957#endif // SANITIZER_INTERCEPT_MMAP64
958
959#if SANITIZER_LINUX
960// Note that even if rtsan is ported to netbsd, it has a slighty different
961// and non-variadic signature
962INTERCEPTOR(void *, mremap, void *oaddr, size_t olength, size_t nlength,
963 int flags, ...) {
964 __rtsan_notify_intercepted_call(intercepted_function_name: "mremap");
965
966 // the last optional argument is only used in this case
967 // as the new page region will be assigned to. Is ignored otherwise.
968 if (flags & MREMAP_FIXED) {
969 va_list args;
970
971 va_start(args, flags);
972 void *naddr = va_arg(args, void *);
973 va_end(args);
974
975 return REAL(mremap)(oaddr, olength, nlength, flags, naddr);
976 }
977
978 return REAL(mremap)(oaddr, olength, nlength, flags);
979}
980#define RTSAN_MAYBE_INTERCEPT_MREMAP INTERCEPT_FUNCTION(mremap)
981#else
982#define RTSAN_MAYBE_INTERCEPT_MREMAP
983#endif
984
985INTERCEPTOR(int, munmap, void *addr, size_t length) {
986 __rtsan_notify_intercepted_call(intercepted_function_name: "munmap");
987 return REAL(munmap)(addr, length);
988}
989
990#if !SANITIZER_APPLE
991INTERCEPTOR(int, madvise, void *addr, size_t length, int flag) {
992 __rtsan_notify_intercepted_call(intercepted_function_name: "madvise");
993 return REAL(madvise)(addr, length, flag);
994}
995
996INTERCEPTOR(int, posix_madvise, void *addr, size_t length, int flag) {
997 __rtsan_notify_intercepted_call(intercepted_function_name: "posix_madvise");
998 return REAL(posix_madvise)(addr, length, flag);
999}
1000#define RTSAN_MAYBE_INTERCEPT_MADVISE INTERCEPT_FUNCTION(madvise)
1001#define RTSAN_MAYBE_INTERCEPT_POSIX_MADVISE INTERCEPT_FUNCTION(posix_madvise)
1002#else
1003#define RTSAN_MAYBE_INTERCEPT_MADVISE
1004#define RTSAN_MAYBE_INTERCEPT_POSIX_MADVISE
1005#endif
1006
1007INTERCEPTOR(int, mprotect, void *addr, size_t length, int prot) {
1008 __rtsan_notify_intercepted_call(intercepted_function_name: "mprotect");
1009 return REAL(mprotect)(addr, length, prot);
1010}
1011
1012INTERCEPTOR(int, msync, void *addr, size_t length, int flag) {
1013 __rtsan_notify_intercepted_call(intercepted_function_name: "msync");
1014 return REAL(msync)(addr, length, flag);
1015}
1016
1017#if SANITIZER_APPLE
1018INTERCEPTOR(int, mincore, const void *addr, size_t length, char *vec) {
1019#else
1020INTERCEPTOR(int, mincore, void *addr, size_t length, unsigned char *vec) {
1021#endif
1022 __rtsan_notify_intercepted_call(intercepted_function_name: "mincore");
1023 return REAL(mincore)(addr, length, vec);
1024}
1025
1026INTERCEPTOR(int, shm_open, const char *name, int oflag, mode_t mode) {
1027 __rtsan_notify_intercepted_call(intercepted_function_name: "shm_open");
1028 return REAL(shm_open)(name, oflag, mode);
1029}
1030
1031INTERCEPTOR(int, shm_unlink, const char *name) {
1032 __rtsan_notify_intercepted_call(intercepted_function_name: "shm_unlink");
1033 return REAL(shm_unlink)(name);
1034}
1035
1036#if !SANITIZER_APPLE
1037// is supported by freebsd too
1038INTERCEPTOR(int, memfd_create, const char *path, unsigned int flags) {
1039 __rtsan_notify_intercepted_call(intercepted_function_name: "memfd_create");
1040 return REAL(memfd_create)(path, flags);
1041}
1042#define RTSAN_MAYBE_INTERCEPT_MEMFD_CREATE INTERCEPT_FUNCTION(memfd_create)
1043#else
1044#define RTSAN_MAYBE_INTERCEPT_MEMFD_CREATE
1045#endif
1046
1047// Sockets
1048INTERCEPTOR(int, getaddrinfo, const char *node, const char *service,
1049 const struct addrinfo *hints, struct addrinfo **res) {
1050 __rtsan_notify_intercepted_call(intercepted_function_name: "getaddrinfo");
1051 return REAL(getaddrinfo)(node, service, hints, res);
1052}
1053
1054INTERCEPTOR(int, getnameinfo, const struct sockaddr *sa, socklen_t salen,
1055 char *host, socklen_t hostlen, char *serv, socklen_t servlen,
1056 int flags) {
1057 __rtsan_notify_intercepted_call(intercepted_function_name: "getnameinfo");
1058 return REAL(getnameinfo)(sa, salen, host, hostlen, serv, servlen, flags);
1059}
1060
1061#if SANITIZER_INTERCEPT_GETSOCKNAME
1062INTERCEPTOR(int, getsockname, int socket, struct sockaddr *sa,
1063 socklen_t *salen) {
1064 __rtsan_notify_intercepted_call(intercepted_function_name: "getsockname");
1065 return REAL(getsockname)(socket, sa, salen);
1066}
1067#define RTSAN_MAYBE_INTERCEPT_GETSOCKNAME INTERCEPT_FUNCTION(getsockname)
1068#else
1069#define RTSAN_MAYBE_INTERCEPT_GETSOCKNAME
1070#endif
1071
1072#if SANITIZER_INTERCEPT_GETPEERNAME
1073INTERCEPTOR(int, getpeername, int socket, struct sockaddr *sa,
1074 socklen_t *salen) {
1075 __rtsan_notify_intercepted_call(intercepted_function_name: "getpeername");
1076 return REAL(getpeername)(socket, sa, salen);
1077}
1078#define RTSAN_MAYBE_INTERCEPT_GETPEERNAME INTERCEPT_FUNCTION(getpeername)
1079#else
1080#define RTSAN_MAYBE_INTERCEPT_GETPEERNAME
1081#endif
1082
1083INTERCEPTOR(int, bind, int socket, const struct sockaddr *address,
1084 socklen_t address_len) {
1085 __rtsan_notify_intercepted_call(intercepted_function_name: "bind");
1086 return REAL(bind)(socket, address, address_len);
1087}
1088
1089INTERCEPTOR(int, listen, int socket, int backlog) {
1090 __rtsan_notify_intercepted_call(intercepted_function_name: "listen");
1091 return REAL(listen)(socket, backlog);
1092}
1093
1094INTERCEPTOR(int, accept, int socket, struct sockaddr *address,
1095 socklen_t *address_len) {
1096 __rtsan_notify_intercepted_call(intercepted_function_name: "accept");
1097 return REAL(accept)(socket, address, address_len);
1098}
1099
1100INTERCEPTOR(int, connect, int socket, const struct sockaddr *address,
1101 socklen_t address_len) {
1102 __rtsan_notify_intercepted_call(intercepted_function_name: "connect");
1103 return REAL(connect)(socket, address, address_len);
1104}
1105
1106INTERCEPTOR(int, socket, int domain, int type, int protocol) {
1107 __rtsan_notify_intercepted_call(intercepted_function_name: "socket");
1108 return REAL(socket)(domain, type, protocol);
1109}
1110
1111INTERCEPTOR(ssize_t, send, int sockfd, const void *buf, size_t len, int flags) {
1112 __rtsan_notify_intercepted_call(intercepted_function_name: "send");
1113 return REAL(send)(sockfd, buf, len, flags);
1114}
1115
1116INTERCEPTOR(ssize_t, sendmsg, int socket, const struct msghdr *message,
1117 int flags) {
1118 __rtsan_notify_intercepted_call(intercepted_function_name: "sendmsg");
1119 return REAL(sendmsg)(socket, message, flags);
1120}
1121
1122#if SANITIZER_INTERCEPT_SENDMMSG
1123#if SANITIZER_MUSL
1124INTERCEPTOR(int, sendmmsg, int socket, struct mmsghdr *message,
1125 unsigned int len, unsigned int flags) {
1126#else
1127INTERCEPTOR(int, sendmmsg, int socket, struct mmsghdr *message,
1128 unsigned int len, int flags) {
1129#endif
1130 __rtsan_notify_intercepted_call(intercepted_function_name: "sendmmsg");
1131 return REAL(sendmmsg)(socket, message, len, flags);
1132}
1133#define RTSAN_MAYBE_INTERCEPT_SENDMMSG INTERCEPT_FUNCTION(sendmmsg)
1134#else
1135#define RTSAN_MAYBE_INTERCEPT_SENDMMSG
1136#endif
1137
1138INTERCEPTOR(ssize_t, sendto, int socket, const void *buffer, size_t length,
1139 int flags, const struct sockaddr *dest_addr, socklen_t dest_len) {
1140 __rtsan_notify_intercepted_call(intercepted_function_name: "sendto");
1141 return REAL(sendto)(socket, buffer, length, flags, dest_addr, dest_len);
1142}
1143
1144INTERCEPTOR(ssize_t, recv, int socket, void *buffer, size_t length, int flags) {
1145 __rtsan_notify_intercepted_call(intercepted_function_name: "recv");
1146 return REAL(recv)(socket, buffer, length, flags);
1147}
1148
1149INTERCEPTOR(ssize_t, recvfrom, int socket, void *buffer, size_t length,
1150 int flags, struct sockaddr *address, socklen_t *address_len) {
1151 __rtsan_notify_intercepted_call(intercepted_function_name: "recvfrom");
1152 return REAL(recvfrom)(socket, buffer, length, flags, address, address_len);
1153}
1154
1155INTERCEPTOR(ssize_t, recvmsg, int socket, struct msghdr *message, int flags) {
1156 __rtsan_notify_intercepted_call(intercepted_function_name: "recvmsg");
1157 return REAL(recvmsg)(socket, message, flags);
1158}
1159
1160#if SANITIZER_INTERCEPT_RECVMMSG
1161#if SANITIZER_MUSL
1162INTERCEPTOR(int, recvmmsg, int socket, struct mmsghdr *message,
1163 unsigned int len, unsigned int flags, struct timespec *timeout) {
1164#elif defined(__GLIBC_MINOR__) && __GLIBC_MINOR__ < 21
1165INTERCEPTOR(int, recvmmsg, int socket, struct mmsghdr *message,
1166 unsigned int len, int flags, const struct timespec *timeout) {
1167#else
1168INTERCEPTOR(int, recvmmsg, int socket, struct mmsghdr *message,
1169 unsigned int len, int flags, struct timespec *timeout) {
1170#endif // defined(__GLIBC_MINOR) && __GLIBC_MINOR__ < 21
1171 __rtsan_notify_intercepted_call(intercepted_function_name: "recvmmsg");
1172 return REAL(recvmmsg)(socket, message, len, flags, timeout);
1173}
1174#define RTSAN_MAYBE_INTERCEPT_RECVMMSG INTERCEPT_FUNCTION(recvmmsg)
1175#else
1176#define RTSAN_MAYBE_INTERCEPT_RECVMMSG
1177#endif
1178
1179INTERCEPTOR(int, shutdown, int socket, int how) {
1180 __rtsan_notify_intercepted_call(intercepted_function_name: "shutdown");
1181 return REAL(shutdown)(socket, how);
1182}
1183
1184#if SANITIZER_INTERCEPT_ACCEPT4
1185INTERCEPTOR(int, accept4, int socket, struct sockaddr *address,
1186 socklen_t *address_len, int flags) {
1187 __rtsan_notify_intercepted_call(intercepted_function_name: "accept4");
1188 return REAL(accept4)(socket, address, address_len, flags);
1189}
1190#define RTSAN_MAYBE_INTERCEPT_ACCEPT4 INTERCEPT_FUNCTION(accept4)
1191#else
1192#define RTSAN_MAYBE_INTERCEPT_ACCEPT4
1193#endif
1194
1195#if SANITIZER_INTERCEPT_GETSOCKOPT
1196INTERCEPTOR(int, getsockopt, int socket, int level, int option, void *value,
1197 socklen_t *len) {
1198 __rtsan_notify_intercepted_call(intercepted_function_name: "getsockopt");
1199 return REAL(getsockopt)(socket, level, option, value, len);
1200}
1201
1202INTERCEPTOR(int, setsockopt, int socket, int level, int option,
1203 const void *value, socklen_t len) {
1204 __rtsan_notify_intercepted_call(intercepted_function_name: "setsockopt");
1205 return REAL(setsockopt)(socket, level, option, value, len);
1206}
1207#define RTSAN_MAYBE_INTERCEPT_GETSOCKOPT INTERCEPT_FUNCTION(getsockopt)
1208#define RTSAN_MAYBE_INTERCEPT_SETSOCKOPT INTERCEPT_FUNCTION(setsockopt)
1209#else
1210#define RTSAN_MAYBE_INTERCEPT_GETSOCKOPT
1211#define RTSAN_MAYBE_INTERCEPT_SETSOCKOPT
1212#endif
1213
1214INTERCEPTOR(int, socketpair, int domain, int type, int protocol, int pair[2]) {
1215 __rtsan_notify_intercepted_call(intercepted_function_name: "socketpair");
1216 return REAL(socketpair)(domain, type, protocol, pair);
1217}
1218
1219// I/O Multiplexing
1220
1221INTERCEPTOR(int, poll, struct pollfd *fds, nfds_t nfds, int timeout) {
1222 __rtsan_notify_intercepted_call(intercepted_function_name: "poll");
1223 return REAL(poll)(fds, nfds, timeout);
1224}
1225
1226#if !SANITIZER_APPLE
1227// FIXME: This should work on all unix systems, even Mac, but currently
1228// it is showing some weird error while linking
1229// error: declaration of 'select' has a different language linkage
1230INTERCEPTOR(int, select, int nfds, fd_set *readfds, fd_set *writefds,
1231 fd_set *exceptfds, struct timeval *timeout) {
1232 __rtsan_notify_intercepted_call(intercepted_function_name: "select");
1233 return REAL(select)(nfds, readfds, writefds, exceptfds, timeout);
1234}
1235#define RTSAN_MAYBE_INTERCEPT_SELECT INTERCEPT_FUNCTION(select)
1236#else
1237#define RTSAN_MAYBE_INTERCEPT_SELECT
1238#endif // !SANITIZER_APPLE
1239
1240INTERCEPTOR(int, pselect, int nfds, fd_set *readfds, fd_set *writefds,
1241 fd_set *exceptfds, const struct timespec *timeout,
1242 const sigset_t *sigmask) {
1243 __rtsan_notify_intercepted_call(intercepted_function_name: "pselect");
1244 return REAL(pselect)(nfds, readfds, writefds, exceptfds, timeout, sigmask);
1245}
1246
1247#if SANITIZER_INTERCEPT_EPOLL
1248INTERCEPTOR(int, epoll_create, int size) {
1249 __rtsan_notify_intercepted_call(intercepted_function_name: "epoll_create");
1250 return REAL(epoll_create)(size);
1251}
1252
1253INTERCEPTOR(int, epoll_create1, int flags) {
1254 __rtsan_notify_intercepted_call(intercepted_function_name: "epoll_create1");
1255 return REAL(epoll_create1)(flags);
1256}
1257
1258INTERCEPTOR(int, epoll_ctl, int epfd, int op, int fd,
1259 struct epoll_event *event) {
1260 __rtsan_notify_intercepted_call(intercepted_function_name: "epoll_ctl");
1261 return REAL(epoll_ctl)(epfd, op, fd, event);
1262}
1263
1264INTERCEPTOR(int, epoll_wait, int epfd, struct epoll_event *events,
1265 int maxevents, int timeout) {
1266 __rtsan_notify_intercepted_call(intercepted_function_name: "epoll_wait");
1267 return REAL(epoll_wait)(epfd, events, maxevents, timeout);
1268}
1269
1270INTERCEPTOR(int, epoll_pwait, int epfd, struct epoll_event *events,
1271 int maxevents, int timeout, const sigset_t *sigmask) {
1272 __rtsan_notify_intercepted_call(intercepted_function_name: "epoll_pwait");
1273 return REAL(epoll_pwait)(epfd, events, maxevents, timeout, sigmask);
1274}
1275#define RTSAN_MAYBE_INTERCEPT_EPOLL_CREATE INTERCEPT_FUNCTION(epoll_create)
1276#define RTSAN_MAYBE_INTERCEPT_EPOLL_CREATE1 INTERCEPT_FUNCTION(epoll_create1)
1277#define RTSAN_MAYBE_INTERCEPT_EPOLL_CTL INTERCEPT_FUNCTION(epoll_ctl)
1278#define RTSAN_MAYBE_INTERCEPT_EPOLL_WAIT INTERCEPT_FUNCTION(epoll_wait)
1279#define RTSAN_MAYBE_INTERCEPT_EPOLL_PWAIT INTERCEPT_FUNCTION(epoll_pwait)
1280#else
1281#define RTSAN_MAYBE_INTERCEPT_EPOLL_CREATE
1282#define RTSAN_MAYBE_INTERCEPT_EPOLL_CREATE1
1283#define RTSAN_MAYBE_INTERCEPT_EPOLL_CTL
1284#define RTSAN_MAYBE_INTERCEPT_EPOLL_WAIT
1285#define RTSAN_MAYBE_INTERCEPT_EPOLL_PWAIT
1286#endif // SANITIZER_INTERCEPT_EPOLL
1287
1288#if SANITIZER_INTERCEPT_PPOLL
1289INTERCEPTOR(int, ppoll, struct pollfd *fds, nfds_t n, const struct timespec *ts,
1290 const sigset_t *set) {
1291 __rtsan_notify_intercepted_call(intercepted_function_name: "ppoll");
1292 return REAL(ppoll)(fds, n, ts, set);
1293}
1294#define RTSAN_MAYBE_INTERCEPT_PPOLL INTERCEPT_FUNCTION(ppoll)
1295#else
1296#define RTSAN_MAYBE_INTERCEPT_PPOLL
1297#endif
1298
1299#if SANITIZER_INTERCEPT_KQUEUE
1300INTERCEPTOR(int, kqueue, void) {
1301 __rtsan_notify_intercepted_call("kqueue");
1302 return REAL(kqueue)();
1303}
1304
1305INTERCEPTOR(int, kevent, int kq, const struct kevent *changelist, int nchanges,
1306 struct kevent *eventlist, int nevents,
1307 const struct timespec *timeout) {
1308 __rtsan_notify_intercepted_call("kevent");
1309 return REAL(kevent)(kq, changelist, nchanges, eventlist, nevents, timeout);
1310}
1311
1312INTERCEPTOR(int, kevent64, int kq, const struct kevent64_s *changelist,
1313 int nchanges, struct kevent64_s *eventlist, int nevents,
1314 unsigned int flags, const struct timespec *timeout) {
1315 __rtsan_notify_intercepted_call("kevent64");
1316 return REAL(kevent64)(kq, changelist, nchanges, eventlist, nevents, flags,
1317 timeout);
1318}
1319#define RTSAN_MAYBE_INTERCEPT_KQUEUE INTERCEPT_FUNCTION(kqueue)
1320#define RTSAN_MAYBE_INTERCEPT_KEVENT INTERCEPT_FUNCTION(kevent)
1321#define RTSAN_MAYBE_INTERCEPT_KEVENT64 INTERCEPT_FUNCTION(kevent64)
1322#else
1323#define RTSAN_MAYBE_INTERCEPT_KQUEUE
1324#define RTSAN_MAYBE_INTERCEPT_KEVENT
1325#define RTSAN_MAYBE_INTERCEPT_KEVENT64
1326#endif // SANITIZER_INTERCEPT_KQUEUE
1327
1328#if SANITIZER_LINUX
1329INTERCEPTOR(int, inotify_init) {
1330 __rtsan_notify_intercepted_call(intercepted_function_name: "inotify_init");
1331 return REAL(inotify_init)();
1332}
1333
1334INTERCEPTOR(int, inotify_init1, int flags) {
1335 __rtsan_notify_intercepted_call(intercepted_function_name: "inotify_init1");
1336 return REAL(inotify_init1)(flags);
1337}
1338
1339INTERCEPTOR(int, inotify_add_watch, int fd, const char *path, uint32_t mask) {
1340 __rtsan_notify_intercepted_call(intercepted_function_name: "inotify_add_watch");
1341 return REAL(inotify_add_watch)(fd, path, mask);
1342}
1343
1344INTERCEPTOR(int, inotify_rm_watch, int fd, int wd) {
1345 __rtsan_notify_intercepted_call(intercepted_function_name: "inotify_rm_watch");
1346 return REAL(inotify_rm_watch)(fd, wd);
1347}
1348
1349INTERCEPTOR(int, timerfd_create, int clockid, int flags) {
1350 __rtsan_notify_intercepted_call(intercepted_function_name: "timerfd_create");
1351 return REAL(timerfd_create)(clockid, flags);
1352}
1353
1354INTERCEPTOR(int, timerfd_settime, int fd, int flags, const itimerspec *newval,
1355 struct itimerspec *oldval) {
1356 __rtsan_notify_intercepted_call(intercepted_function_name: "timerfd_settime");
1357 return REAL(timerfd_settime)(fd, flags, newval, oldval);
1358}
1359
1360INTERCEPTOR(int, timerfd_gettime, int fd, struct itimerspec *val) {
1361 __rtsan_notify_intercepted_call(intercepted_function_name: "timerfd_gettime");
1362 return REAL(timerfd_gettime)(fd, val);
1363}
1364
1365/* eventfd wrappers calls SYS_eventfd2 down the line */
1366INTERCEPTOR(int, eventfd, unsigned int count, int flags) {
1367 __rtsan_notify_intercepted_call(intercepted_function_name: "eventfd");
1368 return REAL(eventfd)(count, flags);
1369}
1370#define RTSAN_MAYBE_INTERCEPT_INOTIFY_INIT INTERCEPT_FUNCTION(inotify_init)
1371#define RTSAN_MAYBE_INTERCEPT_INOTIFY_INIT1 INTERCEPT_FUNCTION(inotify_init1)
1372#define RTSAN_MAYBE_INTERCEPT_INOTIFY_ADD_WATCH \
1373 INTERCEPT_FUNCTION(inotify_add_watch)
1374#define RTSAN_MAYBE_INTERCEPT_INOTIFY_RM_WATCH \
1375 INTERCEPT_FUNCTION(inotify_rm_watch)
1376#define RTSAN_MAYBE_INTERCEPT_TIMERFD_CREATE INTERCEPT_FUNCTION(timerfd_create)
1377#define RTSAN_MAYBE_INTERCEPT_TIMERFD_SETTIME \
1378 INTERCEPT_FUNCTION(timerfd_settime)
1379#define RTSAN_MAYBE_INTERCEPT_TIMERFD_GETTIME \
1380 INTERCEPT_FUNCTION(timerfd_gettime)
1381#define RTSAN_MAYBE_INTERCEPT_EVENTFD INTERCEPT_FUNCTION(eventfd)
1382#else
1383#define RTSAN_MAYBE_INTERCEPT_INOTIFY_INIT
1384#define RTSAN_MAYBE_INTERCEPT_INOTIFY_INIT1
1385#define RTSAN_MAYBE_INTERCEPT_INOTIFY_ADD_WATCH
1386#define RTSAN_MAYBE_INTERCEPT_INOTIFY_RM_WATCH
1387#define RTSAN_MAYBE_INTERCEPT_TIMERFD_CREATE
1388#define RTSAN_MAYBE_INTERCEPT_TIMERFD_SETTIME
1389#define RTSAN_MAYBE_INTERCEPT_TIMERFD_GETTIME
1390#define RTSAN_MAYBE_INTERCEPT_EVENTFD
1391#endif
1392
1393INTERCEPTOR(int, pipe, int pipefd[2]) {
1394 __rtsan_notify_intercepted_call(intercepted_function_name: "pipe");
1395 return REAL(pipe)(pipefd);
1396}
1397
1398#if !SANITIZER_APPLE
1399INTERCEPTOR(int, pipe2, int pipefd[2], int flags) {
1400 __rtsan_notify_intercepted_call(intercepted_function_name: "pipe2");
1401 return REAL(pipe2)(pipefd, flags);
1402}
1403#define RTSAN_MAYBE_INTERCEPT_PIPE2 INTERCEPT_FUNCTION(pipe2)
1404#else
1405#define RTSAN_MAYBE_INTERCEPT_PIPE2
1406#endif
1407
1408INTERCEPTOR(int, mkfifo, const char *pathname, mode_t mode) {
1409 __rtsan_notify_intercepted_call(intercepted_function_name: "mkfifo");
1410 return REAL(mkfifo)(pathname, mode);
1411}
1412
1413INTERCEPTOR(pid_t, fork, void) {
1414 __rtsan_notify_intercepted_call(intercepted_function_name: "fork");
1415 return REAL(fork)();
1416}
1417
1418INTERCEPTOR(int, execve, const char *filename, char *const argv[],
1419 char *const envp[]) {
1420 __rtsan_notify_intercepted_call(intercepted_function_name: "execve");
1421 return REAL(execve)(filename, argv, envp);
1422}
1423
1424#if SANITIZER_INTERCEPT_PROCESS_VM_READV
1425INTERCEPTOR(ssize_t, process_vm_readv, pid_t pid, const struct iovec *local_iov,
1426 unsigned long liovcnt, const struct iovec *remote_iov,
1427 unsigned long riovcnt, unsigned long flags) {
1428 __rtsan_notify_intercepted_call(intercepted_function_name: "process_vm_readv");
1429 return REAL(process_vm_readv)(pid, local_iov, liovcnt, remote_iov, riovcnt,
1430 flags);
1431}
1432
1433INTERCEPTOR(ssize_t, process_vm_writev, pid_t pid,
1434 const struct iovec *local_iov, unsigned long liovcnt,
1435 const struct iovec *remote_iov, unsigned long riovcnt,
1436 unsigned long flags) {
1437 __rtsan_notify_intercepted_call(intercepted_function_name: "process_vm_writev");
1438 return REAL(process_vm_writev)(pid, local_iov, liovcnt, remote_iov, riovcnt,
1439 flags);
1440}
1441#define RTSAN_MAYBE_INTERCEPT_PROCESS_VM_READV \
1442 INTERCEPT_FUNCTION(process_vm_readv)
1443#define RTSAN_MAYBE_INTERCEPT_PROCESS_VM_WRITEV \
1444 INTERCEPT_FUNCTION(process_vm_writev)
1445#else
1446#define RTSAN_MAYBE_INTERCEPT_PROCESS_VM_READV
1447#define RTSAN_MAYBE_INTERCEPT_PROCESS_VM_WRITEV
1448#endif
1449
1450// TODO: the `wait` family of functions is an oddity. In testing, if you
1451// intercept them, Darwin seemingly ignores them, and linux never returns from
1452// the test. Revisit this in the future, but hopefully intercepting fork/exec is
1453// enough to dissuade usage of wait by proxy.
1454
1455#if SANITIZER_APPLE
1456#define INT_TYPE_SYSCALL int
1457#else
1458#define INT_TYPE_SYSCALL long
1459#endif
1460
1461#pragma clang diagnostic push
1462#pragma clang diagnostic ignored "-Wdeprecated-declarations"
1463INTERCEPTOR(INT_TYPE_SYSCALL, syscall, INT_TYPE_SYSCALL number, ...) {
1464 __rtsan_notify_intercepted_call(intercepted_function_name: "syscall");
1465
1466 va_list args;
1467 va_start(args, number);
1468
1469 // the goal is to pick something large enough to hold all syscall args
1470 // see fcntl for more discussion and why we always pull all 6 args
1471 using arg_type = unsigned long;
1472 arg_type arg1 = va_arg(args, arg_type);
1473 arg_type arg2 = va_arg(args, arg_type);
1474 arg_type arg3 = va_arg(args, arg_type);
1475 arg_type arg4 = va_arg(args, arg_type);
1476 arg_type arg5 = va_arg(args, arg_type);
1477 arg_type arg6 = va_arg(args, arg_type);
1478
1479 // these are various examples of things that COULD be passed
1480 static_assert(sizeof(arg_type) >= sizeof(off_t));
1481 static_assert(sizeof(arg_type) >= sizeof(struct flock *));
1482 static_assert(sizeof(arg_type) >= sizeof(const char *));
1483 static_assert(sizeof(arg_type) >= sizeof(int));
1484 static_assert(sizeof(arg_type) >= sizeof(unsigned long));
1485
1486 va_end(args);
1487
1488 return REAL(syscall)(number, arg1, arg2, arg3, arg4, arg5, arg6);
1489}
1490#pragma clang diagnostic pop
1491
1492// Preinit
1493void __rtsan::InitializeInterceptors() {
1494 INTERCEPT_FUNCTION(calloc);
1495 INTERCEPT_FUNCTION(free);
1496 INTERCEPT_FUNCTION(malloc);
1497 INTERCEPT_FUNCTION(realloc);
1498 INTERCEPT_FUNCTION(reallocf);
1499 INTERCEPT_FUNCTION(valloc);
1500 RTSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC;
1501 INTERCEPT_FUNCTION(posix_memalign);
1502 INTERCEPT_FUNCTION(mmap);
1503 RTSAN_MAYBE_INTERCEPT_MMAP64;
1504 RTSAN_MAYBE_INTERCEPT_MREMAP;
1505 INTERCEPT_FUNCTION(munmap);
1506 RTSAN_MAYBE_INTERCEPT_MADVISE;
1507 RTSAN_MAYBE_INTERCEPT_POSIX_MADVISE;
1508 INTERCEPT_FUNCTION(mprotect);
1509 INTERCEPT_FUNCTION(msync);
1510 INTERCEPT_FUNCTION(mincore);
1511 INTERCEPT_FUNCTION(shm_open);
1512 INTERCEPT_FUNCTION(shm_unlink);
1513 RTSAN_MAYBE_INTERCEPT_MEMFD_CREATE;
1514 RTSAN_MAYBE_INTERCEPT_MEMALIGN;
1515 RTSAN_MAYBE_INTERCEPT_PVALLOC;
1516
1517 INTERCEPT_FUNCTION(open);
1518 RTSAN_MAYBE_INTERCEPT_OPEN64;
1519 INTERCEPT_FUNCTION(openat);
1520 RTSAN_MAYBE_INTERCEPT_OPENAT64;
1521 INTERCEPT_FUNCTION(close);
1522 INTERCEPT_FUNCTION(chdir);
1523 INTERCEPT_FUNCTION(fchdir);
1524 RTSAN_MAYBE_INTERCEPT_READLINK;
1525 RTSAN_MAYBE_INTERCEPT_READLINKAT;
1526 INTERCEPT_FUNCTION(unlink);
1527 INTERCEPT_FUNCTION(unlinkat);
1528 INTERCEPT_FUNCTION(symlink);
1529 INTERCEPT_FUNCTION(symlinkat);
1530 INTERCEPT_FUNCTION(truncate);
1531 INTERCEPT_FUNCTION(ftruncate);
1532 RTSAN_MAYBE_INTERCEPT_TRUNCATE64;
1533 RTSAN_MAYBE_INTERCEPT_FTRUNCATE64;
1534 INTERCEPT_FUNCTION(fopen);
1535 RTSAN_MAYBE_INTERCEPT_FOPEN64;
1536 RTSAN_MAYBE_INTERCEPT_FREOPEN64;
1537 INTERCEPT_FUNCTION(fread);
1538 INTERCEPT_FUNCTION(read);
1539 INTERCEPT_FUNCTION(write);
1540 INTERCEPT_FUNCTION(pread);
1541 RTSAN_MAYBE_INTERCEPT_PREAD64;
1542 RTSAN_MAYBE_INTERCEPT_PREADV;
1543 RTSAN_MAYBE_INTERCEPT_PREADV64;
1544 INTERCEPT_FUNCTION(readv);
1545 INTERCEPT_FUNCTION(pwrite);
1546 RTSAN_MAYBE_INTERCEPT_PWRITE64;
1547 RTSAN_MAYBE_INTERCEPT_PWRITEV;
1548 RTSAN_MAYBE_INTERCEPT_PWRITEV64;
1549 INTERCEPT_FUNCTION(writev);
1550 INTERCEPT_FUNCTION(fwrite);
1551 INTERCEPT_FUNCTION(fclose);
1552 INTERCEPT_FUNCTION(fcntl);
1553 RTSAN_MAYBE_INTERCEPT_FCNTL64;
1554 INTERCEPT_FUNCTION(creat);
1555 RTSAN_MAYBE_INTERCEPT_CREAT64;
1556 INTERCEPT_FUNCTION(puts);
1557 INTERCEPT_FUNCTION(fputs);
1558 INTERCEPT_FUNCTION(fflush);
1559 RTSAN_MAYBE_INTERCEPT_FPURGE;
1560 RTSAN_MAYBE_INTERCEPT_PIPE2;
1561 INTERCEPT_FUNCTION(fdopen);
1562 INTERCEPT_FUNCTION(freopen);
1563 RTSAN_MAYBE_INTERCEPT_FOPENCOOKIE;
1564 RTSAN_MAYBE_INTERCEPT_OPEN_MEMSTREAM;
1565 RTSAN_MAYBE_INTERCEPT_FMEMOPEN;
1566 RTSAN_MAYBE_INTERCEPT_SETBUF;
1567 RTSAN_MAYBE_INTERCEPT_SETVBUF;
1568 RTSAN_MAYBE_INTERCEPT_SETLINEBUF;
1569 RTSAN_MAYBE_INTERCEPT_SETBUFFER;
1570 RTSAN_MAYBE_INTERCEPT_FGETPOS;
1571 RTSAN_MAYBE_INTERCEPT_FSEEK;
1572 RTSAN_MAYBE_INTERCEPT_FSEEKO;
1573 RTSAN_MAYBE_INTERCEPT_FSETPOS;
1574 RTSAN_MAYBE_INTERCEPT_FTELL;
1575 RTSAN_MAYBE_INTERCEPT_FTELLO;
1576 RTSAN_MAYBE_INTERCEPT_REWIND;
1577 RTSAN_MAYBE_INTERCEPT_FGETPOS64;
1578 RTSAN_MAYBE_INTERCEPT_FSEEKO64;
1579 RTSAN_MAYBE_INTERCEPT_FSETPOS64;
1580 RTSAN_MAYBE_INTERCEPT_FTELLO64;
1581 INTERCEPT_FUNCTION(lseek);
1582 RTSAN_MAYBE_INTERCEPT_LSEEK64;
1583 INTERCEPT_FUNCTION(dup);
1584 INTERCEPT_FUNCTION(dup2);
1585 INTERCEPT_FUNCTION(chmod);
1586 INTERCEPT_FUNCTION(fchmod);
1587 INTERCEPT_FUNCTION(mkdir);
1588 INTERCEPT_FUNCTION(rmdir);
1589 INTERCEPT_FUNCTION(umask);
1590 INTERCEPT_FUNCTION(ioctl);
1591
1592 RTSAN_MAYBE_INTERCEPT_OSSPINLOCKLOCK;
1593 RTSAN_MAYBE_INTERCEPT_OS_UNFAIR_LOCK_LOCK;
1594 RTSAN_MAYBE_INTERCEPT_PTHREAD_SPIN_LOCK;
1595
1596 INTERCEPT_FUNCTION(pthread_create);
1597 INTERCEPT_FUNCTION(pthread_mutex_lock);
1598 INTERCEPT_FUNCTION(pthread_mutex_unlock);
1599 INTERCEPT_FUNCTION(pthread_join);
1600 INTERCEPT_FUNCTION(pthread_cond_signal);
1601 INTERCEPT_FUNCTION(pthread_cond_broadcast);
1602 INTERCEPT_FUNCTION(pthread_cond_wait);
1603 INTERCEPT_FUNCTION(pthread_cond_timedwait);
1604 INTERCEPT_FUNCTION(pthread_rwlock_rdlock);
1605 INTERCEPT_FUNCTION(pthread_rwlock_unlock);
1606 INTERCEPT_FUNCTION(pthread_rwlock_wrlock);
1607
1608 INTERCEPT_FUNCTION(sleep);
1609 INTERCEPT_FUNCTION(usleep);
1610 INTERCEPT_FUNCTION(nanosleep);
1611 INTERCEPT_FUNCTION(sched_yield);
1612 RTSAN_MAYBE_INTERCEPT_SCHED_GETAFFINITY;
1613 RTSAN_MAYBE_INTERCEPT_SCHED_SETAFFINITY;
1614
1615 INTERCEPT_FUNCTION(accept);
1616 INTERCEPT_FUNCTION(bind);
1617 INTERCEPT_FUNCTION(connect);
1618 INTERCEPT_FUNCTION(getaddrinfo);
1619 INTERCEPT_FUNCTION(getnameinfo);
1620 INTERCEPT_FUNCTION(listen);
1621 INTERCEPT_FUNCTION(recv);
1622 INTERCEPT_FUNCTION(recvfrom);
1623 INTERCEPT_FUNCTION(recvmsg);
1624 RTSAN_MAYBE_INTERCEPT_RECVMMSG;
1625 INTERCEPT_FUNCTION(send);
1626 INTERCEPT_FUNCTION(sendmsg);
1627 RTSAN_MAYBE_INTERCEPT_SENDMMSG;
1628 INTERCEPT_FUNCTION(sendto);
1629 INTERCEPT_FUNCTION(shutdown);
1630 INTERCEPT_FUNCTION(socket);
1631 RTSAN_MAYBE_INTERCEPT_ACCEPT4;
1632 RTSAN_MAYBE_INTERCEPT_GETSOCKNAME;
1633 RTSAN_MAYBE_INTERCEPT_GETPEERNAME;
1634 RTSAN_MAYBE_INTERCEPT_GETSOCKOPT;
1635 RTSAN_MAYBE_INTERCEPT_SETSOCKOPT;
1636 INTERCEPT_FUNCTION(socketpair);
1637
1638 RTSAN_MAYBE_INTERCEPT_SELECT;
1639 INTERCEPT_FUNCTION(pselect);
1640 INTERCEPT_FUNCTION(poll);
1641 RTSAN_MAYBE_INTERCEPT_EPOLL_CREATE;
1642 RTSAN_MAYBE_INTERCEPT_EPOLL_CREATE1;
1643 RTSAN_MAYBE_INTERCEPT_EPOLL_CTL;
1644 RTSAN_MAYBE_INTERCEPT_EPOLL_WAIT;
1645 RTSAN_MAYBE_INTERCEPT_EPOLL_PWAIT;
1646 RTSAN_MAYBE_INTERCEPT_PPOLL;
1647 RTSAN_MAYBE_INTERCEPT_KQUEUE;
1648 RTSAN_MAYBE_INTERCEPT_KEVENT;
1649 RTSAN_MAYBE_INTERCEPT_KEVENT64;
1650
1651 RTSAN_MAYBE_INTERCEPT_INOTIFY_INIT;
1652 RTSAN_MAYBE_INTERCEPT_INOTIFY_INIT1;
1653 RTSAN_MAYBE_INTERCEPT_INOTIFY_ADD_WATCH;
1654 RTSAN_MAYBE_INTERCEPT_INOTIFY_RM_WATCH;
1655
1656 RTSAN_MAYBE_INTERCEPT_TIMERFD_CREATE;
1657 RTSAN_MAYBE_INTERCEPT_TIMERFD_SETTIME;
1658 RTSAN_MAYBE_INTERCEPT_TIMERFD_GETTIME;
1659 RTSAN_MAYBE_INTERCEPT_EVENTFD;
1660
1661 INTERCEPT_FUNCTION(pipe);
1662 INTERCEPT_FUNCTION(mkfifo);
1663
1664 INTERCEPT_FUNCTION(fork);
1665 INTERCEPT_FUNCTION(execve);
1666
1667 RTSAN_MAYBE_INTERCEPT_PROCESS_VM_READV;
1668 RTSAN_MAYBE_INTERCEPT_PROCESS_VM_WRITEV;
1669
1670 INTERCEPT_FUNCTION(syscall);
1671}
1672
1673#endif // SANITIZER_POSIX
1674