1//===--- rtsan_test_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 "gtest/gtest.h"
15
16#include "sanitizer_common/sanitizer_platform_interceptors.h"
17
18#include "rtsan_test_utilities.h"
19
20#if SANITIZER_APPLE
21#include <libkern/OSAtomic.h>
22#include <os/lock.h>
23#include <unistd.h>
24#endif
25
26#if SANITIZER_INTERCEPT_MEMALIGN || SANITIZER_INTERCEPT_PVALLOC
27#include <malloc.h>
28#endif
29
30#if SANITIZER_INTERCEPT_EPOLL
31#include <sys/epoll.h>
32#endif
33
34#if SANITIZER_INTERCEPT_KQUEUE
35#include <sys/event.h>
36#include <sys/time.h>
37#endif
38
39#include <fcntl.h>
40#include <ifaddrs.h>
41#include <net/if.h>
42#include <netdb.h>
43#include <poll.h>
44#include <pthread.h>
45#include <stdio.h>
46#if SANITIZER_LINUX
47#include <sys/eventfd.h>
48#include <sys/inotify.h>
49#include <sys/timerfd.h>
50#endif
51#include <sys/ioctl.h>
52#include <sys/mman.h>
53#include <sys/socket.h>
54#include <sys/stat.h>
55#include <sys/syscall.h>
56#include <sys/types.h>
57#include <sys/uio.h>
58
59#if _FILE_OFFSET_BITS == 64 && SANITIZER_GLIBC
60// Under these conditions, some system calls are `foo64` instead of `foo`
61#define MAYBE_APPEND_64(func) func "64"
62#else
63#define MAYBE_APPEND_64(func) func
64#endif
65
66using namespace testing;
67using namespace rtsan_testing;
68using namespace std::chrono_literals;
69
70// NOTE: In the socket tests we pass in bad info to the calls to ensure they
71// fail which is why we EXPECT_NE 0 for their return codes.
72// We just care that the call is intercepted
73const int kNotASocketFd = 0;
74
75void *FakeThreadEntryPoint(void *) { return nullptr; }
76
77class RtsanFileTest : public ::testing::Test {
78protected:
79 void SetUp() override {
80 const ::testing::TestInfo *const test_info =
81 ::testing::UnitTest::GetInstance()->current_test_info();
82 file_path_ = std::string("/tmp/rtsan_temporary_test_file_") +
83 test_info->name() + ".txt";
84 RemoveTemporaryFile();
85 }
86
87 // Gets a file path with the test's name in it
88 // This file will be removed if it exists at the end of the test
89 const char *GetTemporaryFilePath() const { return file_path_.c_str(); }
90
91 void TearDown() override { RemoveTemporaryFile(); }
92
93private:
94 void RemoveTemporaryFile() const { std::remove(filename: GetTemporaryFilePath()); }
95 std::string file_path_;
96};
97
98/*
99 Allocation and deallocation
100*/
101
102TEST(TestRtsanInterceptors, MallocDiesWhenRealtime) {
103 auto Func = []() { EXPECT_NE(nullptr, malloc(size: 1)); };
104 ExpectRealtimeDeath(Func, intercepted_method_name: "malloc");
105 ExpectNonRealtimeSurvival(Func);
106}
107
108TEST(TestRtsanInterceptors, CallocDiesWhenRealtime) {
109 auto Func = []() { EXPECT_NE(nullptr, calloc(nmemb: 2, size: 4)); };
110 ExpectRealtimeDeath(Func, intercepted_method_name: "calloc");
111 ExpectNonRealtimeSurvival(Func);
112}
113
114TEST(TestRtsanInterceptors, ReallocDiesWhenRealtime) {
115 void *ptr_1 = malloc(size: 1);
116 auto Func = [ptr_1]() { EXPECT_NE(nullptr, realloc(ptr: ptr_1, size: 8)); };
117 ExpectRealtimeDeath(Func, intercepted_method_name: "realloc");
118 ExpectNonRealtimeSurvival(Func);
119}
120
121#if SANITIZER_APPLE
122TEST(TestRtsanInterceptors, ReallocfDiesWhenRealtime) {
123 void *ptr_1 = malloc(1);
124 auto Func = [ptr_1]() { EXPECT_NE(nullptr, reallocf(ptr_1, 8)); };
125 ExpectRealtimeDeath(Func, "reallocf");
126 ExpectNonRealtimeSurvival(Func);
127}
128#endif
129
130TEST(TestRtsanInterceptors, VallocDiesWhenRealtime) {
131 auto Func = []() { EXPECT_NE(nullptr, valloc(size: 4)); };
132 ExpectRealtimeDeath(Func, intercepted_method_name: "valloc");
133 ExpectNonRealtimeSurvival(Func);
134}
135
136#if __has_builtin(__builtin_available) && SANITIZER_APPLE
137#define ALIGNED_ALLOC_AVAILABLE() (__builtin_available(macOS 10.15, *))
138#else
139// We are going to assume this is true until we hit systems where it isn't
140#define ALIGNED_ALLOC_AVAILABLE() (true)
141#endif
142
143TEST(TestRtsanInterceptors, AlignedAllocDiesWhenRealtime) {
144 if (ALIGNED_ALLOC_AVAILABLE()) {
145 auto Func = []() { EXPECT_NE(nullptr, aligned_alloc(alignment: 16, size: 32)); };
146 ExpectRealtimeDeath(Func, intercepted_method_name: "aligned_alloc");
147 ExpectNonRealtimeSurvival(Func);
148 }
149}
150
151// free_sized and free_aligned_sized (both C23) are not yet supported
152TEST(TestRtsanInterceptors, FreeDiesWhenRealtime) {
153 void *ptr_1 = malloc(size: 1);
154 void *ptr_2 = malloc(size: 1);
155 ExpectRealtimeDeath(Func: [ptr_1]() { free(ptr: ptr_1); }, intercepted_method_name: "free");
156 ExpectNonRealtimeSurvival(Func: [ptr_2]() { free(ptr: ptr_2); });
157
158 // Prevent malloc/free pair being optimised out
159 ASSERT_NE(nullptr, ptr_1);
160 ASSERT_NE(nullptr, ptr_2);
161}
162
163TEST(TestRtsanInterceptors, FreeSurvivesWhenRealtimeIfArgumentIsNull) {
164 RealtimeInvoke(Func: []() { free(NULL); });
165 ExpectNonRealtimeSurvival(Func: []() { free(NULL); });
166}
167
168TEST(TestRtsanInterceptors, PosixMemalignDiesWhenRealtime) {
169 auto Func = []() {
170 void *ptr;
171 posix_memalign(memptr: &ptr, alignment: 4, size: 4);
172 };
173 ExpectRealtimeDeath(Func, intercepted_method_name: "posix_memalign");
174 ExpectNonRealtimeSurvival(Func);
175}
176
177#if SANITIZER_INTERCEPT_MEMALIGN
178TEST(TestRtsanInterceptors, MemalignDiesWhenRealtime) {
179 auto Func = []() { EXPECT_NE(memalign(alignment: 2, size: 2048), nullptr); };
180 ExpectRealtimeDeath(Func, intercepted_method_name: "memalign");
181 ExpectNonRealtimeSurvival(Func);
182}
183#endif
184
185#if SANITIZER_INTERCEPT_PVALLOC
186TEST(TestRtsanInterceptors, PvallocDiesWhenRealtime) {
187 auto Func = []() { EXPECT_NE(pvalloc(size: 2048), nullptr); };
188 ExpectRealtimeDeath(Func, intercepted_method_name: "pvalloc");
189 ExpectNonRealtimeSurvival(Func);
190}
191#endif
192
193TEST(TestRtsanInterceptors, MmapDiesWhenRealtime) {
194 auto Func = []() {
195 void *_ = mmap(addr: nullptr, len: 8, PROT_READ | PROT_WRITE,
196 MAP_PRIVATE | MAP_ANONYMOUS, fd: -1, offset: 0);
197 };
198 ExpectRealtimeDeath(Func, MAYBE_APPEND_64("mmap"));
199 ExpectNonRealtimeSurvival(Func);
200}
201
202#if SANITIZER_LINUX
203TEST(TestRtsanInterceptors, MremapDiesWhenRealtime) {
204 void *addr = mmap(addr: nullptr, len: 8, PROT_READ | PROT_WRITE,
205 MAP_PRIVATE | MAP_ANONYMOUS, fd: -1, offset: 0);
206 auto Func = [addr]() { void *_ = mremap(addr: addr, old_len: 8, new_len: 16, flags: 0); };
207 ExpectRealtimeDeath(Func, intercepted_method_name: "mremap");
208 ExpectNonRealtimeSurvival(Func);
209}
210#endif
211
212TEST(TestRtsanInterceptors, MunmapDiesWhenRealtime) {
213 void *ptr = mmap(addr: nullptr, len: 8, PROT_READ | PROT_WRITE,
214 MAP_PRIVATE | MAP_ANONYMOUS, fd: -1, offset: 0);
215 EXPECT_NE(ptr, nullptr);
216 auto Func = [ptr]() { munmap(addr: ptr, len: 8); };
217 printf(format: "Right before death munmap\n");
218 ExpectRealtimeDeath(Func, intercepted_method_name: "munmap");
219 ExpectNonRealtimeSurvival(Func);
220}
221
222class RtsanOpenedMmapTest : public RtsanFileTest {
223protected:
224 void SetUp() override {
225 RtsanFileTest::SetUp();
226 file = fopen(filename: GetTemporaryFilePath(), modes: "w+");
227 ASSERT_THAT(file, Ne(nullptr));
228 fd = fileno(stream: file);
229 ASSERT_THAT(fd, Ne(-1));
230 int ret = ftruncate(GetOpenFd(), size);
231 ASSERT_THAT(ret, Ne(-1));
232 addr =
233 mmap(addr: nullptr, len: size, PROT_READ | PROT_WRITE, MAP_SHARED, fd: GetOpenFd(), offset: 0);
234 ASSERT_THAT(addr, Ne(MAP_FAILED));
235 ASSERT_THAT(addr, Ne(nullptr));
236 }
237
238 void TearDown() override {
239 if (addr != nullptr && addr != MAP_FAILED)
240 munmap(addr: addr, len: size);
241 RtsanFileTest::TearDown();
242 }
243
244 void *GetAddr() { return addr; }
245 static constexpr size_t GetSize() { return size; }
246
247 int GetOpenFd() { return fd; }
248
249private:
250 void *addr = nullptr;
251 static constexpr size_t size = 4096;
252 FILE *file = nullptr;
253 int fd = -1;
254};
255
256#if !SANITIZER_APPLE
257TEST_F(RtsanOpenedMmapTest, MadviseDiesWhenRealtime) {
258 auto Func = [this]() { madvise(GetAddr(), GetSize(), MADV_NORMAL); };
259 ExpectRealtimeDeath(Func, intercepted_method_name: "madvise");
260 ExpectNonRealtimeSurvival(Func);
261}
262
263TEST_F(RtsanOpenedMmapTest, PosixMadviseDiesWhenRealtime) {
264 auto Func = [this]() {
265 posix_madvise(GetAddr(), GetSize(), POSIX_MADV_NORMAL);
266 };
267 ExpectRealtimeDeath(Func, intercepted_method_name: "posix_madvise");
268 ExpectNonRealtimeSurvival(Func);
269}
270#endif
271
272TEST_F(RtsanOpenedMmapTest, MprotectDiesWhenRealtime) {
273 auto Func = [this]() { mprotect(GetAddr(), GetSize(), PROT_READ); };
274 ExpectRealtimeDeath(Func, intercepted_method_name: "mprotect");
275 ExpectNonRealtimeSurvival(Func);
276}
277
278TEST_F(RtsanOpenedMmapTest, MsyncDiesWhenRealtime) {
279 auto Func = [this]() { msync(GetAddr(), GetSize(), MS_INVALIDATE); };
280 ExpectRealtimeDeath(Func, intercepted_method_name: "msync");
281 ExpectNonRealtimeSurvival(Func);
282}
283
284TEST_F(RtsanOpenedMmapTest, MincoreDiesWhenRealtime) {
285#if SANITIZER_APPLE
286 std::vector<char> vec(GetSize() / 1024);
287#else
288 std::vector<unsigned char> vec(GetSize() / 1024);
289#endif
290 auto Func = [this, &vec]() { mincore(GetAddr(), GetSize(), vec.data()); };
291 ExpectRealtimeDeath(Func, intercepted_method_name: "mincore");
292 ExpectNonRealtimeSurvival(Func);
293}
294
295TEST(TestRtsanInterceptors, ShmOpenDiesWhenRealtime) {
296 auto Func = []() { shm_open(name: "/rtsan_test_shm", O_CREAT | O_RDWR, mode: 0); };
297 ExpectRealtimeDeath(Func, intercepted_method_name: "shm_open");
298 ExpectNonRealtimeSurvival(Func);
299}
300
301TEST(TestRtsanInterceptors, ShmUnlinkDiesWhenRealtime) {
302 auto Func = []() { shm_unlink(name: "/rtsan_test_shm"); };
303 ExpectRealtimeDeath(Func, intercepted_method_name: "shm_unlink");
304 ExpectNonRealtimeSurvival(Func);
305}
306
307#if !SANITIZER_APPLE
308TEST(TestRtsanInterceptors, MemfdCreateDiesWhenRealtime) {
309 auto Func = []() { memfd_create(name: "/rtsan_test_memfd_create", MFD_CLOEXEC); };
310 ExpectRealtimeDeath(Func, intercepted_method_name: "memfd_create");
311 ExpectNonRealtimeSurvival(Func);
312}
313#endif
314
315/*
316 Sleeping
317*/
318
319TEST(TestRtsanInterceptors, SleepDiesWhenRealtime) {
320 auto Func = []() { sleep(0u); };
321 ExpectRealtimeDeath(Func, intercepted_method_name: "sleep");
322 ExpectNonRealtimeSurvival(Func);
323}
324
325TEST(TestRtsanInterceptors, UsleepDiesWhenRealtime) {
326 auto Func = []() { usleep(1u); };
327 ExpectRealtimeDeath(Func, intercepted_method_name: "usleep");
328 ExpectNonRealtimeSurvival(Func);
329}
330
331TEST(TestRtsanInterceptors, NanosleepDiesWhenRealtime) {
332 auto Func = []() {
333 timespec T{};
334 nanosleep(requested_time: &T, remaining: &T);
335 };
336 ExpectRealtimeDeath(Func, intercepted_method_name: "nanosleep");
337 ExpectNonRealtimeSurvival(Func);
338}
339
340TEST(TestRtsanInterceptors, SchedYieldDiesWhenRealtime) {
341 auto Func = []() { sched_yield(); };
342 ExpectRealtimeDeath(Func, intercepted_method_name: "sched_yield");
343 ExpectNonRealtimeSurvival(Func);
344}
345
346#if SANITIZER_LINUX
347TEST(TestRtsanInterceptors, SchedGetaffinityDiesWhenRealtime) {
348 cpu_set_t set{};
349 auto Func = [&set]() { sched_getaffinity(pid: 0, cpusetsize: sizeof(set), cpuset: &set); };
350 ExpectRealtimeDeath(Func, intercepted_method_name: "sched_getaffinity");
351 ExpectNonRealtimeSurvival(Func);
352}
353
354TEST(TestRtsanInterceptors, SchedSetaffinityDiesWhenRealtime) {
355 cpu_set_t set{};
356 auto Func = [&set]() { sched_setaffinity(pid: 0, cpusetsize: sizeof(set), cpuset: &set); };
357 ExpectRealtimeDeath(Func, intercepted_method_name: "sched_setaffinity");
358 ExpectNonRealtimeSurvival(Func);
359}
360#endif
361
362/*
363 Filesystem
364*/
365
366TEST_F(RtsanFileTest, OpenDiesWhenRealtime) {
367 auto Func = [this]() { open(GetTemporaryFilePath(), O_RDONLY); };
368 ExpectRealtimeDeath(Func, MAYBE_APPEND_64("open"));
369 ExpectNonRealtimeSurvival(Func);
370}
371
372TEST_F(RtsanFileTest, OpenatDiesWhenRealtime) {
373 auto Func = [this]() { openat(0, GetTemporaryFilePath(), O_RDONLY); };
374 ExpectRealtimeDeath(Func, MAYBE_APPEND_64("openat"));
375 ExpectNonRealtimeSurvival(Func);
376}
377
378TEST_F(RtsanFileTest, OpenCreatesFileWithProperMode) {
379 const mode_t existing_umask = umask(mask: 0);
380 umask(mask: existing_umask);
381
382 const int mode = S_IRGRP | S_IROTH | S_IRUSR | S_IWUSR;
383
384 const int fd = open(GetTemporaryFilePath(), O_CREAT | O_WRONLY, mode);
385 ASSERT_THAT(fd, Ne(-1));
386 close(fd);
387
388 struct stat st;
389 ASSERT_THAT(stat(GetTemporaryFilePath(), &st), Eq(0));
390
391 // Mask st_mode to get permission bits only
392 const mode_t actual_mode = st.st_mode & 0777;
393 const mode_t expected_mode = mode & ~existing_umask;
394 ASSERT_THAT(actual_mode, Eq(expected_mode));
395}
396
397TEST_F(RtsanFileTest, CreatDiesWhenRealtime) {
398 auto Func = [this]() { creat(GetTemporaryFilePath(), S_IWOTH | S_IROTH); };
399 ExpectRealtimeDeath(Func, MAYBE_APPEND_64("creat"));
400 ExpectNonRealtimeSurvival(Func);
401}
402
403TEST(TestRtsanInterceptors, FcntlDiesWhenRealtime) {
404 auto Func = []() { fcntl(fd: 0, F_GETFL); };
405 ExpectRealtimeDeath(Func, MAYBE_APPEND_64("fcntl"));
406 ExpectNonRealtimeSurvival(Func);
407}
408
409TEST_F(RtsanFileTest, FcntlFlockDiesWhenRealtime) {
410 int fd = creat(GetTemporaryFilePath(), S_IRUSR | S_IWUSR);
411 ASSERT_THAT(fd, Ne(-1));
412
413 auto Func = [fd]() {
414 struct flock lock{};
415 lock.l_type = F_RDLCK;
416 lock.l_whence = SEEK_SET;
417 lock.l_start = 0;
418 lock.l_len = 0;
419 lock.l_pid = ::getpid();
420
421 ASSERT_THAT(fcntl(fd: fd, F_GETLK, &lock), Eq(0));
422 ASSERT_THAT(lock.l_type, F_UNLCK);
423 };
424 ExpectRealtimeDeath(Func, MAYBE_APPEND_64("fcntl"));
425 ExpectNonRealtimeSurvival(Func);
426
427 close(fd);
428}
429
430TEST_F(RtsanFileTest, FcntlSetFdDiesWhenRealtime) {
431 int fd = creat(GetTemporaryFilePath(), S_IRUSR | S_IWUSR);
432 ASSERT_THAT(fd, Ne(-1));
433
434 auto Func = [fd]() {
435 int old_flags = fcntl(fd: fd, F_GETFD);
436 ASSERT_THAT(fcntl(fd: fd, F_SETFD, FD_CLOEXEC), Eq(0));
437
438 int flags = fcntl(fd: fd, F_GETFD);
439 ASSERT_THAT(flags, Ne(-1));
440 ASSERT_THAT(flags & FD_CLOEXEC, Eq(FD_CLOEXEC));
441
442 ASSERT_THAT(fcntl(fd: fd, F_SETFD, old_flags), Eq(0));
443 ASSERT_THAT(fcntl(fd: fd, F_GETFD), Eq(old_flags));
444 };
445
446 ExpectRealtimeDeath(Func, MAYBE_APPEND_64("fcntl"));
447 ExpectNonRealtimeSurvival(Func);
448
449 close(fd);
450}
451
452TEST(TestRtsanInterceptors, CloseDiesWhenRealtime) {
453 auto Func = []() { close(0); };
454 ExpectRealtimeDeath(Func, intercepted_method_name: "close");
455 ExpectNonRealtimeSurvival(Func);
456}
457
458TEST(TestRtsanInterceptors, ChdirDiesWhenRealtime) {
459 auto Func = []() { chdir("."); };
460 ExpectRealtimeDeath(Func, intercepted_method_name: "chdir");
461 ExpectNonRealtimeSurvival(Func);
462}
463
464TEST(TestRtsanInterceptors, FchdirDiesWhenRealtime) {
465 auto Func = []() { fchdir(0); };
466 ExpectRealtimeDeath(Func, intercepted_method_name: "fchdir");
467 ExpectNonRealtimeSurvival(Func);
468}
469
470#if SANITIZER_INTERCEPT_READLINK
471TEST(TestRtsanInterceptors, ReadlinkDiesWhenRealtime) {
472 char buf[1024];
473 auto Func = [&buf]() { readlink("/proc/self", buf, sizeof(buf)); };
474 ExpectRealtimeDeath(Func, intercepted_method_name: "readlink");
475 ExpectNonRealtimeSurvival(Func);
476}
477#endif
478
479#if SANITIZER_INTERCEPT_READLINKAT
480TEST(TestRtsanInterceptors, ReadlinkatDiesWhenRealtime) {
481 char buf[1024];
482 auto Func = [&buf]() { readlinkat(0, "/proc/self", buf, sizeof(buf)); };
483 ExpectRealtimeDeath(Func, intercepted_method_name: "readlinkat");
484 ExpectNonRealtimeSurvival(Func);
485}
486#endif
487
488TEST_F(RtsanFileTest, FopenDiesWhenRealtime) {
489 auto Func = [this]() {
490 FILE *f = fopen(GetTemporaryFilePath(), "w");
491 EXPECT_THAT(f, Ne(nullptr));
492 };
493
494 ExpectRealtimeDeath(Func, MAYBE_APPEND_64("fopen"));
495 ExpectNonRealtimeSurvival(Func);
496}
497
498#if SANITIZER_INTERCEPT_FOPENCOOKIE
499TEST_F(RtsanFileTest, FopenCookieDieWhenRealtime) {
500 FILE *f = fopen(GetTemporaryFilePath(), "w");
501 EXPECT_THAT(f, Ne(nullptr));
502 struct fholder {
503 FILE *fp;
504 size_t read;
505 } fh = {.fp: f, .read: 0};
506 auto CookieRead = [](void *cookie, char *buf, size_t size) {
507 fholder *p = reinterpret_cast<fholder *>(cookie);
508 p->read = fread(ptr: static_cast<void *>(buf), size: 1, n: size, stream: p->fp);
509 EXPECT_NE(0u, p->read);
510 };
511 cookie_io_functions_t funcs = {.read: (cookie_read_function_t *)&CookieRead, .write: nullptr,
512 .seek: nullptr, .close: nullptr};
513 auto Func = [&fh, &funcs]() {
514 FILE *f = fopencookie(magic_cookie: &fh, modes: "w", io_funcs: funcs);
515 EXPECT_THAT(f, Ne(nullptr));
516 };
517
518 ExpectRealtimeDeath(Func, intercepted_method_name: "fopencookie");
519 ExpectNonRealtimeSurvival(Func);
520}
521#endif
522
523#if SANITIZER_INTERCEPT_OPEN_MEMSTREAM
524TEST_F(RtsanFileTest, OpenMemstreamDiesWhenRealtime) {
525 char *buffer;
526 size_t size;
527 auto Func = [&buffer, &size]() {
528 FILE *f = open_memstream(bufloc: &buffer, sizeloc: &size);
529 EXPECT_THAT(f, Ne(nullptr));
530 };
531
532 ExpectRealtimeDeath(Func, intercepted_method_name: "open_memstream");
533 ExpectNonRealtimeSurvival(Func);
534}
535
536TEST_F(RtsanFileTest, FmemOpenDiesWhenRealtime) {
537 char buffer[1024];
538 auto Func = [&buffer]() {
539 FILE *f = fmemopen(s: &buffer, len: sizeof(buffer), modes: "w");
540 EXPECT_THAT(f, Ne(nullptr));
541 };
542
543 ExpectRealtimeDeath(Func, intercepted_method_name: "fmemopen");
544 ExpectNonRealtimeSurvival(Func);
545}
546#endif
547
548#if SANITIZER_INTERCEPT_SETVBUF
549TEST_F(RtsanFileTest, SetbufDieWhenRealtime) {
550 char buffer[BUFSIZ];
551 FILE *f = fopen(GetTemporaryFilePath(), "w");
552 EXPECT_THAT(f, Ne(nullptr));
553
554 auto Func = [f, &buffer]() { setbuf(stream: f, buf: buffer); };
555
556 ExpectRealtimeDeath(Func, intercepted_method_name: "setbuf");
557 ExpectNonRealtimeSurvival(Func);
558}
559
560TEST_F(RtsanFileTest, SetvbufDieWhenRealtime) {
561 char buffer[1024];
562 size_t size = sizeof(buffer);
563 FILE *f = fopen(GetTemporaryFilePath(), "w");
564 EXPECT_THAT(f, Ne(nullptr));
565
566 auto Func = [f, &buffer, size]() {
567 int r = setvbuf(stream: f, buf: buffer, _IOFBF, n: size);
568 EXPECT_THAT(r, Eq(0));
569 };
570
571 ExpectRealtimeDeath(Func, intercepted_method_name: "setvbuf");
572 ExpectNonRealtimeSurvival(Func);
573}
574
575TEST_F(RtsanFileTest, SetlinebufDieWhenRealtime) {
576 FILE *f = fopen(GetTemporaryFilePath(), "w");
577 EXPECT_THAT(f, Ne(nullptr));
578
579 auto Func = [f]() { setlinebuf(f); };
580
581 ExpectRealtimeDeath(Func, intercepted_method_name: "setlinebuf");
582 ExpectNonRealtimeSurvival(Func);
583}
584
585TEST_F(RtsanFileTest, SetbufferDieWhenRealtime) {
586 char buffer[1024];
587 size_t size = sizeof(buffer);
588 FILE *f = fopen(GetTemporaryFilePath(), "w");
589 EXPECT_THAT(f, Ne(nullptr));
590
591 auto Func = [f, &buffer, size]() { setbuffer(stream: f, buf: buffer, size: size); };
592
593 ExpectRealtimeDeath(Func, intercepted_method_name: "setbuffer");
594 ExpectNonRealtimeSurvival(Func);
595}
596#endif
597
598class RtsanOpenedFileTest : public RtsanFileTest {
599protected:
600 void SetUp() override {
601 RtsanFileTest::SetUp();
602 file = fopen(filename: GetTemporaryFilePath(), modes: "w");
603 ASSERT_THAT(file, Ne(nullptr));
604 fd = fileno(stream: file);
605 ASSERT_THAT(fd, Ne(-1));
606 }
607
608 void TearDown() override {
609 if (file != nullptr)
610 fclose(stream: file);
611 RtsanFileTest::TearDown();
612 }
613
614 FILE *GetOpenFile() { return file; }
615
616 int GetOpenFd() { return fd; }
617
618private:
619 FILE *file = nullptr;
620 int fd = -1;
621};
622
623#if SANITIZER_INTERCEPT_FSEEK
624TEST_F(RtsanOpenedFileTest, FgetposDieWhenRealtime) {
625 auto Func = [this]() {
626 fpos_t pos;
627 int ret = fgetpos(GetOpenFile(), &pos);
628 ASSERT_THAT(ret, Eq(0));
629 };
630
631 ExpectRealtimeDeath(Func, MAYBE_APPEND_64("fgetpos"));
632 ExpectNonRealtimeSurvival(Func);
633}
634
635TEST_F(RtsanOpenedFileTest, FsetposDieWhenRealtime) {
636 fpos_t pos;
637 int ret = fgetpos(GetOpenFile(), &pos);
638 ASSERT_THAT(ret, Eq(0));
639 auto Func = [this, pos]() {
640 int ret = fsetpos(GetOpenFile(), &pos);
641 ASSERT_THAT(ret, Eq(0));
642 };
643
644 ExpectRealtimeDeath(Func, MAYBE_APPEND_64("fsetpos"));
645 ExpectNonRealtimeSurvival(Func);
646}
647
648TEST_F(RtsanOpenedFileTest, FseekDieWhenRealtime) {
649 auto Func = [this]() {
650 int ret = fseek(GetOpenFile(), 0, SEEK_CUR);
651 ASSERT_THAT(ret, Eq(0));
652 };
653
654 ExpectRealtimeDeath(Func, intercepted_method_name: "fseek");
655 ExpectNonRealtimeSurvival(Func);
656}
657
658TEST_F(RtsanOpenedFileTest, FseekoDieWhenRealtime) {
659 auto Func = [this]() {
660 int ret = fseeko(GetOpenFile(), 0, SEEK_CUR);
661 ASSERT_THAT(ret, Eq(0));
662 };
663
664 ExpectRealtimeDeath(Func, MAYBE_APPEND_64("fseeko"));
665 ExpectNonRealtimeSurvival(Func);
666}
667
668TEST_F(RtsanOpenedFileTest, FtellDieWhenRealtime) {
669 auto Func = [this]() {
670 long ret = ftell(GetOpenFile());
671 ASSERT_THAT(ret, Eq(0));
672 };
673
674 ExpectRealtimeDeath(Func, intercepted_method_name: "ftell");
675 ExpectNonRealtimeSurvival(Func);
676}
677
678TEST_F(RtsanOpenedFileTest, FtelloDieWhenRealtime) {
679 auto Func = [this]() {
680 off_t ret = ftello(GetOpenFile());
681 ASSERT_THAT(ret, Eq(0));
682 };
683
684 ExpectRealtimeDeath(Func, MAYBE_APPEND_64("ftello"));
685 ExpectNonRealtimeSurvival(Func);
686}
687
688TEST_F(RtsanOpenedFileTest, RewindDieWhenRealtime) {
689 int end = fseek(GetOpenFile(), 0, SEEK_END);
690 EXPECT_THAT(end, Eq(0));
691 auto Func = [this]() { rewind(GetOpenFile()); };
692
693 ExpectRealtimeDeath(Func, intercepted_method_name: "rewind");
694 ExpectNonRealtimeSurvival(Func);
695}
696#endif
697
698TEST(TestRtsanInterceptors, IoctlDiesWhenRealtime) {
699 auto Func = []() { ioctl(fd: 0, FIONREAD); };
700 ExpectRealtimeDeath(Func, intercepted_method_name: "ioctl");
701 ExpectNonRealtimeSurvival(Func);
702}
703
704TEST_F(RtsanOpenedFileTest, IoctlBehavesWithOutputArg) {
705 int arg{};
706 ioctl(GetOpenFd(), FIONREAD, &arg);
707
708 EXPECT_THAT(arg, Ge(0));
709}
710
711TEST_F(RtsanOpenedFileTest, FdopenDiesWhenRealtime) {
712 auto Func = [&]() {
713 FILE *f = fdopen(GetOpenFd(), "w");
714 EXPECT_THAT(f, Ne(nullptr));
715 };
716
717 ExpectRealtimeDeath(Func, intercepted_method_name: "fdopen");
718 ExpectNonRealtimeSurvival(Func);
719}
720
721TEST_F(RtsanOpenedFileTest, FreopenDiesWhenRealtime) {
722 auto Func = [&]() {
723 FILE *newfile = freopen(GetTemporaryFilePath(), "w", GetOpenFile());
724 EXPECT_THAT(newfile, Ne(nullptr));
725 };
726
727 ExpectRealtimeDeath(Func, MAYBE_APPEND_64("freopen"));
728 ExpectNonRealtimeSurvival(Func);
729}
730
731TEST(TestRtsanInterceptors, IoctlBehavesWithOutputPointer) {
732 // These initial checks just see if we CAN run these tests.
733 // If we can't (can't open a socket, or can't find an interface, just
734 // gracefully skip.
735 int sock = socket(AF_INET, SOCK_STREAM, protocol: 0);
736 if (sock == -1) {
737 perror(s: "socket");
738 GTEST_SKIP();
739 }
740
741 struct ifaddrs *ifaddr = nullptr;
742 if (getifaddrs(ifap: &ifaddr) == -1 || ifaddr == nullptr) {
743 perror(s: "getifaddrs");
744 close(sock);
745 GTEST_SKIP();
746 }
747
748 struct ifreq ifr{};
749 strncpy(ifr.ifr_name, ifaddr->ifa_name, IFNAMSIZ - 1);
750
751 int retval = ioctl(fd: sock, SIOCGIFADDR, &ifr);
752 if (retval == -1) {
753 perror(s: "ioctl");
754 close(sock);
755 freeifaddrs(ifa: ifaddr);
756 FAIL();
757 }
758
759 freeifaddrs(ifa: ifaddr);
760 close(sock);
761
762 ASSERT_THAT(ifr.ifr_addr.sa_data, NotNull());
763 ASSERT_THAT(ifr.ifr_addr.sa_family, Eq(AF_INET));
764}
765
766TEST_F(RtsanOpenedFileTest, LseekDiesWhenRealtime) {
767 auto Func = [this]() { lseek(GetOpenFd(), 0, SEEK_SET); };
768 ExpectRealtimeDeath(Func, MAYBE_APPEND_64("lseek"));
769 ExpectNonRealtimeSurvival(Func);
770}
771
772TEST_F(RtsanOpenedFileTest, DupDiesWhenRealtime) {
773 auto Func = [this]() { dup(GetOpenFd()); };
774 ExpectRealtimeDeath(Func, intercepted_method_name: "dup");
775 ExpectNonRealtimeSurvival(Func);
776}
777
778TEST_F(RtsanOpenedFileTest, Dup2DiesWhenRealtime) {
779 auto Func = [this]() { dup2(GetOpenFd(), 0); };
780 ExpectRealtimeDeath(Func, intercepted_method_name: "dup2");
781 ExpectNonRealtimeSurvival(Func);
782}
783
784TEST_F(RtsanFileTest, ChmodDiesWhenRealtime) {
785 auto Func = [this]() { chmod(GetTemporaryFilePath(), 0777); };
786 ExpectRealtimeDeath(Func, intercepted_method_name: "chmod");
787 ExpectNonRealtimeSurvival(Func);
788}
789
790TEST_F(RtsanOpenedFileTest, FchmodDiesWhenRealtime) {
791 auto Func = [this]() { fchmod(GetOpenFd(), 0777); };
792 ExpectRealtimeDeath(Func, intercepted_method_name: "fchmod");
793 ExpectNonRealtimeSurvival(Func);
794}
795
796TEST(TestRtsanInterceptors, UmaskDiesWhenRealtime) {
797 auto Func = []() { umask(mask: 0); };
798 ExpectRealtimeDeath(Func, intercepted_method_name: "umask");
799 ExpectNonRealtimeSurvival(Func);
800}
801
802#if SANITIZER_INTERCEPT_PROCESS_VM_READV
803TEST(TestRtsanInterceptors, ProcessVmReadvDiesWhenRealtime) {
804 char stack[1024];
805 int p;
806 iovec lcl{.iov_base: &stack, .iov_len: sizeof(stack)};
807 iovec rmt{.iov_base: &p, .iov_len: sizeof(p)};
808 auto Func = [&lcl, &rmt]() { process_vm_readv(pid: 0, lvec: &lcl, liovcnt: 1, rvec: &rmt, riovcnt: 1, flags: 0); };
809 ExpectRealtimeDeath(Func, intercepted_method_name: "process_vm_readv");
810 ExpectNonRealtimeSurvival(Func);
811}
812
813TEST(TestRtsanInterceptors, ProcessVmWritevDiesWhenRealtime) {
814 char stack[1024];
815 int p;
816 iovec lcl{.iov_base: &p, .iov_len: sizeof(p)};
817 iovec rmt{.iov_base: &stack, .iov_len: sizeof(stack)};
818 auto Func = [&lcl, &rmt]() { process_vm_writev(pid: 0, lvec: &lcl, liovcnt: 1, rvec: &rmt, riovcnt: 1, flags: 0); };
819 ExpectRealtimeDeath(Func, intercepted_method_name: "process_vm_writev");
820 ExpectNonRealtimeSurvival(Func);
821}
822#endif
823
824class RtsanDirectoryTest : public ::testing::Test {
825protected:
826 void SetUp() override {
827 const ::testing::TestInfo *const test_info =
828 ::testing::UnitTest::GetInstance()->current_test_info();
829 directory_path_ = std::string("/tmp/rtsan_temp_dir_") + test_info->name();
830 RemoveTemporaryDirectory();
831 }
832
833 const char *GetTemporaryDirectoryPath() const {
834 return directory_path_.c_str();
835 }
836
837 void TearDown() override { RemoveTemporaryDirectory(); }
838
839private:
840 void RemoveTemporaryDirectory() const {
841 std::remove(filename: GetTemporaryDirectoryPath());
842 }
843 std::string directory_path_;
844};
845
846TEST_F(RtsanDirectoryTest, MkdirDiesWhenRealtime) {
847 auto Func = [this]() { mkdir(GetTemporaryDirectoryPath(), 0777); };
848 ExpectRealtimeDeath(Func, intercepted_method_name: "mkdir");
849 ExpectNonRealtimeSurvival(Func);
850}
851
852TEST_F(RtsanDirectoryTest, RmdirDiesWhenRealtime) {
853 // We don't actually create this directory before we try to remove it
854 // Thats OK - we are just making sure the call gets intercepted
855 auto Func = [this]() { rmdir(GetTemporaryDirectoryPath()); };
856 ExpectRealtimeDeath(Func, intercepted_method_name: "rmdir");
857 ExpectNonRealtimeSurvival(Func);
858}
859
860TEST_F(RtsanOpenedFileTest, FreadDiesWhenRealtime) {
861 auto Func = [this]() {
862 char c{};
863 fread(&c, 1, 1, GetOpenFile());
864 };
865 ExpectRealtimeDeath(Func, intercepted_method_name: "fread");
866 ExpectNonRealtimeSurvival(Func);
867}
868
869TEST_F(RtsanOpenedFileTest, FwriteDiesWhenRealtime) {
870 const char *message = "Hello, world!";
871 auto Func = [&]() { fwrite(&message, 1, 4, GetOpenFile()); };
872 ExpectRealtimeDeath(Func, intercepted_method_name: "fwrite");
873 ExpectNonRealtimeSurvival(Func);
874}
875
876TEST_F(RtsanOpenedFileTest, UnlinkDiesWhenRealtime) {
877 auto Func = [&]() { unlink(GetTemporaryFilePath()); };
878 ExpectRealtimeDeath(Func, intercepted_method_name: "unlink");
879 ExpectNonRealtimeSurvival(Func);
880}
881
882TEST_F(RtsanOpenedFileTest, UnlinkatDiesWhenRealtime) {
883 auto Func = [&]() { unlinkat(0, GetTemporaryFilePath(), 0); };
884 ExpectRealtimeDeath(Func, intercepted_method_name: "unlinkat");
885 ExpectNonRealtimeSurvival(Func);
886}
887
888TEST_F(RtsanOpenedFileTest, TruncateDiesWhenRealtime) {
889 auto Func = [&]() { truncate(GetTemporaryFilePath(), 16); };
890 ExpectRealtimeDeath(Func, MAYBE_APPEND_64("truncate"));
891 ExpectNonRealtimeSurvival(Func);
892}
893
894TEST_F(RtsanOpenedFileTest, FtruncateDiesWhenRealtime) {
895 auto Func = [&]() { ftruncate(GetOpenFd(), 16); };
896 ExpectRealtimeDeath(Func, MAYBE_APPEND_64("ftruncate"));
897 ExpectNonRealtimeSurvival(Func);
898}
899
900TEST_F(RtsanOpenedFileTest, SymlinkDiesWhenRealtime) {
901 auto Func = [&]() {
902 symlink("/tmp/rtsan_symlink_test", GetTemporaryFilePath());
903 };
904 ExpectRealtimeDeath(Func, intercepted_method_name: "symlink");
905 ExpectNonRealtimeSurvival(Func);
906}
907
908TEST_F(RtsanOpenedFileTest, SymlinkatDiesWhenRealtime) {
909 auto Func = [&]() {
910 symlinkat("/tmp/rtsan_symlinkat_test", AT_FDCWD, GetTemporaryFilePath());
911 };
912 ExpectRealtimeDeath(Func, intercepted_method_name: "symlinkat");
913 ExpectNonRealtimeSurvival(Func);
914}
915
916TEST_F(RtsanFileTest, FcloseDiesWhenRealtime) {
917 FILE *f = fopen(GetTemporaryFilePath(), "w");
918 EXPECT_THAT(f, Ne(nullptr));
919 auto Func = [f]() { fclose(stream: f); };
920 ExpectRealtimeDeath(Func, intercepted_method_name: "fclose");
921 ExpectNonRealtimeSurvival(Func);
922}
923
924TEST(TestRtsanInterceptors, PutsDiesWhenRealtime) {
925 auto Func = []() { puts(s: "Hello, world!\n"); };
926 ExpectRealtimeDeath(Func);
927 ExpectNonRealtimeSurvival(Func);
928}
929
930TEST_F(RtsanOpenedFileTest, FputsDiesWhenRealtime) {
931 auto Func = [this]() { fputs("Hello, world!\n", GetOpenFile()); };
932 ExpectRealtimeDeath(Func);
933 ExpectNonRealtimeSurvival(Func);
934}
935
936TEST_F(RtsanFileTest, FflushDiesWhenRealtime) {
937 FILE *f = fopen(GetTemporaryFilePath(), "w");
938 EXPECT_THAT(f, Ne(nullptr));
939 int written = fwrite(ptr: "abc", size: 1, n: 3, s: f);
940 EXPECT_THAT(written, Eq(3));
941 auto Func = [&f]() {
942 int res = fflush(stream: f);
943 EXPECT_THAT(res, Eq(0));
944 };
945 ExpectRealtimeDeath(Func, intercepted_method_name: "fflush");
946 ExpectNonRealtimeSurvival(Func);
947}
948
949#if SANITIZER_APPLE
950TEST_F(RtsanFileTest, FpurgeDiesWhenRealtime) {
951 FILE *f = fopen(GetTemporaryFilePath(), "w");
952 EXPECT_THAT(f, Ne(nullptr));
953 int written = fwrite("abc", 1, 3, f);
954 EXPECT_THAT(written, Eq(3));
955 auto Func = [&f]() {
956 int res = fpurge(f);
957 EXPECT_THAT(res, Eq(0));
958 };
959 ExpectRealtimeDeath(Func, "fpurge");
960 ExpectNonRealtimeSurvival(Func);
961}
962#endif
963
964TEST_F(RtsanOpenedFileTest, ReadDiesWhenRealtime) {
965 auto Func = [this]() {
966 char c{};
967 read(GetOpenFd(), &c, 1);
968 };
969 ExpectRealtimeDeath(Func, intercepted_method_name: "read");
970 ExpectNonRealtimeSurvival(Func);
971}
972
973TEST_F(RtsanOpenedFileTest, WriteDiesWhenRealtime) {
974 auto Func = [this]() {
975 char c = 'a';
976 write(GetOpenFd(), &c, 1);
977 };
978 ExpectRealtimeDeath(Func, intercepted_method_name: "write");
979 ExpectNonRealtimeSurvival(Func);
980}
981
982TEST_F(RtsanOpenedFileTest, PreadDiesWhenRealtime) {
983 auto Func = [this]() {
984 char c{};
985 pread(GetOpenFd(), &c, 1, 0);
986 };
987 ExpectRealtimeDeath(Func, MAYBE_APPEND_64("pread"));
988 ExpectNonRealtimeSurvival(Func);
989}
990
991#if SANITIZER_INTERCEPT_PREADV
992TEST_F(RtsanOpenedFileTest, PreadvDiesWhenRealtime) {
993 auto Func = [this]() {
994 char c{};
995 iovec iov{.iov_base: &c, .iov_len: sizeof(c)};
996 preadv(GetOpenFd(), &iov, 1, 0);
997 };
998 ExpectRealtimeDeath(Func, MAYBE_APPEND_64("preadv"));
999 ExpectNonRealtimeSurvival(Func);
1000}
1001#endif
1002
1003#if SANITIZER_INTERCEPT_PWRITEV
1004TEST_F(RtsanOpenedFileTest, PwritevDiesWhenRealtime) {
1005 auto Func = [this]() {
1006 char c{};
1007 iovec iov{.iov_base: &c, .iov_len: sizeof(c)};
1008 pwritev(GetOpenFd(), &iov, 1, 0);
1009 };
1010 ExpectRealtimeDeath(Func, MAYBE_APPEND_64("pwritev"));
1011 ExpectNonRealtimeSurvival(Func);
1012}
1013#endif
1014
1015TEST_F(RtsanOpenedFileTest, ReadvDiesWhenRealtime) {
1016 auto Func = [this]() {
1017 char c{};
1018 iovec iov{.iov_base: &c, .iov_len: 1};
1019 readv(GetOpenFd(), &iov, 1);
1020 };
1021 ExpectRealtimeDeath(Func, intercepted_method_name: "readv");
1022 ExpectNonRealtimeSurvival(Func);
1023}
1024
1025TEST_F(RtsanOpenedFileTest, PwriteDiesWhenRealtime) {
1026 auto Func = [this]() {
1027 char c = 'a';
1028 pwrite(GetOpenFd(), &c, 1, 0);
1029 };
1030 ExpectRealtimeDeath(Func, MAYBE_APPEND_64("pwrite"));
1031 ExpectNonRealtimeSurvival(Func);
1032}
1033
1034TEST_F(RtsanOpenedFileTest, WritevDiesWhenRealtime) {
1035 auto Func = [this]() {
1036 char c = 'a';
1037 iovec iov{.iov_base: &c, .iov_len: 1};
1038 writev(GetOpenFd(), &iov, 1);
1039 };
1040 ExpectRealtimeDeath(Func, intercepted_method_name: "writev");
1041 ExpectNonRealtimeSurvival(Func);
1042}
1043
1044/*
1045 Concurrency
1046*/
1047
1048TEST(TestRtsanInterceptors, PthreadCreateDiesWhenRealtime) {
1049 auto Func = []() {
1050 pthread_t thread{};
1051 const pthread_attr_t attr{};
1052 struct thread_info *thread_info{};
1053 pthread_create(newthread: &thread, attr: &attr, start_routine: &FakeThreadEntryPoint, arg: thread_info);
1054 };
1055 ExpectRealtimeDeath(Func, intercepted_method_name: "pthread_create");
1056 ExpectNonRealtimeSurvival(Func);
1057}
1058
1059class PthreadMutexLockTest : public ::testing::Test {
1060protected:
1061 void SetUp() override {
1062 pthread_mutex_init(mutex: &mutex, mutexattr: nullptr);
1063 is_locked = false;
1064 }
1065
1066 void TearDown() override {
1067 if (is_locked)
1068 Unlock();
1069
1070 pthread_mutex_destroy(mutex: &mutex);
1071 }
1072
1073 void Lock() {
1074 ASSERT_TRUE(!is_locked);
1075 pthread_mutex_lock(mutex: &mutex);
1076 is_locked = true;
1077 }
1078
1079 void Unlock() {
1080 ASSERT_TRUE(is_locked);
1081 pthread_mutex_unlock(mutex: &mutex);
1082 is_locked = false;
1083 }
1084
1085private:
1086 pthread_mutex_t mutex;
1087 bool is_locked;
1088};
1089
1090TEST_F(PthreadMutexLockTest, PthreadMutexLockDiesWhenRealtime) {
1091 auto Func = [this]() { Lock(); };
1092
1093 ExpectRealtimeDeath(Func, intercepted_method_name: "pthread_mutex_lock");
1094}
1095
1096TEST_F(PthreadMutexLockTest, PthreadMutexLockSurvivesWhenNotRealtime) {
1097 auto Func = [this]() { Lock(); };
1098
1099 ExpectNonRealtimeSurvival(Func);
1100}
1101
1102TEST_F(PthreadMutexLockTest, PthreadMutexUnlockDiesWhenRealtime) {
1103 Lock();
1104 auto Func = [this]() { Unlock(); };
1105
1106 ExpectRealtimeDeath(Func, intercepted_method_name: "pthread_mutex_unlock");
1107 ExpectNonRealtimeSurvival(Func);
1108}
1109
1110TEST_F(PthreadMutexLockTest, PthreadMutexUnlockSurvivesWhenNotRealtime) {
1111 Lock();
1112 auto Func = [this]() { Unlock(); };
1113
1114 ExpectNonRealtimeSurvival(Func);
1115}
1116
1117TEST(TestRtsanInterceptors, PthreadJoinDiesWhenRealtime) {
1118 pthread_t thread{};
1119 ASSERT_EQ(0,
1120 pthread_create(newthread: &thread, attr: nullptr, start_routine: &FakeThreadEntryPoint, arg: nullptr));
1121
1122 auto Func = [&thread]() { pthread_join(th: thread, thread_return: nullptr); };
1123
1124 ExpectRealtimeDeath(Func, intercepted_method_name: "pthread_join");
1125 ExpectNonRealtimeSurvival(Func);
1126}
1127
1128#if SANITIZER_APPLE
1129#pragma clang diagnostic push
1130// OSSpinLockLock is deprecated, but still in use in libc++
1131#pragma clang diagnostic ignored "-Wdeprecated-declarations"
1132#undef OSSpinLockLock
1133extern "C" {
1134typedef int32_t OSSpinLock;
1135void OSSpinLockLock(volatile OSSpinLock *__lock);
1136// _os_nospin_lock_lock may replace OSSpinLockLock due to deprecation macro.
1137typedef volatile OSSpinLock *_os_nospin_lock_t;
1138void _os_nospin_lock_lock(_os_nospin_lock_t lock);
1139}
1140
1141TEST(TestRtsanInterceptors, OsSpinLockLockDiesWhenRealtime) {
1142 auto Func = []() {
1143 OSSpinLock spin_lock{};
1144 OSSpinLockLock(&spin_lock);
1145 };
1146 ExpectRealtimeDeath(Func, "OSSpinLockLock");
1147 ExpectNonRealtimeSurvival(Func);
1148}
1149
1150TEST(TestRtsanInterceptors, OsNoSpinLockLockDiesWhenRealtime) {
1151 OSSpinLock lock{};
1152 auto Func = [&]() { _os_nospin_lock_lock(&lock); };
1153 ExpectRealtimeDeath(Func, "_os_nospin_lock_lock");
1154 ExpectNonRealtimeSurvival(Func);
1155}
1156#pragma clang diagnostic pop //"-Wdeprecated-declarations"
1157
1158TEST(TestRtsanInterceptors, OsUnfairLockLockDiesWhenRealtime) {
1159 auto Func = []() {
1160 os_unfair_lock_s unfair_lock{};
1161 os_unfair_lock_lock(&unfair_lock);
1162 };
1163 ExpectRealtimeDeath(Func, "os_unfair_lock_lock");
1164 ExpectNonRealtimeSurvival(Func);
1165}
1166#endif // SANITIZER_APPLE
1167
1168#if SANITIZER_LINUX
1169TEST(TestRtsanInterceptors, SpinLockLockDiesWhenRealtime) {
1170 pthread_spinlock_t spin_lock;
1171 pthread_spin_init(lock: &spin_lock, PTHREAD_PROCESS_SHARED);
1172 auto Func = [&]() { pthread_spin_lock(lock: &spin_lock); };
1173 ExpectRealtimeDeath(Func, intercepted_method_name: "pthread_spin_lock");
1174 ExpectNonRealtimeSurvival(Func);
1175}
1176#endif
1177
1178TEST(TestRtsanInterceptors, PthreadCondSignalDiesWhenRealtime) {
1179 pthread_cond_t cond{};
1180 ASSERT_EQ(0, pthread_cond_init(cond: &cond, cond_attr: nullptr));
1181
1182 auto Func = [&cond]() { pthread_cond_signal(cond: &cond); };
1183 ExpectRealtimeDeath(Func, intercepted_method_name: "pthread_cond_signal");
1184 ExpectNonRealtimeSurvival(Func);
1185
1186 pthread_cond_destroy(cond: &cond);
1187}
1188
1189TEST(TestRtsanInterceptors, PthreadCondBroadcastDiesWhenRealtime) {
1190 pthread_cond_t cond{};
1191 ASSERT_EQ(0, pthread_cond_init(cond: &cond, cond_attr: nullptr));
1192
1193 auto Func = [&cond]() { pthread_cond_broadcast(cond: &cond); };
1194 ExpectRealtimeDeath(Func, intercepted_method_name: "pthread_cond_broadcast");
1195 ExpectNonRealtimeSurvival(Func);
1196
1197 pthread_cond_destroy(cond: &cond);
1198}
1199
1200TEST(TestRtsanInterceptors, PthreadCondWaitDiesWhenRealtime) {
1201 pthread_cond_t cond;
1202 pthread_mutex_t mutex;
1203 ASSERT_EQ(0, pthread_cond_init(cond: &cond, cond_attr: nullptr));
1204 ASSERT_EQ(0, pthread_mutex_init(mutex: &mutex, mutexattr: nullptr));
1205
1206 auto Func = [&]() { pthread_cond_wait(cond: &cond, mutex: &mutex); };
1207 ExpectRealtimeDeath(Func, intercepted_method_name: "pthread_cond_wait");
1208 // It's very difficult to test the success case here without doing some
1209 // sleeping, which is at the mercy of the scheduler. What's really important
1210 // here is the interception - so we're only testing that for now.
1211
1212 pthread_cond_destroy(cond: &cond);
1213 pthread_mutex_destroy(mutex: &mutex);
1214}
1215
1216class PthreadRwlockTest : public ::testing::Test {
1217protected:
1218 void SetUp() override {
1219 pthread_rwlock_init(rwlock: &rw_lock, attr: nullptr);
1220 is_locked = false;
1221 }
1222
1223 void TearDown() override {
1224 if (is_locked)
1225 Unlock();
1226
1227 pthread_rwlock_destroy(rwlock: &rw_lock);
1228 }
1229
1230 void RdLock() {
1231 ASSERT_TRUE(!is_locked);
1232 pthread_rwlock_rdlock(rwlock: &rw_lock);
1233 is_locked = true;
1234 }
1235
1236 void WrLock() {
1237 ASSERT_TRUE(!is_locked);
1238 pthread_rwlock_wrlock(rwlock: &rw_lock);
1239 is_locked = true;
1240 }
1241
1242 void Unlock() {
1243 ASSERT_TRUE(is_locked);
1244 pthread_rwlock_unlock(rwlock: &rw_lock);
1245 is_locked = false;
1246 }
1247
1248private:
1249 pthread_rwlock_t rw_lock;
1250 bool is_locked;
1251};
1252
1253TEST_F(PthreadRwlockTest, PthreadRwlockRdlockDiesWhenRealtime) {
1254 auto Func = [this]() { RdLock(); };
1255 ExpectRealtimeDeath(Func, intercepted_method_name: "pthread_rwlock_rdlock");
1256}
1257
1258TEST_F(PthreadRwlockTest, PthreadRwlockRdlockSurvivesWhenNonRealtime) {
1259 auto Func = [this]() { RdLock(); };
1260 ExpectNonRealtimeSurvival(Func);
1261}
1262
1263TEST_F(PthreadRwlockTest, PthreadRwlockUnlockDiesWhenRealtime) {
1264 RdLock();
1265
1266 auto Func = [this]() { Unlock(); };
1267 ExpectRealtimeDeath(Func, intercepted_method_name: "pthread_rwlock_unlock");
1268}
1269
1270TEST_F(PthreadRwlockTest, PthreadRwlockUnlockSurvivesWhenNonRealtime) {
1271 RdLock();
1272
1273 auto Func = [this]() { Unlock(); };
1274 ExpectNonRealtimeSurvival(Func);
1275}
1276
1277TEST_F(PthreadRwlockTest, PthreadRwlockWrlockDiesWhenRealtime) {
1278 auto Func = [this]() { WrLock(); };
1279
1280 ExpectRealtimeDeath(Func, intercepted_method_name: "pthread_rwlock_wrlock");
1281}
1282
1283TEST_F(PthreadRwlockTest, PthreadRwlockWrlockSurvivesWhenNonRealtime) {
1284 auto Func = [this]() { WrLock(); };
1285
1286 ExpectNonRealtimeSurvival(Func);
1287}
1288
1289/*
1290 Sockets
1291*/
1292TEST(TestRtsanInterceptors, GetAddrInfoDiesWhenRealtime) {
1293 auto Func = []() {
1294 addrinfo *info{};
1295 getaddrinfo(name: "localhost", service: "http", req: nullptr, pai: &info);
1296 };
1297 ExpectRealtimeDeath(Func, intercepted_method_name: "getaddrinfo");
1298 ExpectNonRealtimeSurvival(Func);
1299}
1300
1301TEST(TestRtsanInterceptors, GetNameInfoDiesWhenRealtime) {
1302 auto Func = []() {
1303 char host[NI_MAXHOST];
1304 char serv[NI_MAXSERV];
1305 getnameinfo(sa: nullptr, salen: 0, host: host, NI_MAXHOST, serv: serv, NI_MAXSERV, flags: 0);
1306 };
1307 ExpectRealtimeDeath(Func, intercepted_method_name: "getnameinfo");
1308 ExpectNonRealtimeSurvival(Func);
1309}
1310
1311TEST(TestRtsanInterceptors, BindingASocketDiesWhenRealtime) {
1312 auto Func = []() { EXPECT_NE(bind(fd: kNotASocketFd, addr: nullptr, len: 0), 0); };
1313 ExpectRealtimeDeath(Func, intercepted_method_name: "bind");
1314 ExpectNonRealtimeSurvival(Func);
1315}
1316
1317TEST(TestRtsanInterceptors, ListeningOnASocketDiesWhenRealtime) {
1318 auto Func = []() { EXPECT_NE(listen(fd: kNotASocketFd, n: 0), 0); };
1319 ExpectRealtimeDeath(Func, intercepted_method_name: "listen");
1320 ExpectNonRealtimeSurvival(Func);
1321}
1322
1323TEST(TestRtsanInterceptors, AcceptingASocketDiesWhenRealtime) {
1324 auto Func = []() { EXPECT_LT(accept(fd: kNotASocketFd, addr: nullptr, addr_len: nullptr), 0); };
1325 ExpectRealtimeDeath(Func, intercepted_method_name: "accept");
1326 ExpectNonRealtimeSurvival(Func);
1327}
1328
1329#if SANITIZER_INTERCEPT_ACCEPT4
1330TEST(TestRtsanInterceptors, Accepting4ASocketDiesWhenRealtime) {
1331 auto Func = []() {
1332 EXPECT_LT(accept4(fd: kNotASocketFd, addr: nullptr, addr_len: nullptr, flags: 0), 0);
1333 };
1334 ExpectRealtimeDeath(Func, intercepted_method_name: "accept4");
1335 ExpectNonRealtimeSurvival(Func);
1336}
1337#endif
1338
1339TEST(TestRtsanInterceptors, ConnectingASocketDiesWhenRealtime) {
1340 auto Func = []() { EXPECT_NE(connect(fd: kNotASocketFd, addr: nullptr, len: 0), 0); };
1341 ExpectRealtimeDeath(Func, intercepted_method_name: "connect");
1342 ExpectNonRealtimeSurvival(Func);
1343}
1344
1345TEST(TestRtsanInterceptors, OpeningASocketDiesWhenRealtime) {
1346 auto Func = []() { socket(PF_INET, SOCK_STREAM, protocol: 0); };
1347 ExpectRealtimeDeath(Func, intercepted_method_name: "socket");
1348 ExpectNonRealtimeSurvival(Func);
1349}
1350
1351TEST(TestRtsanInterceptors, SendToASocketDiesWhenRealtime) {
1352 auto Func = []() { send(fd: 0, buf: nullptr, n: 0, flags: 0); };
1353 ExpectRealtimeDeath(Func, intercepted_method_name: "send");
1354 ExpectNonRealtimeSurvival(Func);
1355}
1356
1357TEST(TestRtsanInterceptors, SendmsgToASocketDiesWhenRealtime) {
1358 msghdr msg{};
1359 auto Func = [&]() { sendmsg(fd: 0, message: &msg, flags: 0); };
1360 ExpectRealtimeDeath(Func, intercepted_method_name: "sendmsg");
1361 ExpectNonRealtimeSurvival(Func);
1362}
1363
1364#if SANITIZER_INTERCEPT_SENDMMSG
1365TEST(TestRtsanInterceptors, SendmmsgOnASocketDiesWhenRealtime) {
1366 mmsghdr msg{};
1367 auto Func = [&]() { sendmmsg(fd: 0, vmessages: &msg, vlen: 0, flags: 0); };
1368 ExpectRealtimeDeath(Func, intercepted_method_name: "sendmmsg");
1369 ExpectNonRealtimeSurvival(Func);
1370}
1371#endif
1372
1373TEST(TestRtsanInterceptors, SendtoToASocketDiesWhenRealtime) {
1374 sockaddr addr{};
1375 socklen_t len{};
1376 auto Func = [&]() { sendto(fd: 0, buf: nullptr, n: 0, flags: 0, addr: &addr, addr_len: len); };
1377 ExpectRealtimeDeath(Func, intercepted_method_name: "sendto");
1378 ExpectNonRealtimeSurvival(Func);
1379}
1380
1381TEST(TestRtsanInterceptors, RecvFromASocketDiesWhenRealtime) {
1382 auto Func = []() { recv(fd: 0, buf: nullptr, n: 0, flags: 0); };
1383 ExpectRealtimeDeath(Func, intercepted_method_name: "recv");
1384 ExpectNonRealtimeSurvival(Func);
1385}
1386
1387TEST(TestRtsanInterceptors, RecvfromOnASocketDiesWhenRealtime) {
1388 sockaddr addr{};
1389 socklen_t len{};
1390 auto Func = [&]() { recvfrom(fd: 0, buf: nullptr, n: 0, flags: 0, addr: &addr, addr_len: &len); };
1391 ExpectRealtimeDeath(Func, intercepted_method_name: "recvfrom");
1392 ExpectNonRealtimeSurvival(Func);
1393}
1394
1395TEST(TestRtsanInterceptors, RecvmsgOnASocketDiesWhenRealtime) {
1396 msghdr msg{};
1397 auto Func = [&]() { recvmsg(fd: 0, message: &msg, flags: 0); };
1398 ExpectRealtimeDeath(Func, intercepted_method_name: "recvmsg");
1399 ExpectNonRealtimeSurvival(Func);
1400}
1401
1402#if SANITIZER_INTERCEPT_RECVMMSG
1403TEST(TestRtsanInterceptors, RecvmmsgOnASocketDiesWhenRealtime) {
1404 mmsghdr msg{};
1405 auto Func = [&]() { recvmmsg(fd: 0, vmessages: &msg, vlen: 0, flags: 0, tmo: nullptr); };
1406 ExpectRealtimeDeath(Func, intercepted_method_name: "recvmmsg");
1407 ExpectNonRealtimeSurvival(Func);
1408}
1409#endif
1410
1411TEST(TestRtsanInterceptors, ShutdownOnASocketDiesWhenRealtime) {
1412 auto Func = [&]() { shutdown(fd: 0, how: 0); };
1413 ExpectRealtimeDeath(Func, intercepted_method_name: "shutdown");
1414 ExpectNonRealtimeSurvival(Func);
1415}
1416
1417#if SANITIZER_INTERCEPT_GETSOCKNAME
1418TEST(TestRtsanInterceptors, GetsocknameOnASocketDiesWhenRealtime) {
1419 sockaddr addr{};
1420 socklen_t len{};
1421 auto Func = [&]() { getsockname(fd: 0, addr: &addr, len: &len); };
1422 ExpectRealtimeDeath(Func, intercepted_method_name: "getsockname");
1423 ExpectNonRealtimeSurvival(Func);
1424}
1425#endif
1426
1427#if SANITIZER_INTERCEPT_GETPEERNAME
1428TEST(TestRtsanInterceptors, GetpeernameOnASocketDiesWhenRealtime) {
1429 sockaddr addr{};
1430 socklen_t len{};
1431 auto Func = [&]() { getpeername(fd: 0, addr: &addr, len: &len); };
1432 ExpectRealtimeDeath(Func, intercepted_method_name: "getpeername");
1433 ExpectNonRealtimeSurvival(Func);
1434}
1435#endif
1436
1437#if SANITIZER_INTERCEPT_GETSOCKOPT
1438TEST(TestRtsanInterceptors, GetsockoptOnASocketDiesWhenRealtime) {
1439 int val = 0;
1440 socklen_t len = static_cast<socklen_t>(sizeof(val));
1441 auto Func = [&val, &len]() {
1442 getsockopt(fd: 0, SOL_SOCKET, SO_REUSEADDR, optval: &val, optlen: &len);
1443 };
1444 ExpectRealtimeDeath(Func, intercepted_method_name: "getsockopt");
1445 ExpectNonRealtimeSurvival(Func);
1446}
1447
1448TEST(TestRtsanInterceptors, SetsockoptOnASocketDiesWhenRealtime) {
1449 int val = 0;
1450 socklen_t len = static_cast<socklen_t>(sizeof(val));
1451 auto Func = [&val, &len]() {
1452 setsockopt(fd: 0, SOL_SOCKET, SO_REUSEADDR, optval: &val, optlen: len);
1453 };
1454 ExpectRealtimeDeath(Func, intercepted_method_name: "setsockopt");
1455 ExpectNonRealtimeSurvival(Func);
1456}
1457#endif
1458
1459TEST(TestRtsanInterceptors, SocketpairDiesWhenRealtime) {
1460 int pair[2]{};
1461 auto Func = [&pair]() { socketpair(domain: 0, type: 0, protocol: 0, fds: pair); };
1462 ExpectRealtimeDeath(Func, intercepted_method_name: "socketpair");
1463 ExpectNonRealtimeSurvival(Func);
1464}
1465
1466/*
1467 I/O Multiplexing
1468*/
1469
1470TEST(TestRtsanInterceptors, PollDiesWhenRealtime) {
1471 struct pollfd fds[1];
1472 fds[0].fd = 0;
1473 fds[0].events = POLLIN;
1474
1475 auto Func = [&fds]() { poll(fds: fds, nfds: 1, timeout: 0); };
1476
1477 ExpectRealtimeDeath(Func, intercepted_method_name: "poll");
1478 ExpectNonRealtimeSurvival(Func);
1479}
1480
1481#if !SANITIZER_APPLE
1482// FIXME: This should work on Darwin as well
1483// see the comment near the interceptor
1484TEST(TestRtsanInterceptors, SelectDiesWhenRealtime) {
1485 fd_set readfds;
1486 FD_ZERO(&readfds);
1487 FD_SET(0, &readfds);
1488 struct timeval timeout = {.tv_sec: 0, .tv_usec: 0};
1489
1490 auto Func = [&readfds, &timeout]() {
1491 select(nfds: 1, readfds: &readfds, writefds: nullptr, exceptfds: nullptr, timeout: &timeout);
1492 };
1493 ExpectRealtimeDeath(Func, intercepted_method_name: "select");
1494 ExpectNonRealtimeSurvival(Func);
1495}
1496#endif
1497
1498TEST(TestRtsanInterceptors, PSelectDiesWhenRealtime) {
1499 fd_set readfds;
1500 FD_ZERO(&readfds);
1501 FD_SET(0, &readfds);
1502 struct timespec timeout = {.tv_sec: 0, .tv_nsec: 0};
1503
1504 auto Func = [&]() {
1505 pselect(nfds: 1, readfds: &readfds, writefds: nullptr, exceptfds: nullptr, timeout: &timeout, sigmask: nullptr);
1506 };
1507 ExpectRealtimeDeath(Func, intercepted_method_name: "pselect");
1508 ExpectNonRealtimeSurvival(Func);
1509}
1510
1511#if SANITIZER_INTERCEPT_EPOLL
1512TEST(TestRtsanInterceptors, EpollCreateDiesWhenRealtime) {
1513 auto Func = []() { epoll_create(size: 1); };
1514 ExpectRealtimeDeath(Func, intercepted_method_name: "epoll_create");
1515 ExpectNonRealtimeSurvival(Func);
1516}
1517
1518TEST(TestRtsanInterceptors, EpollCreate1DiesWhenRealtime) {
1519 auto Func = []() { epoll_create1(EPOLL_CLOEXEC); };
1520 ExpectRealtimeDeath(Func, intercepted_method_name: "epoll_create1");
1521 ExpectNonRealtimeSurvival(Func);
1522}
1523
1524class EpollTest : public ::testing::Test {
1525protected:
1526 void SetUp() override {
1527 epfd = epoll_create1(EPOLL_CLOEXEC);
1528 ASSERT_GE(epfd, 0);
1529 }
1530
1531 void TearDown() override {
1532 if (epfd >= 0)
1533 close(epfd);
1534 }
1535
1536 int GetEpollFd() { return epfd; }
1537
1538private:
1539 int epfd = -1;
1540};
1541
1542TEST_F(EpollTest, EpollCtlDiesWhenRealtime) {
1543 auto Func = [this]() {
1544 struct epoll_event event = {.events = EPOLLIN, .data = {.fd = 0}};
1545 epoll_ctl(GetEpollFd(), EPOLL_CTL_ADD, 0, &event);
1546 };
1547 ExpectRealtimeDeath(Func, intercepted_method_name: "epoll_ctl");
1548 ExpectNonRealtimeSurvival(Func);
1549}
1550
1551TEST_F(EpollTest, EpollWaitDiesWhenRealtime) {
1552 auto Func = [this]() {
1553 struct epoll_event events[1];
1554 epoll_wait(GetEpollFd(), events, 1, 0);
1555 };
1556
1557 ExpectRealtimeDeath(Func, intercepted_method_name: "epoll_wait");
1558 ExpectNonRealtimeSurvival(Func);
1559}
1560
1561TEST_F(EpollTest, EpollPWaitDiesWhenRealtime) {
1562 auto Func = [this]() {
1563 struct epoll_event events[1];
1564 epoll_pwait(GetEpollFd(), events, 1, 0, nullptr);
1565 };
1566
1567 ExpectRealtimeDeath(Func, intercepted_method_name: "epoll_pwait");
1568 ExpectNonRealtimeSurvival(Func);
1569}
1570#endif // SANITIZER_INTERCEPT_EPOLL
1571
1572#if SANITIZER_INTERCEPT_PPOLL
1573TEST(TestRtsanInterceptors, PpollDiesWhenRealtime) {
1574 struct pollfd fds[1];
1575 fds[0].fd = 0;
1576 fds[0].events = POLLIN;
1577
1578 timespec ts = {.tv_sec: 0, .tv_nsec: 0};
1579
1580 auto Func = [&fds, &ts]() { ppoll(fds: fds, nfds: 1, timeout: &ts, ss: nullptr); };
1581
1582 ExpectRealtimeDeath(Func, intercepted_method_name: "ppoll");
1583 ExpectNonRealtimeSurvival(Func);
1584}
1585#endif
1586
1587#if SANITIZER_INTERCEPT_KQUEUE
1588TEST(TestRtsanInterceptors, KqueueDiesWhenRealtime) {
1589 auto Func = []() { kqueue(); };
1590 ExpectRealtimeDeath(Func, "kqueue");
1591 ExpectNonRealtimeSurvival(Func);
1592}
1593
1594class KqueueTest : public ::testing::Test {
1595protected:
1596 void SetUp() override {
1597 kq = kqueue();
1598 ASSERT_GE(kq, 0);
1599 }
1600
1601 void TearDown() override {
1602 if (kq >= 0)
1603 close(kq);
1604 }
1605
1606 int GetKqueueFd() { return kq; }
1607
1608private:
1609 int kq = -1;
1610};
1611
1612TEST_F(KqueueTest, KeventDiesWhenRealtime) {
1613 struct kevent event;
1614 EV_SET(&event, 0, EVFILT_READ, EV_ADD, 0, 0, nullptr);
1615 struct timespec timeout = {0, 0};
1616
1617 auto Func = [this, event, timeout]() {
1618 kevent(GetKqueueFd(), &event, 1, nullptr, 0, &timeout);
1619 };
1620
1621 ExpectRealtimeDeath(Func, "kevent");
1622 ExpectNonRealtimeSurvival(Func);
1623}
1624
1625TEST_F(KqueueTest, Kevent64DiesWhenRealtime) {
1626 struct kevent64_s event;
1627 EV_SET64(&event, 0, EVFILT_READ, EV_ADD, 0, 0, 0, 0, 0);
1628 struct timespec timeout = {0, 0};
1629
1630 auto Func = [this, event, timeout]() {
1631 kevent64(GetKqueueFd(), &event, 1, nullptr, 0, 0, &timeout);
1632 };
1633
1634 ExpectRealtimeDeath(Func, "kevent64");
1635 ExpectNonRealtimeSurvival(Func);
1636}
1637#endif // SANITIZER_INTERCEPT_KQUEUE
1638
1639#if SANITIZER_LINUX
1640TEST(TestRtsanInterceptors, InotifyInitDiesWhenRealtime) {
1641 auto Func = []() { inotify_init(); };
1642 ExpectRealtimeDeath(Func, intercepted_method_name: "inotify_init");
1643 ExpectNonRealtimeSurvival(Func);
1644}
1645
1646TEST(TestRtsanInterceptors, InotifyInit1DiesWhenRealtime) {
1647 auto Func = []() { inotify_init1(flags: 0); };
1648 ExpectRealtimeDeath(Func, intercepted_method_name: "inotify_init1");
1649 ExpectNonRealtimeSurvival(Func);
1650}
1651
1652TEST(TestRtsanInterceptors, InotifyAddWatchDiesWhenRealtime) {
1653 int fd = inotify_init();
1654 EXPECT_THAT(fd, Ne(-1));
1655 auto Func = [fd]() {
1656 inotify_add_watch(fd: fd, name: "/tmp/rtsan_inotify", IN_CREATE);
1657 };
1658 ExpectRealtimeDeath(Func, intercepted_method_name: "inotify_add_watch");
1659 ExpectNonRealtimeSurvival(Func);
1660}
1661
1662TEST(TestRtsanInterceptors, InotifyRmWatchDiesWhenRealtime) {
1663 int fd = inotify_init();
1664 EXPECT_THAT(fd, Ne(-1));
1665 auto Func = [fd]() { inotify_rm_watch(fd: fd, wd: -1); };
1666 ExpectRealtimeDeath(Func, intercepted_method_name: "inotify_rm_watch");
1667 ExpectNonRealtimeSurvival(Func);
1668}
1669
1670TEST(TestRtsanInterceptors, TimerfdCreateDiesWhenRealtime) {
1671 auto Func = []() { timerfd_create(CLOCK_MONOTONIC, flags: 0); };
1672 ExpectRealtimeDeath(Func, intercepted_method_name: "timerfd_create");
1673 ExpectNonRealtimeSurvival(Func);
1674}
1675
1676TEST(TestRtsanInterceptors, TimerfdSettimeDiesWhenRealtime) {
1677 int fd = timerfd_create(CLOCK_MONOTONIC, flags: 0);
1678 EXPECT_THAT(fd, Ne(-1));
1679 auto ts = itimerspec{.it_interval: {.tv_sec: 0, .tv_nsec: 0}, .it_value: {.tv_sec: 0, .tv_nsec: 0}};
1680 auto Func = [fd, ts]() { timerfd_settime(ufd: fd, flags: 0, utmr: &ts, NULL); };
1681 ExpectRealtimeDeath(Func, intercepted_method_name: "timerfd_settime");
1682 ExpectNonRealtimeSurvival(Func);
1683}
1684
1685TEST(TestRtsanInterceptors, TimerfdGettimeDiesWhenRealtime) {
1686 int fd = timerfd_create(CLOCK_MONOTONIC, flags: 0);
1687 EXPECT_THAT(fd, Ne(-1));
1688 itimerspec ts{};
1689 auto Func = [fd, &ts]() { timerfd_gettime(ufd: fd, otmr: &ts); };
1690 ExpectRealtimeDeath(Func, intercepted_method_name: "timerfd_gettime");
1691 ExpectNonRealtimeSurvival(Func);
1692}
1693
1694TEST(TestRtsanInterceptors, EventfdDiesWhenRealtime) {
1695 auto Func = []() { eventfd(EFD_CLOEXEC, flags: 0); };
1696 ExpectRealtimeDeath(Func, intercepted_method_name: "eventfd");
1697 ExpectNonRealtimeSurvival(Func);
1698}
1699#endif
1700
1701TEST(TestRtsanInterceptors, MkfifoDiesWhenRealtime) {
1702 auto Func = []() { mkfifo(path: "/tmp/rtsan_test_fifo", mode: 0); };
1703 ExpectRealtimeDeath(Func, intercepted_method_name: "mkfifo");
1704 ExpectNonRealtimeSurvival(Func);
1705}
1706
1707TEST(TestRtsanInterceptors, PipeDiesWhenRealtime) {
1708 int fds[2];
1709 auto Func = [&fds]() { pipe(fds); };
1710 ExpectRealtimeDeath(Func, intercepted_method_name: "pipe");
1711 ExpectNonRealtimeSurvival(Func);
1712}
1713
1714#if !SANITIZER_APPLE
1715TEST(TestRtsanInterceptors, Pipe2DiesWhenRealtime) {
1716 int fds[2];
1717 auto Func = [&fds]() { pipe2(fds, O_CLOEXEC); };
1718 ExpectRealtimeDeath(Func, intercepted_method_name: "pipe2");
1719 ExpectNonRealtimeSurvival(Func);
1720}
1721#endif
1722
1723#pragma clang diagnostic push
1724#pragma clang diagnostic ignored "-Wdeprecated-declarations"
1725TEST(TestRtsanInterceptors, SyscallDiesWhenRealtime) {
1726 auto Func = []() { syscall(SYS_getpid); };
1727 ExpectRealtimeDeath(Func, intercepted_method_name: "syscall");
1728 ExpectNonRealtimeSurvival(Func);
1729}
1730
1731TEST(TestRtsanInterceptors, GetPidReturnsSame) {
1732 int pid = syscall(SYS_getpid);
1733 EXPECT_THAT(pid, Ne(-1));
1734
1735 EXPECT_THAT(getpid(), Eq(pid));
1736}
1737#pragma clang diagnostic pop
1738
1739#endif // SANITIZER_POSIX
1740

source code of compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp