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

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