xref: /llvm-project/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp (revision 23763a1200edfe209d1e334d1d1ff71b2a992b3a)
11e07c480SChris Apple //===--- rtsan_test_interceptors.cpp - Realtime Sanitizer -------*- C++ -*-===//
21e07c480SChris Apple //
31e07c480SChris Apple // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
41e07c480SChris Apple // See https://llvm.org/LICENSE.txt for license information.
51e07c480SChris Apple // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
61e07c480SChris Apple //
71e07c480SChris Apple //===----------------------------------------------------------------------===//
81e07c480SChris Apple //
91e07c480SChris Apple //===----------------------------------------------------------------------===//
101e07c480SChris Apple 
119ed6f7f9SChris Apple #include "sanitizer_common/sanitizer_platform.h"
129ed6f7f9SChris Apple #if SANITIZER_POSIX
139ed6f7f9SChris Apple 
141e07c480SChris Apple #include "gtest/gtest.h"
151e07c480SChris Apple 
161e07c480SChris Apple #include "sanitizer_common/sanitizer_platform_interceptors.h"
171e07c480SChris Apple 
181e07c480SChris Apple #include "rtsan_test_utilities.h"
191e07c480SChris Apple 
201e07c480SChris Apple #if SANITIZER_APPLE
211e07c480SChris Apple #include <libkern/OSAtomic.h>
221e07c480SChris Apple #include <os/lock.h>
231e07c480SChris Apple #include <unistd.h>
241e07c480SChris Apple #endif
251e07c480SChris Apple 
261e07c480SChris Apple #if SANITIZER_INTERCEPT_MEMALIGN || SANITIZER_INTERCEPT_PVALLOC
271e07c480SChris Apple #include <malloc.h>
281e07c480SChris Apple #endif
291e07c480SChris Apple 
309c3665c8SChris Apple #if SANITIZER_INTERCEPT_EPOLL
319c3665c8SChris Apple #include <sys/epoll.h>
329c3665c8SChris Apple #endif
339c3665c8SChris Apple 
349c3665c8SChris Apple #if SANITIZER_INTERCEPT_KQUEUE
359c3665c8SChris Apple #include <sys/event.h>
369c3665c8SChris Apple #include <sys/time.h>
379c3665c8SChris Apple #endif
389c3665c8SChris Apple 
391e07c480SChris Apple #include <fcntl.h>
403a8b28f6SChris Apple #include <ifaddrs.h>
413a8b28f6SChris Apple #include <net/if.h>
428699f301SChris Apple #include <netdb.h>
439c3665c8SChris Apple #include <poll.h>
441e07c480SChris Apple #include <pthread.h>
451e07c480SChris Apple #include <stdio.h>
46f3d2e75eSDavid CARLIER #if SANITIZER_LINUX
47f3d2e75eSDavid CARLIER #include <sys/inotify.h>
48f3d2e75eSDavid CARLIER #endif
493a8b28f6SChris Apple #include <sys/ioctl.h>
5061e50b9fSChris Apple #include <sys/mman.h>
511e07c480SChris Apple #include <sys/socket.h>
524a074330SChris Apple #include <sys/stat.h>
53eae30a24SChris Apple #include <sys/syscall.h>
543a8b28f6SChris Apple #include <sys/types.h>
551e07c480SChris Apple #include <sys/uio.h>
561e07c480SChris Apple 
571e07c480SChris Apple #if _FILE_OFFSET_BITS == 64 && SANITIZER_GLIBC
58a5e18987SChris Apple // Under these conditions, some system calls are `foo64` instead of `foo`
59a5e18987SChris Apple #define MAYBE_APPEND_64(func) func "64"
601e07c480SChris Apple #else
61a5e18987SChris Apple #define MAYBE_APPEND_64(func) func
621e07c480SChris Apple #endif
631e07c480SChris Apple 
641e07c480SChris Apple using namespace testing;
651e07c480SChris Apple using namespace rtsan_testing;
661e07c480SChris Apple using namespace std::chrono_literals;
671e07c480SChris Apple 
688699f301SChris Apple // NOTE: In the socket tests we pass in bad info to the calls to ensure they
698699f301SChris Apple //       fail which is why we EXPECT_NE 0 for their return codes.
708699f301SChris Apple //       We just care that the call is intercepted
718699f301SChris Apple const int kNotASocketFd = 0;
728699f301SChris Apple 
731e07c480SChris Apple void *FakeThreadEntryPoint(void *) { return nullptr; }
741e07c480SChris Apple 
751e07c480SChris Apple class RtsanFileTest : public ::testing::Test {
761e07c480SChris Apple protected:
771e07c480SChris Apple   void SetUp() override {
781e07c480SChris Apple     const ::testing::TestInfo *const test_info =
791e07c480SChris Apple         ::testing::UnitTest::GetInstance()->current_test_info();
801e07c480SChris Apple     file_path_ = std::string("/tmp/rtsan_temporary_test_file_") +
811e07c480SChris Apple                  test_info->name() + ".txt";
821e07c480SChris Apple     RemoveTemporaryFile();
831e07c480SChris Apple   }
841e07c480SChris Apple 
851e07c480SChris Apple   // Gets a file path with the test's name in it
861e07c480SChris Apple   // This file will be removed if it exists at the end of the test
871e07c480SChris Apple   const char *GetTemporaryFilePath() const { return file_path_.c_str(); }
881e07c480SChris Apple 
891e07c480SChris Apple   void TearDown() override { RemoveTemporaryFile(); }
901e07c480SChris Apple 
911e07c480SChris Apple private:
921e07c480SChris Apple   void RemoveTemporaryFile() const { std::remove(GetTemporaryFilePath()); }
931e07c480SChris Apple   std::string file_path_;
941e07c480SChris Apple };
951e07c480SChris Apple 
961e07c480SChris Apple /*
971e07c480SChris Apple     Allocation and deallocation
981e07c480SChris Apple */
991e07c480SChris Apple 
1001e07c480SChris Apple TEST(TestRtsanInterceptors, MallocDiesWhenRealtime) {
1011e07c480SChris Apple   auto Func = []() { EXPECT_NE(nullptr, malloc(1)); };
1021e07c480SChris Apple   ExpectRealtimeDeath(Func, "malloc");
1031e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
1041e07c480SChris Apple }
1051e07c480SChris Apple 
1061e07c480SChris Apple TEST(TestRtsanInterceptors, CallocDiesWhenRealtime) {
1071e07c480SChris Apple   auto Func = []() { EXPECT_NE(nullptr, calloc(2, 4)); };
1081e07c480SChris Apple   ExpectRealtimeDeath(Func, "calloc");
1091e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
1101e07c480SChris Apple }
1111e07c480SChris Apple 
1121e07c480SChris Apple TEST(TestRtsanInterceptors, ReallocDiesWhenRealtime) {
1131e07c480SChris Apple   void *ptr_1 = malloc(1);
1141e07c480SChris Apple   auto Func = [ptr_1]() { EXPECT_NE(nullptr, realloc(ptr_1, 8)); };
1151e07c480SChris Apple   ExpectRealtimeDeath(Func, "realloc");
1161e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
1171e07c480SChris Apple }
1181e07c480SChris Apple 
1191e07c480SChris Apple #if SANITIZER_APPLE
1201e07c480SChris Apple TEST(TestRtsanInterceptors, ReallocfDiesWhenRealtime) {
1211e07c480SChris Apple   void *ptr_1 = malloc(1);
1221e07c480SChris Apple   auto Func = [ptr_1]() { EXPECT_NE(nullptr, reallocf(ptr_1, 8)); };
1231e07c480SChris Apple   ExpectRealtimeDeath(Func, "reallocf");
1241e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
1251e07c480SChris Apple }
1261e07c480SChris Apple #endif
1271e07c480SChris Apple 
1281e07c480SChris Apple TEST(TestRtsanInterceptors, VallocDiesWhenRealtime) {
1291e07c480SChris Apple   auto Func = []() { EXPECT_NE(nullptr, valloc(4)); };
1301e07c480SChris Apple   ExpectRealtimeDeath(Func, "valloc");
1311e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
1321e07c480SChris Apple }
1331e07c480SChris Apple 
1344ccd2b0cSChris Apple #if __has_builtin(__builtin_available) && SANITIZER_APPLE
1354ccd2b0cSChris Apple #define ALIGNED_ALLOC_AVAILABLE() (__builtin_available(macOS 10.15, *))
1364ccd2b0cSChris Apple #else
1374ccd2b0cSChris Apple // We are going to assume this is true until we hit systems where it isn't
1384ccd2b0cSChris Apple #define ALIGNED_ALLOC_AVAILABLE() (true)
1394ccd2b0cSChris Apple #endif
1404ccd2b0cSChris Apple 
1411e07c480SChris Apple TEST(TestRtsanInterceptors, AlignedAllocDiesWhenRealtime) {
1424ccd2b0cSChris Apple   if (ALIGNED_ALLOC_AVAILABLE()) {
1431e07c480SChris Apple     auto Func = []() { EXPECT_NE(nullptr, aligned_alloc(16, 32)); };
1441e07c480SChris Apple     ExpectRealtimeDeath(Func, "aligned_alloc");
1451e07c480SChris Apple     ExpectNonRealtimeSurvival(Func);
1461e07c480SChris Apple   }
1474ccd2b0cSChris Apple }
1481e07c480SChris Apple 
1491e07c480SChris Apple // free_sized and free_aligned_sized (both C23) are not yet supported
1501e07c480SChris Apple TEST(TestRtsanInterceptors, FreeDiesWhenRealtime) {
1511e07c480SChris Apple   void *ptr_1 = malloc(1);
1521e07c480SChris Apple   void *ptr_2 = malloc(1);
1531e07c480SChris Apple   ExpectRealtimeDeath([ptr_1]() { free(ptr_1); }, "free");
1541e07c480SChris Apple   ExpectNonRealtimeSurvival([ptr_2]() { free(ptr_2); });
1551e07c480SChris Apple 
1561e07c480SChris Apple   // Prevent malloc/free pair being optimised out
1571e07c480SChris Apple   ASSERT_NE(nullptr, ptr_1);
1581e07c480SChris Apple   ASSERT_NE(nullptr, ptr_2);
1591e07c480SChris Apple }
1601e07c480SChris Apple 
1611e07c480SChris Apple TEST(TestRtsanInterceptors, FreeSurvivesWhenRealtimeIfArgumentIsNull) {
1621e07c480SChris Apple   RealtimeInvoke([]() { free(NULL); });
1631e07c480SChris Apple   ExpectNonRealtimeSurvival([]() { free(NULL); });
1641e07c480SChris Apple }
1651e07c480SChris Apple 
1661e07c480SChris Apple TEST(TestRtsanInterceptors, PosixMemalignDiesWhenRealtime) {
1671e07c480SChris Apple   auto Func = []() {
1681e07c480SChris Apple     void *ptr;
1691e07c480SChris Apple     posix_memalign(&ptr, 4, 4);
1701e07c480SChris Apple   };
1711e07c480SChris Apple   ExpectRealtimeDeath(Func, "posix_memalign");
1721e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
1731e07c480SChris Apple }
1741e07c480SChris Apple 
1751e07c480SChris Apple #if SANITIZER_INTERCEPT_MEMALIGN
1761e07c480SChris Apple TEST(TestRtsanInterceptors, MemalignDiesWhenRealtime) {
1771e07c480SChris Apple   auto Func = []() { EXPECT_NE(memalign(2, 2048), nullptr); };
1781e07c480SChris Apple   ExpectRealtimeDeath(Func, "memalign");
1791e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
1801e07c480SChris Apple }
1811e07c480SChris Apple #endif
1821e07c480SChris Apple 
1831e07c480SChris Apple #if SANITIZER_INTERCEPT_PVALLOC
1841e07c480SChris Apple TEST(TestRtsanInterceptors, PvallocDiesWhenRealtime) {
1851e07c480SChris Apple   auto Func = []() { EXPECT_NE(pvalloc(2048), nullptr); };
1861e07c480SChris Apple   ExpectRealtimeDeath(Func, "pvalloc");
1871e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
1881e07c480SChris Apple }
1891e07c480SChris Apple #endif
1901e07c480SChris Apple 
19161e50b9fSChris Apple TEST(TestRtsanInterceptors, MmapDiesWhenRealtime) {
19261e50b9fSChris Apple   auto Func = []() {
19361e50b9fSChris Apple     void *_ = mmap(nullptr, 8, PROT_READ | PROT_WRITE,
19461e50b9fSChris Apple                    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
19561e50b9fSChris Apple   };
196a5e18987SChris Apple   ExpectRealtimeDeath(Func, MAYBE_APPEND_64("mmap"));
19761e50b9fSChris Apple   ExpectNonRealtimeSurvival(Func);
19861e50b9fSChris Apple }
19961e50b9fSChris Apple 
200*23763a12SDavid CARLIER #if SANITIZER_LINUX
201*23763a12SDavid CARLIER TEST(TestRtsanInterceptors, MremapDiesWhenRealtime) {
202*23763a12SDavid CARLIER   void *addr = mmap(nullptr, 8, PROT_READ | PROT_WRITE,
203*23763a12SDavid CARLIER                     MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
204*23763a12SDavid CARLIER   auto Func = [addr]() { void *_ = mremap(addr, 8, 16, 0); };
205*23763a12SDavid CARLIER   ExpectRealtimeDeath(Func, "mremap");
206*23763a12SDavid CARLIER   ExpectNonRealtimeSurvival(Func);
207*23763a12SDavid CARLIER }
208*23763a12SDavid CARLIER #endif
209*23763a12SDavid CARLIER 
21061e50b9fSChris Apple TEST(TestRtsanInterceptors, MunmapDiesWhenRealtime) {
21161e50b9fSChris Apple   void *ptr = mmap(nullptr, 8, PROT_READ | PROT_WRITE,
21261e50b9fSChris Apple                    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
21361e50b9fSChris Apple   EXPECT_NE(ptr, nullptr);
21461e50b9fSChris Apple   auto Func = [ptr]() { munmap(ptr, 8); };
21561e50b9fSChris Apple   printf("Right before death munmap\n");
21661e50b9fSChris Apple   ExpectRealtimeDeath(Func, "munmap");
21761e50b9fSChris Apple   ExpectNonRealtimeSurvival(Func);
21861e50b9fSChris Apple }
21961e50b9fSChris Apple 
220c745ece2SDavid CARLIER class RtsanOpenedMmapTest : public RtsanFileTest {
221c745ece2SDavid CARLIER protected:
222c745ece2SDavid CARLIER   void SetUp() override {
223c745ece2SDavid CARLIER     RtsanFileTest::SetUp();
224c745ece2SDavid CARLIER     file = fopen(GetTemporaryFilePath(), "w+");
225c745ece2SDavid CARLIER     ASSERT_THAT(file, Ne(nullptr));
226c745ece2SDavid CARLIER     fd = fileno(file);
227c745ece2SDavid CARLIER     ASSERT_THAT(fd, Ne(-1));
228c745ece2SDavid CARLIER     int ret = ftruncate(GetOpenFd(), size);
229c745ece2SDavid CARLIER     ASSERT_THAT(ret, Ne(-1));
230c745ece2SDavid CARLIER     addr =
231c745ece2SDavid CARLIER         mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, GetOpenFd(), 0);
232c745ece2SDavid CARLIER     ASSERT_THAT(addr, Ne(MAP_FAILED));
233c745ece2SDavid CARLIER     ASSERT_THAT(addr, Ne(nullptr));
234c745ece2SDavid CARLIER   }
235c745ece2SDavid CARLIER 
236c745ece2SDavid CARLIER   void TearDown() override {
237c745ece2SDavid CARLIER     if (addr != nullptr && addr != MAP_FAILED)
238c745ece2SDavid CARLIER       munmap(addr, size);
239c745ece2SDavid CARLIER     RtsanFileTest::TearDown();
240c745ece2SDavid CARLIER   }
241c745ece2SDavid CARLIER 
242c745ece2SDavid CARLIER   void *GetAddr() { return addr; }
243c745ece2SDavid CARLIER   static constexpr size_t GetSize() { return size; }
244c745ece2SDavid CARLIER 
245c745ece2SDavid CARLIER   int GetOpenFd() { return fd; }
246c745ece2SDavid CARLIER 
247c745ece2SDavid CARLIER private:
248c745ece2SDavid CARLIER   void *addr = nullptr;
249c745ece2SDavid CARLIER   static constexpr size_t size = 4096;
250c745ece2SDavid CARLIER   FILE *file = nullptr;
251c745ece2SDavid CARLIER   int fd = -1;
252c745ece2SDavid CARLIER };
253c745ece2SDavid CARLIER 
254630177ccSDavid CARLIER #if !SANITIZER_APPLE
255c745ece2SDavid CARLIER TEST_F(RtsanOpenedMmapTest, MadviseDiesWhenRealtime) {
256c745ece2SDavid CARLIER   auto Func = [this]() { madvise(GetAddr(), GetSize(), MADV_NORMAL); };
257c745ece2SDavid CARLIER   ExpectRealtimeDeath(Func, "madvise");
258c745ece2SDavid CARLIER   ExpectNonRealtimeSurvival(Func);
259c745ece2SDavid CARLIER }
260c745ece2SDavid CARLIER 
261c745ece2SDavid CARLIER TEST_F(RtsanOpenedMmapTest, PosixMadviseDiesWhenRealtime) {
262630177ccSDavid CARLIER   auto Func = [this]() {
263630177ccSDavid CARLIER     posix_madvise(GetAddr(), GetSize(), POSIX_MADV_NORMAL);
264630177ccSDavid CARLIER   };
265c745ece2SDavid CARLIER   ExpectRealtimeDeath(Func, "posix_madvise");
266c745ece2SDavid CARLIER   ExpectNonRealtimeSurvival(Func);
267c745ece2SDavid CARLIER }
268630177ccSDavid CARLIER #endif
269c745ece2SDavid CARLIER 
270c745ece2SDavid CARLIER TEST_F(RtsanOpenedMmapTest, MprotectDiesWhenRealtime) {
271c745ece2SDavid CARLIER   auto Func = [this]() { mprotect(GetAddr(), GetSize(), PROT_READ); };
272c745ece2SDavid CARLIER   ExpectRealtimeDeath(Func, "mprotect");
273c745ece2SDavid CARLIER   ExpectNonRealtimeSurvival(Func);
274c745ece2SDavid CARLIER }
275c745ece2SDavid CARLIER 
276c745ece2SDavid CARLIER TEST_F(RtsanOpenedMmapTest, MsyncDiesWhenRealtime) {
277c745ece2SDavid CARLIER   auto Func = [this]() { msync(GetAddr(), GetSize(), MS_INVALIDATE); };
278c745ece2SDavid CARLIER   ExpectRealtimeDeath(Func, "msync");
279c745ece2SDavid CARLIER   ExpectNonRealtimeSurvival(Func);
280c745ece2SDavid CARLIER }
281c745ece2SDavid CARLIER 
282c745ece2SDavid CARLIER TEST_F(RtsanOpenedMmapTest, MincoreDiesWhenRealtime) {
283c745ece2SDavid CARLIER #if SANITIZER_APPLE
284c745ece2SDavid CARLIER   std::vector<char> vec(GetSize() / 1024);
285c745ece2SDavid CARLIER #else
286c745ece2SDavid CARLIER   std::vector<unsigned char> vec(GetSize() / 1024);
287c745ece2SDavid CARLIER #endif
288c745ece2SDavid CARLIER   auto Func = [this, &vec]() { mincore(GetAddr(), GetSize(), vec.data()); };
289c745ece2SDavid CARLIER   ExpectRealtimeDeath(Func, "mincore");
290c745ece2SDavid CARLIER   ExpectNonRealtimeSurvival(Func);
291c745ece2SDavid CARLIER }
292c745ece2SDavid CARLIER 
29361e50b9fSChris Apple TEST(TestRtsanInterceptors, ShmOpenDiesWhenRealtime) {
29461e50b9fSChris Apple   auto Func = []() { shm_open("/rtsan_test_shm", O_CREAT | O_RDWR, 0); };
29561e50b9fSChris Apple   ExpectRealtimeDeath(Func, "shm_open");
29661e50b9fSChris Apple   ExpectNonRealtimeSurvival(Func);
29761e50b9fSChris Apple }
29861e50b9fSChris Apple 
29961e50b9fSChris Apple TEST(TestRtsanInterceptors, ShmUnlinkDiesWhenRealtime) {
30061e50b9fSChris Apple   auto Func = []() { shm_unlink("/rtsan_test_shm"); };
30161e50b9fSChris Apple   ExpectRealtimeDeath(Func, "shm_unlink");
30261e50b9fSChris Apple   ExpectNonRealtimeSurvival(Func);
30361e50b9fSChris Apple }
30461e50b9fSChris Apple 
3051e07c480SChris Apple /*
3061e07c480SChris Apple     Sleeping
3071e07c480SChris Apple */
3081e07c480SChris Apple 
3091e07c480SChris Apple TEST(TestRtsanInterceptors, SleepDiesWhenRealtime) {
3101e07c480SChris Apple   auto Func = []() { sleep(0u); };
3111e07c480SChris Apple   ExpectRealtimeDeath(Func, "sleep");
3121e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
3131e07c480SChris Apple }
3141e07c480SChris Apple 
3151e07c480SChris Apple TEST(TestRtsanInterceptors, UsleepDiesWhenRealtime) {
3161e07c480SChris Apple   auto Func = []() { usleep(1u); };
3171e07c480SChris Apple   ExpectRealtimeDeath(Func, "usleep");
3181e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
3191e07c480SChris Apple }
3201e07c480SChris Apple 
3211e07c480SChris Apple TEST(TestRtsanInterceptors, NanosleepDiesWhenRealtime) {
3221e07c480SChris Apple   auto Func = []() {
3231e07c480SChris Apple     timespec T{};
3241e07c480SChris Apple     nanosleep(&T, &T);
3251e07c480SChris Apple   };
3261e07c480SChris Apple   ExpectRealtimeDeath(Func, "nanosleep");
3271e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
3281e07c480SChris Apple }
3291e07c480SChris Apple 
330963b8e36SChris Apple TEST(TestRtsanInterceptors, SchedYieldDiesWhenRealtime) {
331963b8e36SChris Apple   auto Func = []() { sched_yield(); };
332963b8e36SChris Apple   ExpectRealtimeDeath(Func, "sched_yield");
333963b8e36SChris Apple   ExpectNonRealtimeSurvival(Func);
334963b8e36SChris Apple }
335963b8e36SChris Apple 
336cfdd7d73SDavid CARLIER #if SANITIZER_LINUX
337cfdd7d73SDavid CARLIER TEST(TestRtsanInterceptors, SchedGetaffinityDiesWhenRealtime) {
338cfdd7d73SDavid CARLIER   cpu_set_t set{};
339cfdd7d73SDavid CARLIER   auto Func = [&set]() { sched_getaffinity(0, sizeof(set), &set); };
340cfdd7d73SDavid CARLIER   ExpectRealtimeDeath(Func, "sched_getaffinity");
341cfdd7d73SDavid CARLIER   ExpectNonRealtimeSurvival(Func);
342cfdd7d73SDavid CARLIER }
343cfdd7d73SDavid CARLIER 
344cfdd7d73SDavid CARLIER TEST(TestRtsanInterceptors, SchedSetaffinityDiesWhenRealtime) {
345cfdd7d73SDavid CARLIER   cpu_set_t set{};
346cfdd7d73SDavid CARLIER   auto Func = [&set]() { sched_setaffinity(0, sizeof(set), &set); };
347cfdd7d73SDavid CARLIER   ExpectRealtimeDeath(Func, "sched_setaffinity");
348cfdd7d73SDavid CARLIER   ExpectNonRealtimeSurvival(Func);
349cfdd7d73SDavid CARLIER }
350cfdd7d73SDavid CARLIER #endif
351cfdd7d73SDavid CARLIER 
3521e07c480SChris Apple /*
3531e07c480SChris Apple     Filesystem
3541e07c480SChris Apple */
3551e07c480SChris Apple 
3561e07c480SChris Apple TEST_F(RtsanFileTest, OpenDiesWhenRealtime) {
3571e07c480SChris Apple   auto Func = [this]() { open(GetTemporaryFilePath(), O_RDONLY); };
358a5e18987SChris Apple   ExpectRealtimeDeath(Func, MAYBE_APPEND_64("open"));
3591e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
3601e07c480SChris Apple }
3611e07c480SChris Apple 
3621e07c480SChris Apple TEST_F(RtsanFileTest, OpenatDiesWhenRealtime) {
3631e07c480SChris Apple   auto Func = [this]() { openat(0, GetTemporaryFilePath(), O_RDONLY); };
364a5e18987SChris Apple   ExpectRealtimeDeath(Func, MAYBE_APPEND_64("openat"));
3651e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
3661e07c480SChris Apple }
3671e07c480SChris Apple 
3681e07c480SChris Apple TEST_F(RtsanFileTest, OpenCreatesFileWithProperMode) {
3691e07c480SChris Apple   const mode_t existing_umask = umask(0);
3701e07c480SChris Apple   umask(existing_umask);
3711e07c480SChris Apple 
3721e07c480SChris Apple   const int mode = S_IRGRP | S_IROTH | S_IRUSR | S_IWUSR;
3731e07c480SChris Apple 
3741e07c480SChris Apple   const int fd = open(GetTemporaryFilePath(), O_CREAT | O_WRONLY, mode);
3751e07c480SChris Apple   ASSERT_THAT(fd, Ne(-1));
3761e07c480SChris Apple   close(fd);
3771e07c480SChris Apple 
3781e07c480SChris Apple   struct stat st;
3791e07c480SChris Apple   ASSERT_THAT(stat(GetTemporaryFilePath(), &st), Eq(0));
3801e07c480SChris Apple 
3811e07c480SChris Apple   // Mask st_mode to get permission bits only
3821e07c480SChris Apple   const mode_t actual_mode = st.st_mode & 0777;
3831e07c480SChris Apple   const mode_t expected_mode = mode & ~existing_umask;
3841e07c480SChris Apple   ASSERT_THAT(actual_mode, Eq(expected_mode));
3851e07c480SChris Apple }
3861e07c480SChris Apple 
3871e07c480SChris Apple TEST_F(RtsanFileTest, CreatDiesWhenRealtime) {
3881e07c480SChris Apple   auto Func = [this]() { creat(GetTemporaryFilePath(), S_IWOTH | S_IROTH); };
389a5e18987SChris Apple   ExpectRealtimeDeath(Func, MAYBE_APPEND_64("creat"));
3901e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
3911e07c480SChris Apple }
3921e07c480SChris Apple 
3931e07c480SChris Apple TEST(TestRtsanInterceptors, FcntlDiesWhenRealtime) {
3941e07c480SChris Apple   auto Func = []() { fcntl(0, F_GETFL); };
395a5e18987SChris Apple   ExpectRealtimeDeath(Func, MAYBE_APPEND_64("fcntl"));
3961e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
3971e07c480SChris Apple }
3981e07c480SChris Apple 
3991e07c480SChris Apple TEST_F(RtsanFileTest, FcntlFlockDiesWhenRealtime) {
4001e07c480SChris Apple   int fd = creat(GetTemporaryFilePath(), S_IRUSR | S_IWUSR);
4011e07c480SChris Apple   ASSERT_THAT(fd, Ne(-1));
4021e07c480SChris Apple 
4031e07c480SChris Apple   auto Func = [fd]() {
4041e07c480SChris Apple     struct flock lock {};
4051e07c480SChris Apple     lock.l_type = F_RDLCK;
4061e07c480SChris Apple     lock.l_whence = SEEK_SET;
4071e07c480SChris Apple     lock.l_start = 0;
4081e07c480SChris Apple     lock.l_len = 0;
4091e07c480SChris Apple     lock.l_pid = ::getpid();
4101e07c480SChris Apple 
4111e07c480SChris Apple     ASSERT_THAT(fcntl(fd, F_GETLK, &lock), Eq(0));
4121e07c480SChris Apple     ASSERT_THAT(lock.l_type, F_UNLCK);
4131e07c480SChris Apple   };
414a5e18987SChris Apple   ExpectRealtimeDeath(Func, MAYBE_APPEND_64("fcntl"));
4151e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
4161e07c480SChris Apple 
4171e07c480SChris Apple   close(fd);
4181e07c480SChris Apple }
4191e07c480SChris Apple 
4201e07c480SChris Apple TEST_F(RtsanFileTest, FcntlSetFdDiesWhenRealtime) {
4211e07c480SChris Apple   int fd = creat(GetTemporaryFilePath(), S_IRUSR | S_IWUSR);
4221e07c480SChris Apple   ASSERT_THAT(fd, Ne(-1));
4231e07c480SChris Apple 
4241e07c480SChris Apple   auto Func = [fd]() {
4251e07c480SChris Apple     int old_flags = fcntl(fd, F_GETFD);
4261e07c480SChris Apple     ASSERT_THAT(fcntl(fd, F_SETFD, FD_CLOEXEC), Eq(0));
4271e07c480SChris Apple 
4281e07c480SChris Apple     int flags = fcntl(fd, F_GETFD);
4291e07c480SChris Apple     ASSERT_THAT(flags, Ne(-1));
4301e07c480SChris Apple     ASSERT_THAT(flags & FD_CLOEXEC, Eq(FD_CLOEXEC));
4311e07c480SChris Apple 
4321e07c480SChris Apple     ASSERT_THAT(fcntl(fd, F_SETFD, old_flags), Eq(0));
4331e07c480SChris Apple     ASSERT_THAT(fcntl(fd, F_GETFD), Eq(old_flags));
4341e07c480SChris Apple   };
4351e07c480SChris Apple 
436a5e18987SChris Apple   ExpectRealtimeDeath(Func, MAYBE_APPEND_64("fcntl"));
4371e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
4381e07c480SChris Apple 
4391e07c480SChris Apple   close(fd);
4401e07c480SChris Apple }
4411e07c480SChris Apple 
4421e07c480SChris Apple TEST(TestRtsanInterceptors, CloseDiesWhenRealtime) {
4431e07c480SChris Apple   auto Func = []() { close(0); };
4441e07c480SChris Apple   ExpectRealtimeDeath(Func, "close");
4451e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
4461e07c480SChris Apple }
4471e07c480SChris Apple 
4481e07c480SChris Apple TEST_F(RtsanFileTest, FopenDiesWhenRealtime) {
4491e07c480SChris Apple   auto Func = [this]() {
4501e07c480SChris Apple     FILE *f = fopen(GetTemporaryFilePath(), "w");
4511e07c480SChris Apple     EXPECT_THAT(f, Ne(nullptr));
4521e07c480SChris Apple   };
4531e07c480SChris Apple 
454a5e18987SChris Apple   ExpectRealtimeDeath(Func, MAYBE_APPEND_64("fopen"));
4551e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
4561e07c480SChris Apple }
4571e07c480SChris Apple 
45885849917SDavid CARLIER #if SANITIZER_INTERCEPT_FOPENCOOKIE
45985849917SDavid CARLIER TEST_F(RtsanFileTest, FopenCookieDieWhenRealtime) {
46085849917SDavid CARLIER   FILE *f = fopen(GetTemporaryFilePath(), "w");
46185849917SDavid CARLIER   EXPECT_THAT(f, Ne(nullptr));
46285849917SDavid CARLIER   struct fholder {
46385849917SDavid CARLIER     FILE *fp;
46485849917SDavid CARLIER     size_t read;
46585849917SDavid CARLIER   } fh = {f, 0};
466d1d40037SDavid CARLIER   auto CookieRead = [](void *cookie, char *buf, size_t size) {
46785849917SDavid CARLIER     fholder *p = reinterpret_cast<fholder *>(cookie);
46885849917SDavid CARLIER     p->read = fread(static_cast<void *>(buf), 1, size, p->fp);
469d1d40037SDavid CARLIER     EXPECT_NE(0u, p->read);
47085849917SDavid CARLIER   };
47185849917SDavid CARLIER   cookie_io_functions_t funcs = {(cookie_read_function_t *)&CookieRead, nullptr,
47285849917SDavid CARLIER                                  nullptr, nullptr};
47385849917SDavid CARLIER   auto Func = [&fh, &funcs]() {
47485849917SDavid CARLIER     FILE *f = fopencookie(&fh, "w", funcs);
47585849917SDavid CARLIER     EXPECT_THAT(f, Ne(nullptr));
47685849917SDavid CARLIER   };
47785849917SDavid CARLIER 
47885849917SDavid CARLIER   ExpectRealtimeDeath(Func, "fopencookie");
47985849917SDavid CARLIER   ExpectNonRealtimeSurvival(Func);
48085849917SDavid CARLIER }
48185849917SDavid CARLIER #endif
48285849917SDavid CARLIER 
483f39ecb7bSDavid CARLIER #if SANITIZER_INTERCEPT_OPEN_MEMSTREAM
484f39ecb7bSDavid CARLIER TEST_F(RtsanFileTest, OpenMemstreamDiesWhenRealtime) {
485f39ecb7bSDavid CARLIER   char *buffer;
486f39ecb7bSDavid CARLIER   size_t size;
487f39ecb7bSDavid CARLIER   auto Func = [&buffer, &size]() {
488f39ecb7bSDavid CARLIER     FILE *f = open_memstream(&buffer, &size);
489f39ecb7bSDavid CARLIER     EXPECT_THAT(f, Ne(nullptr));
490f39ecb7bSDavid CARLIER   };
491f39ecb7bSDavid CARLIER 
492f39ecb7bSDavid CARLIER   ExpectRealtimeDeath(Func, "open_memstream");
493f39ecb7bSDavid CARLIER   ExpectNonRealtimeSurvival(Func);
494f39ecb7bSDavid CARLIER }
495f39ecb7bSDavid CARLIER 
496f39ecb7bSDavid CARLIER TEST_F(RtsanFileTest, FmemOpenDiesWhenRealtime) {
497f39ecb7bSDavid CARLIER   char buffer[1024];
498f39ecb7bSDavid CARLIER   auto Func = [&buffer]() {
499f39ecb7bSDavid CARLIER     FILE *f = fmemopen(&buffer, sizeof(buffer), "w");
500f39ecb7bSDavid CARLIER     EXPECT_THAT(f, Ne(nullptr));
501f39ecb7bSDavid CARLIER   };
502f39ecb7bSDavid CARLIER 
503f39ecb7bSDavid CARLIER   ExpectRealtimeDeath(Func, "fmemopen");
504f39ecb7bSDavid CARLIER   ExpectNonRealtimeSurvival(Func);
505f39ecb7bSDavid CARLIER }
506f39ecb7bSDavid CARLIER #endif
507f39ecb7bSDavid CARLIER 
50893744536SDavid CARLIER #if SANITIZER_INTERCEPT_SETVBUF
50993744536SDavid CARLIER TEST_F(RtsanFileTest, SetbufDieWhenRealtime) {
51093744536SDavid CARLIER   char buffer[BUFSIZ];
51193744536SDavid CARLIER   FILE *f = fopen(GetTemporaryFilePath(), "w");
51293744536SDavid CARLIER   EXPECT_THAT(f, Ne(nullptr));
51393744536SDavid CARLIER 
5147004d681SDavid CARLIER   auto Func = [f, &buffer]() { setbuf(f, buffer); };
51593744536SDavid CARLIER 
51693744536SDavid CARLIER   ExpectRealtimeDeath(Func, "setbuf");
51793744536SDavid CARLIER   ExpectNonRealtimeSurvival(Func);
51893744536SDavid CARLIER }
51993744536SDavid CARLIER 
52093744536SDavid CARLIER TEST_F(RtsanFileTest, SetvbufDieWhenRealtime) {
52193744536SDavid CARLIER   char buffer[1024];
52293744536SDavid CARLIER   size_t size = sizeof(buffer);
52393744536SDavid CARLIER   FILE *f = fopen(GetTemporaryFilePath(), "w");
52493744536SDavid CARLIER   EXPECT_THAT(f, Ne(nullptr));
52593744536SDavid CARLIER 
5267004d681SDavid CARLIER   auto Func = [f, &buffer, size]() {
52793744536SDavid CARLIER     int r = setvbuf(f, buffer, _IOFBF, size);
52893744536SDavid CARLIER     EXPECT_THAT(r, Eq(0));
52993744536SDavid CARLIER   };
53093744536SDavid CARLIER 
53193744536SDavid CARLIER   ExpectRealtimeDeath(Func, "setvbuf");
53293744536SDavid CARLIER   ExpectNonRealtimeSurvival(Func);
53393744536SDavid CARLIER }
5347004d681SDavid CARLIER 
5357004d681SDavid CARLIER TEST_F(RtsanFileTest, SetlinebufDieWhenRealtime) {
5367004d681SDavid CARLIER   FILE *f = fopen(GetTemporaryFilePath(), "w");
5377004d681SDavid CARLIER   EXPECT_THAT(f, Ne(nullptr));
5387004d681SDavid CARLIER 
5397004d681SDavid CARLIER   auto Func = [f]() { setlinebuf(f); };
5407004d681SDavid CARLIER 
5417004d681SDavid CARLIER   ExpectRealtimeDeath(Func, "setlinebuf");
5427004d681SDavid CARLIER   ExpectNonRealtimeSurvival(Func);
5437004d681SDavid CARLIER }
5447004d681SDavid CARLIER 
5457004d681SDavid CARLIER TEST_F(RtsanFileTest, SetbufferDieWhenRealtime) {
5467004d681SDavid CARLIER   char buffer[1024];
5477004d681SDavid CARLIER   size_t size = sizeof(buffer);
5487004d681SDavid CARLIER   FILE *f = fopen(GetTemporaryFilePath(), "w");
5497004d681SDavid CARLIER   EXPECT_THAT(f, Ne(nullptr));
5507004d681SDavid CARLIER 
5517004d681SDavid CARLIER   auto Func = [f, &buffer, size]() { setbuffer(f, buffer, size); };
5527004d681SDavid CARLIER 
5537004d681SDavid CARLIER   ExpectRealtimeDeath(Func, "setbuffer");
5547004d681SDavid CARLIER   ExpectNonRealtimeSurvival(Func);
5557004d681SDavid CARLIER }
55693744536SDavid CARLIER #endif
55793744536SDavid CARLIER 
5581e07c480SChris Apple class RtsanOpenedFileTest : public RtsanFileTest {
5591e07c480SChris Apple protected:
5601e07c480SChris Apple   void SetUp() override {
5611e07c480SChris Apple     RtsanFileTest::SetUp();
5621e07c480SChris Apple     file = fopen(GetTemporaryFilePath(), "w");
5631e07c480SChris Apple     ASSERT_THAT(file, Ne(nullptr));
5641e07c480SChris Apple     fd = fileno(file);
5651e07c480SChris Apple     ASSERT_THAT(fd, Ne(-1));
5661e07c480SChris Apple   }
5671e07c480SChris Apple 
5681e07c480SChris Apple   void TearDown() override {
5691e07c480SChris Apple     if (file != nullptr)
5701e07c480SChris Apple       fclose(file);
5711e07c480SChris Apple     RtsanFileTest::TearDown();
5721e07c480SChris Apple   }
5731e07c480SChris Apple 
5741e07c480SChris Apple   FILE *GetOpenFile() { return file; }
5751e07c480SChris Apple 
5761e07c480SChris Apple   int GetOpenFd() { return fd; }
5771e07c480SChris Apple 
5781e07c480SChris Apple private:
5791e07c480SChris Apple   FILE *file = nullptr;
5801e07c480SChris Apple   int fd = -1;
5811e07c480SChris Apple };
5821e07c480SChris Apple 
583c4443a1bSDavid CARLIER #if SANITIZER_INTERCEPT_FSEEK
584c4443a1bSDavid CARLIER TEST_F(RtsanOpenedFileTest, FgetposDieWhenRealtime) {
585c4443a1bSDavid CARLIER   auto Func = [this]() {
586c4443a1bSDavid CARLIER     fpos_t pos;
587c4443a1bSDavid CARLIER     int ret = fgetpos(GetOpenFile(), &pos);
588c4443a1bSDavid CARLIER     ASSERT_THAT(ret, Eq(0));
589c4443a1bSDavid CARLIER   };
590c4443a1bSDavid CARLIER 
591c4443a1bSDavid CARLIER   ExpectRealtimeDeath(Func, MAYBE_APPEND_64("fgetpos"));
592c4443a1bSDavid CARLIER   ExpectNonRealtimeSurvival(Func);
593c4443a1bSDavid CARLIER }
594c4443a1bSDavid CARLIER 
595c4443a1bSDavid CARLIER TEST_F(RtsanOpenedFileTest, FsetposDieWhenRealtime) {
596c4443a1bSDavid CARLIER   fpos_t pos;
597c4443a1bSDavid CARLIER   int ret = fgetpos(GetOpenFile(), &pos);
598c4443a1bSDavid CARLIER   ASSERT_THAT(ret, Eq(0));
599c4443a1bSDavid CARLIER   auto Func = [this, pos]() {
600c4443a1bSDavid CARLIER     int ret = fsetpos(GetOpenFile(), &pos);
601c4443a1bSDavid CARLIER     ASSERT_THAT(ret, Eq(0));
602c4443a1bSDavid CARLIER   };
603c4443a1bSDavid CARLIER 
604c4443a1bSDavid CARLIER   ExpectRealtimeDeath(Func, MAYBE_APPEND_64("fsetpos"));
605c4443a1bSDavid CARLIER   ExpectNonRealtimeSurvival(Func);
606c4443a1bSDavid CARLIER }
607c4443a1bSDavid CARLIER 
608c4443a1bSDavid CARLIER TEST_F(RtsanOpenedFileTest, FseekDieWhenRealtime) {
609c4443a1bSDavid CARLIER   auto Func = [this]() {
610c4443a1bSDavid CARLIER     int ret = fseek(GetOpenFile(), 0, SEEK_CUR);
611c4443a1bSDavid CARLIER     ASSERT_THAT(ret, Eq(0));
612c4443a1bSDavid CARLIER   };
613c4443a1bSDavid CARLIER 
614c4443a1bSDavid CARLIER   ExpectRealtimeDeath(Func, "fseek");
615c4443a1bSDavid CARLIER   ExpectNonRealtimeSurvival(Func);
616c4443a1bSDavid CARLIER }
617c4443a1bSDavid CARLIER 
618c4443a1bSDavid CARLIER TEST_F(RtsanOpenedFileTest, FseekoDieWhenRealtime) {
619c4443a1bSDavid CARLIER   auto Func = [this]() {
620c4443a1bSDavid CARLIER     int ret = fseeko(GetOpenFile(), 0, SEEK_CUR);
621c4443a1bSDavid CARLIER     ASSERT_THAT(ret, Eq(0));
622c4443a1bSDavid CARLIER   };
623c4443a1bSDavid CARLIER 
624c4443a1bSDavid CARLIER   ExpectRealtimeDeath(Func, MAYBE_APPEND_64("fseeko"));
625c4443a1bSDavid CARLIER   ExpectNonRealtimeSurvival(Func);
626c4443a1bSDavid CARLIER }
627c4443a1bSDavid CARLIER 
628c4443a1bSDavid CARLIER TEST_F(RtsanOpenedFileTest, FtellDieWhenRealtime) {
629c4443a1bSDavid CARLIER   auto Func = [this]() {
630c4443a1bSDavid CARLIER     long ret = ftell(GetOpenFile());
631c4443a1bSDavid CARLIER     ASSERT_THAT(ret, Eq(0));
632c4443a1bSDavid CARLIER   };
633c4443a1bSDavid CARLIER 
634c4443a1bSDavid CARLIER   ExpectRealtimeDeath(Func, "ftell");
635c4443a1bSDavid CARLIER   ExpectNonRealtimeSurvival(Func);
636c4443a1bSDavid CARLIER }
637c4443a1bSDavid CARLIER 
638c4443a1bSDavid CARLIER TEST_F(RtsanOpenedFileTest, FtelloDieWhenRealtime) {
639c4443a1bSDavid CARLIER   auto Func = [this]() {
640c4443a1bSDavid CARLIER     off_t ret = ftello(GetOpenFile());
641c4443a1bSDavid CARLIER     ASSERT_THAT(ret, Eq(0));
642c4443a1bSDavid CARLIER   };
643c4443a1bSDavid CARLIER 
644c4443a1bSDavid CARLIER   ExpectRealtimeDeath(Func, MAYBE_APPEND_64("ftello"));
645c4443a1bSDavid CARLIER   ExpectNonRealtimeSurvival(Func);
646c4443a1bSDavid CARLIER }
647c4443a1bSDavid CARLIER 
648c4443a1bSDavid CARLIER TEST_F(RtsanOpenedFileTest, RewindDieWhenRealtime) {
649c4443a1bSDavid CARLIER   int end = fseek(GetOpenFile(), 0, SEEK_END);
650d15d410aSDavid CARLIER   EXPECT_THAT(end, Eq(0));
651c4443a1bSDavid CARLIER   auto Func = [this]() { rewind(GetOpenFile()); };
652c4443a1bSDavid CARLIER 
653c4443a1bSDavid CARLIER   ExpectRealtimeDeath(Func, "rewind");
654c4443a1bSDavid CARLIER   ExpectNonRealtimeSurvival(Func);
655c4443a1bSDavid CARLIER }
656c4443a1bSDavid CARLIER #endif
657c4443a1bSDavid CARLIER 
6583a8b28f6SChris Apple TEST(TestRtsanInterceptors, IoctlDiesWhenRealtime) {
6593a8b28f6SChris Apple   auto Func = []() { ioctl(0, FIONREAD); };
6603a8b28f6SChris Apple   ExpectRealtimeDeath(Func, "ioctl");
6613a8b28f6SChris Apple   ExpectNonRealtimeSurvival(Func);
6623a8b28f6SChris Apple }
6633a8b28f6SChris Apple 
6643a8b28f6SChris Apple TEST_F(RtsanOpenedFileTest, IoctlBehavesWithOutputArg) {
6653a8b28f6SChris Apple   int arg{};
6663a8b28f6SChris Apple   ioctl(GetOpenFd(), FIONREAD, &arg);
6673a8b28f6SChris Apple 
6683a8b28f6SChris Apple   EXPECT_THAT(arg, Ge(0));
6693a8b28f6SChris Apple }
6703a8b28f6SChris Apple 
6712ab687e2SDavid CARLIER TEST_F(RtsanOpenedFileTest, FdopenDiesWhenRealtime) {
6722ab687e2SDavid CARLIER   auto Func = [&]() {
6732ab687e2SDavid CARLIER     FILE *f = fdopen(GetOpenFd(), "w");
6742ab687e2SDavid CARLIER     EXPECT_THAT(f, Ne(nullptr));
6752ab687e2SDavid CARLIER   };
6762ab687e2SDavid CARLIER 
6772ab687e2SDavid CARLIER   ExpectRealtimeDeath(Func, "fdopen");
6782ab687e2SDavid CARLIER   ExpectNonRealtimeSurvival(Func);
6792ab687e2SDavid CARLIER }
6802ab687e2SDavid CARLIER 
6812ab687e2SDavid CARLIER TEST_F(RtsanOpenedFileTest, FreopenDiesWhenRealtime) {
6822ab687e2SDavid CARLIER   auto Func = [&]() {
6832ab687e2SDavid CARLIER     FILE *newfile = freopen(GetTemporaryFilePath(), "w", GetOpenFile());
6842ab687e2SDavid CARLIER     EXPECT_THAT(newfile, Ne(nullptr));
6852ab687e2SDavid CARLIER   };
6862ab687e2SDavid CARLIER 
6872ab687e2SDavid CARLIER   ExpectRealtimeDeath(Func, MAYBE_APPEND_64("freopen"));
6882ab687e2SDavid CARLIER   ExpectNonRealtimeSurvival(Func);
6892ab687e2SDavid CARLIER }
6902ab687e2SDavid CARLIER 
6913a8b28f6SChris Apple TEST(TestRtsanInterceptors, IoctlBehavesWithOutputPointer) {
6923a8b28f6SChris Apple   // These initial checks just see if we CAN run these tests.
6933a8b28f6SChris Apple   // If we can't (can't open a socket, or can't find an interface, just
6943a8b28f6SChris Apple   // gracefully skip.
6953a8b28f6SChris Apple   int sock = socket(AF_INET, SOCK_STREAM, 0);
6963a8b28f6SChris Apple   if (sock == -1) {
6973a8b28f6SChris Apple     perror("socket");
6983a8b28f6SChris Apple     GTEST_SKIP();
6993a8b28f6SChris Apple   }
7003a8b28f6SChris Apple 
7013a8b28f6SChris Apple   struct ifaddrs *ifaddr = nullptr;
7023a8b28f6SChris Apple   if (getifaddrs(&ifaddr) == -1 || ifaddr == nullptr) {
7033a8b28f6SChris Apple     perror("getifaddrs");
7043a8b28f6SChris Apple     close(sock);
7053a8b28f6SChris Apple     GTEST_SKIP();
7063a8b28f6SChris Apple   }
7073a8b28f6SChris Apple 
7083a8b28f6SChris Apple   struct ifreq ifr {};
7093a8b28f6SChris Apple   strncpy(ifr.ifr_name, ifaddr->ifa_name, IFNAMSIZ - 1);
7103a8b28f6SChris Apple 
7113a8b28f6SChris Apple   int retval = ioctl(sock, SIOCGIFADDR, &ifr);
7123a8b28f6SChris Apple   if (retval == -1) {
7133a8b28f6SChris Apple     perror("ioctl");
7143a8b28f6SChris Apple     close(sock);
7153a8b28f6SChris Apple     freeifaddrs(ifaddr);
7163a8b28f6SChris Apple     FAIL();
7173a8b28f6SChris Apple   }
7183a8b28f6SChris Apple 
7193a8b28f6SChris Apple   freeifaddrs(ifaddr);
7203a8b28f6SChris Apple   close(sock);
7213a8b28f6SChris Apple 
7223a8b28f6SChris Apple   ASSERT_THAT(ifr.ifr_addr.sa_data, NotNull());
7233a8b28f6SChris Apple   ASSERT_THAT(ifr.ifr_addr.sa_family, Eq(AF_INET));
7243a8b28f6SChris Apple }
7253a8b28f6SChris Apple 
7263c8818cfSChris Apple TEST_F(RtsanOpenedFileTest, LseekDiesWhenRealtime) {
7273c8818cfSChris Apple   auto Func = [this]() { lseek(GetOpenFd(), 0, SEEK_SET); };
7283c8818cfSChris Apple   ExpectRealtimeDeath(Func, MAYBE_APPEND_64("lseek"));
7293c8818cfSChris Apple   ExpectNonRealtimeSurvival(Func);
7303c8818cfSChris Apple }
7313c8818cfSChris Apple 
7323c8818cfSChris Apple TEST_F(RtsanOpenedFileTest, DupDiesWhenRealtime) {
7333c8818cfSChris Apple   auto Func = [this]() { dup(GetOpenFd()); };
7343c8818cfSChris Apple   ExpectRealtimeDeath(Func, "dup");
7353c8818cfSChris Apple   ExpectNonRealtimeSurvival(Func);
7363c8818cfSChris Apple }
7373c8818cfSChris Apple 
7383c8818cfSChris Apple TEST_F(RtsanOpenedFileTest, Dup2DiesWhenRealtime) {
7393c8818cfSChris Apple   auto Func = [this]() { dup2(GetOpenFd(), 0); };
7403c8818cfSChris Apple   ExpectRealtimeDeath(Func, "dup2");
7413c8818cfSChris Apple   ExpectNonRealtimeSurvival(Func);
7423c8818cfSChris Apple }
7433c8818cfSChris Apple 
7444a074330SChris Apple TEST_F(RtsanFileTest, ChmodDiesWhenRealtime) {
7454a074330SChris Apple   auto Func = [this]() { chmod(GetTemporaryFilePath(), 0777); };
7464a074330SChris Apple   ExpectRealtimeDeath(Func, "chmod");
7474a074330SChris Apple   ExpectNonRealtimeSurvival(Func);
7484a074330SChris Apple }
7494a074330SChris Apple 
7504a074330SChris Apple TEST_F(RtsanOpenedFileTest, FchmodDiesWhenRealtime) {
7514a074330SChris Apple   auto Func = [this]() { fchmod(GetOpenFd(), 0777); };
7524a074330SChris Apple   ExpectRealtimeDeath(Func, "fchmod");
7534a074330SChris Apple   ExpectNonRealtimeSurvival(Func);
7544a074330SChris Apple }
7554a074330SChris Apple 
7564a074330SChris Apple TEST(TestRtsanInterceptors, UmaskDiesWhenRealtime) {
7574a074330SChris Apple   auto Func = []() { umask(0); };
7584a074330SChris Apple   ExpectRealtimeDeath(Func, "umask");
7594a074330SChris Apple   ExpectNonRealtimeSurvival(Func);
7604a074330SChris Apple }
7614a074330SChris Apple 
7628fad58a6SDavid CARLIER #if SANITIZER_INTERCEPT_PROCESS_VM_READV
7638fad58a6SDavid CARLIER TEST(TestRtsanInterceptors, ProcessVmReadvDiesWhenRealtime) {
7648fad58a6SDavid CARLIER   char stack[1024];
7658fad58a6SDavid CARLIER   int p;
7668fad58a6SDavid CARLIER   iovec lcl{&stack, sizeof(stack)};
7678fad58a6SDavid CARLIER   iovec rmt{&p, sizeof(p)};
7688fad58a6SDavid CARLIER   auto Func = [&lcl, &rmt]() { process_vm_readv(0, &lcl, 1, &rmt, 1, 0); };
7698fad58a6SDavid CARLIER   ExpectRealtimeDeath(Func, "process_vm_readv");
7708fad58a6SDavid CARLIER   ExpectNonRealtimeSurvival(Func);
7718fad58a6SDavid CARLIER }
7728fad58a6SDavid CARLIER 
7738fad58a6SDavid CARLIER TEST(TestRtsanInterceptors, ProcessVmWritevDiesWhenRealtime) {
7748fad58a6SDavid CARLIER   char stack[1024];
7758fad58a6SDavid CARLIER   int p;
7768fad58a6SDavid CARLIER   iovec lcl{&p, sizeof(p)};
7778fad58a6SDavid CARLIER   iovec rmt{&stack, sizeof(stack)};
7788fad58a6SDavid CARLIER   auto Func = [&lcl, &rmt]() { process_vm_writev(0, &lcl, 1, &rmt, 1, 0); };
7798fad58a6SDavid CARLIER   ExpectRealtimeDeath(Func, "process_vm_writev");
7808fad58a6SDavid CARLIER   ExpectNonRealtimeSurvival(Func);
7818fad58a6SDavid CARLIER }
7828fad58a6SDavid CARLIER #endif
7838fad58a6SDavid CARLIER 
7844a074330SChris Apple class RtsanDirectoryTest : public ::testing::Test {
7854a074330SChris Apple protected:
7864a074330SChris Apple   void SetUp() override {
7874a074330SChris Apple     const ::testing::TestInfo *const test_info =
7884a074330SChris Apple         ::testing::UnitTest::GetInstance()->current_test_info();
7894a074330SChris Apple     directory_path_ = std::string("/tmp/rtsan_temp_dir_") + test_info->name();
7904a074330SChris Apple     RemoveTemporaryDirectory();
7914a074330SChris Apple   }
7924a074330SChris Apple 
7934a074330SChris Apple   const char *GetTemporaryDirectoryPath() const {
7944a074330SChris Apple     return directory_path_.c_str();
7954a074330SChris Apple   }
7964a074330SChris Apple 
7974a074330SChris Apple   void TearDown() override { RemoveTemporaryDirectory(); }
7984a074330SChris Apple 
7994a074330SChris Apple private:
8004a074330SChris Apple   void RemoveTemporaryDirectory() const {
8014a074330SChris Apple     std::remove(GetTemporaryDirectoryPath());
8024a074330SChris Apple   }
8034a074330SChris Apple   std::string directory_path_;
8044a074330SChris Apple };
8054a074330SChris Apple 
8064a074330SChris Apple TEST_F(RtsanDirectoryTest, MkdirDiesWhenRealtime) {
8074a074330SChris Apple   auto Func = [this]() { mkdir(GetTemporaryDirectoryPath(), 0777); };
8084a074330SChris Apple   ExpectRealtimeDeath(Func, "mkdir");
8094a074330SChris Apple   ExpectNonRealtimeSurvival(Func);
8104a074330SChris Apple }
8114a074330SChris Apple 
8124a074330SChris Apple TEST_F(RtsanDirectoryTest, RmdirDiesWhenRealtime) {
8134a074330SChris Apple   // We don't actually create this directory before we try to remove it
8144a074330SChris Apple   // Thats OK - we are just making sure the call gets intercepted
8154a074330SChris Apple   auto Func = [this]() { rmdir(GetTemporaryDirectoryPath()); };
8164a074330SChris Apple   ExpectRealtimeDeath(Func, "rmdir");
8174a074330SChris Apple   ExpectNonRealtimeSurvival(Func);
8184a074330SChris Apple }
8194a074330SChris Apple 
8201e07c480SChris Apple TEST_F(RtsanOpenedFileTest, FreadDiesWhenRealtime) {
8211e07c480SChris Apple   auto Func = [this]() {
8221e07c480SChris Apple     char c{};
8231e07c480SChris Apple     fread(&c, 1, 1, GetOpenFile());
8241e07c480SChris Apple   };
8251e07c480SChris Apple   ExpectRealtimeDeath(Func, "fread");
8261e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
8271e07c480SChris Apple }
8281e07c480SChris Apple 
8291e07c480SChris Apple TEST_F(RtsanOpenedFileTest, FwriteDiesWhenRealtime) {
8301e07c480SChris Apple   const char *message = "Hello, world!";
8311e07c480SChris Apple   auto Func = [&]() { fwrite(&message, 1, 4, GetOpenFile()); };
8321e07c480SChris Apple   ExpectRealtimeDeath(Func, "fwrite");
8331e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
8341e07c480SChris Apple }
8351e07c480SChris Apple 
8361e07c480SChris Apple TEST_F(RtsanFileTest, FcloseDiesWhenRealtime) {
8371e07c480SChris Apple   FILE *f = fopen(GetTemporaryFilePath(), "w");
8381e07c480SChris Apple   EXPECT_THAT(f, Ne(nullptr));
8391e07c480SChris Apple   auto Func = [f]() { fclose(f); };
8401e07c480SChris Apple   ExpectRealtimeDeath(Func, "fclose");
8411e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
8421e07c480SChris Apple }
8431e07c480SChris Apple 
8441e07c480SChris Apple TEST(TestRtsanInterceptors, PutsDiesWhenRealtime) {
8451e07c480SChris Apple   auto Func = []() { puts("Hello, world!\n"); };
8461e07c480SChris Apple   ExpectRealtimeDeath(Func);
8471e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
8481e07c480SChris Apple }
8491e07c480SChris Apple 
8501e07c480SChris Apple TEST_F(RtsanOpenedFileTest, FputsDiesWhenRealtime) {
8511e07c480SChris Apple   auto Func = [this]() { fputs("Hello, world!\n", GetOpenFile()); };
8521e07c480SChris Apple   ExpectRealtimeDeath(Func);
8531e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
8541e07c480SChris Apple }
8551e07c480SChris Apple 
85659354a86SDavid CARLIER TEST_F(RtsanFileTest, FflushDiesWhenRealtime) {
85759354a86SDavid CARLIER   FILE *f = fopen(GetTemporaryFilePath(), "w");
85859354a86SDavid CARLIER   EXPECT_THAT(f, Ne(nullptr));
85959354a86SDavid CARLIER   int written = fwrite("abc", 1, 3, f);
86059354a86SDavid CARLIER   EXPECT_THAT(written, Eq(3));
86159354a86SDavid CARLIER   auto Func = [&f]() {
86259354a86SDavid CARLIER     int res = fflush(f);
86359354a86SDavid CARLIER     EXPECT_THAT(res, Eq(0));
86459354a86SDavid CARLIER   };
86559354a86SDavid CARLIER   ExpectRealtimeDeath(Func, "fflush");
86659354a86SDavid CARLIER   ExpectNonRealtimeSurvival(Func);
86759354a86SDavid CARLIER }
86859354a86SDavid CARLIER 
86959354a86SDavid CARLIER #if SANITIZER_APPLE
87059354a86SDavid CARLIER TEST_F(RtsanFileTest, FpurgeDiesWhenRealtime) {
87159354a86SDavid CARLIER   FILE *f = fopen(GetTemporaryFilePath(), "w");
87259354a86SDavid CARLIER   EXPECT_THAT(f, Ne(nullptr));
87359354a86SDavid CARLIER   int written = fwrite("abc", 1, 3, f);
87459354a86SDavid CARLIER   EXPECT_THAT(written, Eq(3));
87559354a86SDavid CARLIER   auto Func = [&f]() {
87659354a86SDavid CARLIER     int res = fpurge(f);
87759354a86SDavid CARLIER     EXPECT_THAT(res, Eq(0));
87859354a86SDavid CARLIER   };
87959354a86SDavid CARLIER   ExpectRealtimeDeath(Func, "fpurge");
88059354a86SDavid CARLIER   ExpectNonRealtimeSurvival(Func);
88159354a86SDavid CARLIER }
88259354a86SDavid CARLIER #endif
88359354a86SDavid CARLIER 
8841e07c480SChris Apple TEST_F(RtsanOpenedFileTest, ReadDiesWhenRealtime) {
8851e07c480SChris Apple   auto Func = [this]() {
8861e07c480SChris Apple     char c{};
8871e07c480SChris Apple     read(GetOpenFd(), &c, 1);
8881e07c480SChris Apple   };
8891e07c480SChris Apple   ExpectRealtimeDeath(Func, "read");
8901e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
8911e07c480SChris Apple }
8921e07c480SChris Apple 
8931e07c480SChris Apple TEST_F(RtsanOpenedFileTest, WriteDiesWhenRealtime) {
8941e07c480SChris Apple   auto Func = [this]() {
8951e07c480SChris Apple     char c = 'a';
8961e07c480SChris Apple     write(GetOpenFd(), &c, 1);
8971e07c480SChris Apple   };
8981e07c480SChris Apple   ExpectRealtimeDeath(Func, "write");
8991e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
9001e07c480SChris Apple }
9011e07c480SChris Apple 
9021e07c480SChris Apple TEST_F(RtsanOpenedFileTest, PreadDiesWhenRealtime) {
9031e07c480SChris Apple   auto Func = [this]() {
9041e07c480SChris Apple     char c{};
9051e07c480SChris Apple     pread(GetOpenFd(), &c, 1, 0);
9061e07c480SChris Apple   };
907a5e18987SChris Apple   ExpectRealtimeDeath(Func, MAYBE_APPEND_64("pread"));
9081e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
9091e07c480SChris Apple }
9101e07c480SChris Apple 
91102a30049SDavid CARLIER #if SANITIZER_INTERCEPT_PREADV
91202a30049SDavid CARLIER TEST_F(RtsanOpenedFileTest, PreadvDiesWhenRealtime) {
91302a30049SDavid CARLIER   auto Func = [this]() {
91402a30049SDavid CARLIER     char c{};
91502a30049SDavid CARLIER     iovec iov{&c, sizeof(c)};
91602a30049SDavid CARLIER     preadv(GetOpenFd(), &iov, 1, 0);
91702a30049SDavid CARLIER   };
91802a30049SDavid CARLIER   ExpectRealtimeDeath(Func, MAYBE_APPEND_64("preadv"));
91902a30049SDavid CARLIER   ExpectNonRealtimeSurvival(Func);
92002a30049SDavid CARLIER }
92102a30049SDavid CARLIER #endif
92202a30049SDavid CARLIER 
92302a30049SDavid CARLIER #if SANITIZER_INTERCEPT_PWRITEV
92402a30049SDavid CARLIER TEST_F(RtsanOpenedFileTest, PwritevDiesWhenRealtime) {
92502a30049SDavid CARLIER   auto Func = [this]() {
92602a30049SDavid CARLIER     char c{};
92702a30049SDavid CARLIER     iovec iov{&c, sizeof(c)};
92802a30049SDavid CARLIER     pwritev(GetOpenFd(), &iov, 1, 0);
92902a30049SDavid CARLIER   };
93002a30049SDavid CARLIER   ExpectRealtimeDeath(Func, MAYBE_APPEND_64("pwritev"));
93102a30049SDavid CARLIER   ExpectNonRealtimeSurvival(Func);
93202a30049SDavid CARLIER }
93302a30049SDavid CARLIER #endif
93402a30049SDavid CARLIER 
9351e07c480SChris Apple TEST_F(RtsanOpenedFileTest, ReadvDiesWhenRealtime) {
9361e07c480SChris Apple   auto Func = [this]() {
9371e07c480SChris Apple     char c{};
9381e07c480SChris Apple     iovec iov{&c, 1};
9391e07c480SChris Apple     readv(GetOpenFd(), &iov, 1);
9401e07c480SChris Apple   };
9411e07c480SChris Apple   ExpectRealtimeDeath(Func, "readv");
9421e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
9431e07c480SChris Apple }
9441e07c480SChris Apple 
9451e07c480SChris Apple TEST_F(RtsanOpenedFileTest, PwriteDiesWhenRealtime) {
9461e07c480SChris Apple   auto Func = [this]() {
9471e07c480SChris Apple     char c = 'a';
9481e07c480SChris Apple     pwrite(GetOpenFd(), &c, 1, 0);
9491e07c480SChris Apple   };
950a5e18987SChris Apple   ExpectRealtimeDeath(Func, MAYBE_APPEND_64("pwrite"));
9511e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
9521e07c480SChris Apple }
9531e07c480SChris Apple 
9541e07c480SChris Apple TEST_F(RtsanOpenedFileTest, WritevDiesWhenRealtime) {
9551e07c480SChris Apple   auto Func = [this]() {
9561e07c480SChris Apple     char c = 'a';
9571e07c480SChris Apple     iovec iov{&c, 1};
9581e07c480SChris Apple     writev(GetOpenFd(), &iov, 1);
9591e07c480SChris Apple   };
9601e07c480SChris Apple   ExpectRealtimeDeath(Func, "writev");
9611e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
9621e07c480SChris Apple }
9631e07c480SChris Apple 
9641e07c480SChris Apple /*
9651e07c480SChris Apple     Concurrency
9661e07c480SChris Apple */
9671e07c480SChris Apple 
9681e07c480SChris Apple TEST(TestRtsanInterceptors, PthreadCreateDiesWhenRealtime) {
9691e07c480SChris Apple   auto Func = []() {
9701e07c480SChris Apple     pthread_t thread{};
9711e07c480SChris Apple     const pthread_attr_t attr{};
9721e07c480SChris Apple     struct thread_info *thread_info{};
9731e07c480SChris Apple     pthread_create(&thread, &attr, &FakeThreadEntryPoint, thread_info);
9741e07c480SChris Apple   };
9751e07c480SChris Apple   ExpectRealtimeDeath(Func, "pthread_create");
9761e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
9771e07c480SChris Apple }
9781e07c480SChris Apple 
9791e07c480SChris Apple class PthreadMutexLockTest : public ::testing::Test {
9801e07c480SChris Apple protected:
9811e07c480SChris Apple   void SetUp() override {
9821e07c480SChris Apple     pthread_mutex_init(&mutex, nullptr);
9831e07c480SChris Apple     is_locked = false;
9841e07c480SChris Apple   }
9851e07c480SChris Apple 
9861e07c480SChris Apple   void TearDown() override {
9871e07c480SChris Apple     if (is_locked)
9881e07c480SChris Apple       Unlock();
9891e07c480SChris Apple 
9901e07c480SChris Apple     pthread_mutex_destroy(&mutex);
9911e07c480SChris Apple   }
9921e07c480SChris Apple 
9931e07c480SChris Apple   void Lock() {
9941e07c480SChris Apple     ASSERT_TRUE(!is_locked);
9951e07c480SChris Apple     pthread_mutex_lock(&mutex);
9961e07c480SChris Apple     is_locked = true;
9971e07c480SChris Apple   }
9981e07c480SChris Apple 
9991e07c480SChris Apple   void Unlock() {
10001e07c480SChris Apple     ASSERT_TRUE(is_locked);
10011e07c480SChris Apple     pthread_mutex_unlock(&mutex);
10021e07c480SChris Apple     is_locked = false;
10031e07c480SChris Apple   }
10041e07c480SChris Apple 
10051e07c480SChris Apple private:
10061e07c480SChris Apple   pthread_mutex_t mutex;
10071e07c480SChris Apple   bool is_locked;
10081e07c480SChris Apple };
10091e07c480SChris Apple 
10101e07c480SChris Apple TEST_F(PthreadMutexLockTest, PthreadMutexLockDiesWhenRealtime) {
10111e07c480SChris Apple   auto Func = [this]() { Lock(); };
10121e07c480SChris Apple 
10131e07c480SChris Apple   ExpectRealtimeDeath(Func, "pthread_mutex_lock");
10141e07c480SChris Apple }
10151e07c480SChris Apple 
10161e07c480SChris Apple TEST_F(PthreadMutexLockTest, PthreadMutexLockSurvivesWhenNotRealtime) {
10171e07c480SChris Apple   auto Func = [this]() { Lock(); };
10181e07c480SChris Apple 
10191e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
10201e07c480SChris Apple }
10211e07c480SChris Apple 
10221e07c480SChris Apple TEST_F(PthreadMutexLockTest, PthreadMutexUnlockDiesWhenRealtime) {
10231e07c480SChris Apple   Lock();
10241e07c480SChris Apple   auto Func = [this]() { Unlock(); };
10251e07c480SChris Apple 
10261e07c480SChris Apple   ExpectRealtimeDeath(Func, "pthread_mutex_unlock");
10271e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
10281e07c480SChris Apple }
10291e07c480SChris Apple 
10301e07c480SChris Apple TEST_F(PthreadMutexLockTest, PthreadMutexUnlockSurvivesWhenNotRealtime) {
10311e07c480SChris Apple   Lock();
10321e07c480SChris Apple   auto Func = [this]() { Unlock(); };
10331e07c480SChris Apple 
10341e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
10351e07c480SChris Apple }
10361e07c480SChris Apple 
10371e07c480SChris Apple TEST(TestRtsanInterceptors, PthreadJoinDiesWhenRealtime) {
10381e07c480SChris Apple   pthread_t thread{};
10391e07c480SChris Apple   ASSERT_EQ(0,
10401e07c480SChris Apple             pthread_create(&thread, nullptr, &FakeThreadEntryPoint, nullptr));
10411e07c480SChris Apple 
10421e07c480SChris Apple   auto Func = [&thread]() { pthread_join(thread, nullptr); };
10431e07c480SChris Apple 
10441e07c480SChris Apple   ExpectRealtimeDeath(Func, "pthread_join");
10451e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
10461e07c480SChris Apple }
10471e07c480SChris Apple 
10481e07c480SChris Apple #if SANITIZER_APPLE
10491e07c480SChris Apple 
10501e07c480SChris Apple #pragma clang diagnostic push
10511e07c480SChris Apple // OSSpinLockLock is deprecated, but still in use in libc++
10521e07c480SChris Apple #pragma clang diagnostic ignored "-Wdeprecated-declarations"
10531e07c480SChris Apple TEST(TestRtsanInterceptors, OsSpinLockLockDiesWhenRealtime) {
10541e07c480SChris Apple   auto Func = []() {
10551e07c480SChris Apple     OSSpinLock spin_lock{};
10561e07c480SChris Apple     OSSpinLockLock(&spin_lock);
10571e07c480SChris Apple   };
10581e07c480SChris Apple   ExpectRealtimeDeath(Func, "OSSpinLockLock");
10591e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
10601e07c480SChris Apple }
10611e07c480SChris Apple #pragma clang diagnostic pop
10621e07c480SChris Apple 
10631e07c480SChris Apple TEST(TestRtsanInterceptors, OsUnfairLockLockDiesWhenRealtime) {
10641e07c480SChris Apple   auto Func = []() {
10651e07c480SChris Apple     os_unfair_lock_s unfair_lock{};
10661e07c480SChris Apple     os_unfair_lock_lock(&unfair_lock);
10671e07c480SChris Apple   };
10681e07c480SChris Apple   ExpectRealtimeDeath(Func, "os_unfair_lock_lock");
10691e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
10701e07c480SChris Apple }
10711e07c480SChris Apple #endif
10721e07c480SChris Apple 
10731e07c480SChris Apple #if SANITIZER_LINUX
10741e07c480SChris Apple TEST(TestRtsanInterceptors, SpinLockLockDiesWhenRealtime) {
10751e07c480SChris Apple   pthread_spinlock_t spin_lock;
10761e07c480SChris Apple   pthread_spin_init(&spin_lock, PTHREAD_PROCESS_SHARED);
10771e07c480SChris Apple   auto Func = [&]() { pthread_spin_lock(&spin_lock); };
10781e07c480SChris Apple   ExpectRealtimeDeath(Func, "pthread_spin_lock");
10791e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
10801e07c480SChris Apple }
10811e07c480SChris Apple #endif
10821e07c480SChris Apple 
10831e07c480SChris Apple TEST(TestRtsanInterceptors, PthreadCondSignalDiesWhenRealtime) {
10841e07c480SChris Apple   pthread_cond_t cond{};
10851e07c480SChris Apple   ASSERT_EQ(0, pthread_cond_init(&cond, nullptr));
10861e07c480SChris Apple 
10871e07c480SChris Apple   auto Func = [&cond]() { pthread_cond_signal(&cond); };
10881e07c480SChris Apple   ExpectRealtimeDeath(Func, "pthread_cond_signal");
10891e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
10901e07c480SChris Apple 
10911e07c480SChris Apple   pthread_cond_destroy(&cond);
10921e07c480SChris Apple }
10931e07c480SChris Apple 
10941e07c480SChris Apple TEST(TestRtsanInterceptors, PthreadCondBroadcastDiesWhenRealtime) {
10951e07c480SChris Apple   pthread_cond_t cond{};
10961e07c480SChris Apple   ASSERT_EQ(0, pthread_cond_init(&cond, nullptr));
10971e07c480SChris Apple 
10981e07c480SChris Apple   auto Func = [&cond]() { pthread_cond_broadcast(&cond); };
10991e07c480SChris Apple   ExpectRealtimeDeath(Func, "pthread_cond_broadcast");
11001e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
11011e07c480SChris Apple 
11021e07c480SChris Apple   pthread_cond_destroy(&cond);
11031e07c480SChris Apple }
11041e07c480SChris Apple 
11051e07c480SChris Apple TEST(TestRtsanInterceptors, PthreadCondWaitDiesWhenRealtime) {
11061e07c480SChris Apple   pthread_cond_t cond;
11071e07c480SChris Apple   pthread_mutex_t mutex;
11081e07c480SChris Apple   ASSERT_EQ(0, pthread_cond_init(&cond, nullptr));
11091e07c480SChris Apple   ASSERT_EQ(0, pthread_mutex_init(&mutex, nullptr));
11101e07c480SChris Apple 
11111e07c480SChris Apple   auto Func = [&]() { pthread_cond_wait(&cond, &mutex); };
11121e07c480SChris Apple   ExpectRealtimeDeath(Func, "pthread_cond_wait");
11131e07c480SChris Apple   // It's very difficult to test the success case here without doing some
11141e07c480SChris Apple   // sleeping, which is at the mercy of the scheduler. What's really important
11151e07c480SChris Apple   // here is the interception - so we're only testing that for now.
11161e07c480SChris Apple 
11171e07c480SChris Apple   pthread_cond_destroy(&cond);
11181e07c480SChris Apple   pthread_mutex_destroy(&mutex);
11191e07c480SChris Apple }
11201e07c480SChris Apple 
11211e07c480SChris Apple class PthreadRwlockTest : public ::testing::Test {
11221e07c480SChris Apple protected:
11231e07c480SChris Apple   void SetUp() override {
11241e07c480SChris Apple     pthread_rwlock_init(&rw_lock, nullptr);
11251e07c480SChris Apple     is_locked = false;
11261e07c480SChris Apple   }
11271e07c480SChris Apple 
11281e07c480SChris Apple   void TearDown() override {
11291e07c480SChris Apple     if (is_locked)
11301e07c480SChris Apple       Unlock();
11311e07c480SChris Apple 
11321e07c480SChris Apple     pthread_rwlock_destroy(&rw_lock);
11331e07c480SChris Apple   }
11341e07c480SChris Apple 
11351e07c480SChris Apple   void RdLock() {
11361e07c480SChris Apple     ASSERT_TRUE(!is_locked);
11371e07c480SChris Apple     pthread_rwlock_rdlock(&rw_lock);
11381e07c480SChris Apple     is_locked = true;
11391e07c480SChris Apple   }
11401e07c480SChris Apple 
11411e07c480SChris Apple   void WrLock() {
11421e07c480SChris Apple     ASSERT_TRUE(!is_locked);
11431e07c480SChris Apple     pthread_rwlock_wrlock(&rw_lock);
11441e07c480SChris Apple     is_locked = true;
11451e07c480SChris Apple   }
11461e07c480SChris Apple 
11471e07c480SChris Apple   void Unlock() {
11481e07c480SChris Apple     ASSERT_TRUE(is_locked);
11491e07c480SChris Apple     pthread_rwlock_unlock(&rw_lock);
11501e07c480SChris Apple     is_locked = false;
11511e07c480SChris Apple   }
11521e07c480SChris Apple 
11531e07c480SChris Apple private:
11541e07c480SChris Apple   pthread_rwlock_t rw_lock;
11551e07c480SChris Apple   bool is_locked;
11561e07c480SChris Apple };
11571e07c480SChris Apple 
11581e07c480SChris Apple TEST_F(PthreadRwlockTest, PthreadRwlockRdlockDiesWhenRealtime) {
11591e07c480SChris Apple   auto Func = [this]() { RdLock(); };
11601e07c480SChris Apple   ExpectRealtimeDeath(Func, "pthread_rwlock_rdlock");
11611e07c480SChris Apple }
11621e07c480SChris Apple 
11631e07c480SChris Apple TEST_F(PthreadRwlockTest, PthreadRwlockRdlockSurvivesWhenNonRealtime) {
11641e07c480SChris Apple   auto Func = [this]() { RdLock(); };
11651e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
11661e07c480SChris Apple }
11671e07c480SChris Apple 
11681e07c480SChris Apple TEST_F(PthreadRwlockTest, PthreadRwlockUnlockDiesWhenRealtime) {
11691e07c480SChris Apple   RdLock();
11701e07c480SChris Apple 
11711e07c480SChris Apple   auto Func = [this]() { Unlock(); };
11721e07c480SChris Apple   ExpectRealtimeDeath(Func, "pthread_rwlock_unlock");
11731e07c480SChris Apple }
11741e07c480SChris Apple 
11751e07c480SChris Apple TEST_F(PthreadRwlockTest, PthreadRwlockUnlockSurvivesWhenNonRealtime) {
11761e07c480SChris Apple   RdLock();
11771e07c480SChris Apple 
11781e07c480SChris Apple   auto Func = [this]() { Unlock(); };
11791e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
11801e07c480SChris Apple }
11811e07c480SChris Apple 
11821e07c480SChris Apple TEST_F(PthreadRwlockTest, PthreadRwlockWrlockDiesWhenRealtime) {
11831e07c480SChris Apple   auto Func = [this]() { WrLock(); };
11841e07c480SChris Apple 
11851e07c480SChris Apple   ExpectRealtimeDeath(Func, "pthread_rwlock_wrlock");
11861e07c480SChris Apple }
11871e07c480SChris Apple 
11881e07c480SChris Apple TEST_F(PthreadRwlockTest, PthreadRwlockWrlockSurvivesWhenNonRealtime) {
11891e07c480SChris Apple   auto Func = [this]() { WrLock(); };
11901e07c480SChris Apple 
11911e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
11921e07c480SChris Apple }
11931e07c480SChris Apple 
11941e07c480SChris Apple /*
11951e07c480SChris Apple     Sockets
11961e07c480SChris Apple */
11978699f301SChris Apple TEST(TestRtsanInterceptors, GetAddrInfoDiesWhenRealtime) {
11988699f301SChris Apple   auto Func = []() {
11998699f301SChris Apple     addrinfo *info{};
12008699f301SChris Apple     getaddrinfo("localhost", "http", nullptr, &info);
12018699f301SChris Apple   };
12028699f301SChris Apple   ExpectRealtimeDeath(Func, "getaddrinfo");
12038699f301SChris Apple   ExpectNonRealtimeSurvival(Func);
12048699f301SChris Apple }
12058699f301SChris Apple 
12068699f301SChris Apple TEST(TestRtsanInterceptors, GetNameInfoDiesWhenRealtime) {
12078699f301SChris Apple   auto Func = []() {
12088699f301SChris Apple     char host[NI_MAXHOST];
12098699f301SChris Apple     char serv[NI_MAXSERV];
12108699f301SChris Apple     getnameinfo(nullptr, 0, host, NI_MAXHOST, serv, NI_MAXSERV, 0);
12118699f301SChris Apple   };
12128699f301SChris Apple   ExpectRealtimeDeath(Func, "getnameinfo");
12138699f301SChris Apple   ExpectNonRealtimeSurvival(Func);
12148699f301SChris Apple }
12158699f301SChris Apple 
12168699f301SChris Apple TEST(TestRtsanInterceptors, BindingASocketDiesWhenRealtime) {
12178699f301SChris Apple   auto Func = []() { EXPECT_NE(bind(kNotASocketFd, nullptr, 0), 0); };
12188699f301SChris Apple   ExpectRealtimeDeath(Func, "bind");
12198699f301SChris Apple   ExpectNonRealtimeSurvival(Func);
12208699f301SChris Apple }
12218699f301SChris Apple 
12228699f301SChris Apple TEST(TestRtsanInterceptors, ListeningOnASocketDiesWhenRealtime) {
12238699f301SChris Apple   auto Func = []() { EXPECT_NE(listen(kNotASocketFd, 0), 0); };
12248699f301SChris Apple   ExpectRealtimeDeath(Func, "listen");
12258699f301SChris Apple   ExpectNonRealtimeSurvival(Func);
12268699f301SChris Apple }
12278699f301SChris Apple 
12288699f301SChris Apple TEST(TestRtsanInterceptors, AcceptingASocketDiesWhenRealtime) {
12298699f301SChris Apple   auto Func = []() { EXPECT_LT(accept(kNotASocketFd, nullptr, nullptr), 0); };
12308699f301SChris Apple   ExpectRealtimeDeath(Func, "accept");
12318699f301SChris Apple   ExpectNonRealtimeSurvival(Func);
12328699f301SChris Apple }
12338699f301SChris Apple 
123497fd435eSDavid CARLIER #if SANITIZER_INTERCEPT_ACCEPT4
123597fd435eSDavid CARLIER TEST(TestRtsanInterceptors, Accepting4ASocketDiesWhenRealtime) {
123697fd435eSDavid CARLIER   auto Func = []() {
123797fd435eSDavid CARLIER     EXPECT_LT(accept4(kNotASocketFd, nullptr, nullptr, 0), 0);
123897fd435eSDavid CARLIER   };
123997fd435eSDavid CARLIER   ExpectRealtimeDeath(Func, "accept4");
124097fd435eSDavid CARLIER   ExpectNonRealtimeSurvival(Func);
124197fd435eSDavid CARLIER }
124297fd435eSDavid CARLIER #endif
124397fd435eSDavid CARLIER 
12448699f301SChris Apple TEST(TestRtsanInterceptors, ConnectingASocketDiesWhenRealtime) {
12458699f301SChris Apple   auto Func = []() { EXPECT_NE(connect(kNotASocketFd, nullptr, 0), 0); };
12468699f301SChris Apple   ExpectRealtimeDeath(Func, "connect");
12478699f301SChris Apple   ExpectNonRealtimeSurvival(Func);
12488699f301SChris Apple }
12498699f301SChris Apple 
12501e07c480SChris Apple TEST(TestRtsanInterceptors, OpeningASocketDiesWhenRealtime) {
12511e07c480SChris Apple   auto Func = []() { socket(PF_INET, SOCK_STREAM, 0); };
12521e07c480SChris Apple   ExpectRealtimeDeath(Func, "socket");
12531e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
12541e07c480SChris Apple }
12551e07c480SChris Apple 
12561e07c480SChris Apple TEST(TestRtsanInterceptors, SendToASocketDiesWhenRealtime) {
12571e07c480SChris Apple   auto Func = []() { send(0, nullptr, 0, 0); };
12581e07c480SChris Apple   ExpectRealtimeDeath(Func, "send");
12591e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
12601e07c480SChris Apple }
12611e07c480SChris Apple 
12621e07c480SChris Apple TEST(TestRtsanInterceptors, SendmsgToASocketDiesWhenRealtime) {
12631e07c480SChris Apple   msghdr msg{};
12641e07c480SChris Apple   auto Func = [&]() { sendmsg(0, &msg, 0); };
12651e07c480SChris Apple   ExpectRealtimeDeath(Func, "sendmsg");
12661e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
12671e07c480SChris Apple }
12681e07c480SChris Apple 
126918d5d84dSDavid CARLIER #if SANITIZER_INTERCEPT_SENDMMSG
127018d5d84dSDavid CARLIER TEST(TestRtsanInterceptors, SendmmsgOnASocketDiesWhenRealtime) {
127118d5d84dSDavid CARLIER   mmsghdr msg{};
127218d5d84dSDavid CARLIER   auto Func = [&]() { sendmmsg(0, &msg, 0, 0); };
127318d5d84dSDavid CARLIER   ExpectRealtimeDeath(Func, "sendmmsg");
127418d5d84dSDavid CARLIER   ExpectNonRealtimeSurvival(Func);
127518d5d84dSDavid CARLIER }
127618d5d84dSDavid CARLIER #endif
127718d5d84dSDavid CARLIER 
12781e07c480SChris Apple TEST(TestRtsanInterceptors, SendtoToASocketDiesWhenRealtime) {
12791e07c480SChris Apple   sockaddr addr{};
12801e07c480SChris Apple   socklen_t len{};
12811e07c480SChris Apple   auto Func = [&]() { sendto(0, nullptr, 0, 0, &addr, len); };
12821e07c480SChris Apple   ExpectRealtimeDeath(Func, "sendto");
12831e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
12841e07c480SChris Apple }
12851e07c480SChris Apple 
12861e07c480SChris Apple TEST(TestRtsanInterceptors, RecvFromASocketDiesWhenRealtime) {
12871e07c480SChris Apple   auto Func = []() { recv(0, nullptr, 0, 0); };
12881e07c480SChris Apple   ExpectRealtimeDeath(Func, "recv");
12891e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
12901e07c480SChris Apple }
12911e07c480SChris Apple 
12921e07c480SChris Apple TEST(TestRtsanInterceptors, RecvfromOnASocketDiesWhenRealtime) {
12931e07c480SChris Apple   sockaddr addr{};
12941e07c480SChris Apple   socklen_t len{};
12951e07c480SChris Apple   auto Func = [&]() { recvfrom(0, nullptr, 0, 0, &addr, &len); };
12961e07c480SChris Apple   ExpectRealtimeDeath(Func, "recvfrom");
12971e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
12981e07c480SChris Apple }
12991e07c480SChris Apple 
13001e07c480SChris Apple TEST(TestRtsanInterceptors, RecvmsgOnASocketDiesWhenRealtime) {
13011e07c480SChris Apple   msghdr msg{};
13021e07c480SChris Apple   auto Func = [&]() { recvmsg(0, &msg, 0); };
13031e07c480SChris Apple   ExpectRealtimeDeath(Func, "recvmsg");
13041e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
13051e07c480SChris Apple }
13061e07c480SChris Apple 
130718d5d84dSDavid CARLIER #if SANITIZER_INTERCEPT_RECVMMSG
130818d5d84dSDavid CARLIER TEST(TestRtsanInterceptors, RecvmmsgOnASocketDiesWhenRealtime) {
130918d5d84dSDavid CARLIER   mmsghdr msg{};
131018d5d84dSDavid CARLIER   auto Func = [&]() { recvmmsg(0, &msg, 0, 0, nullptr); };
131118d5d84dSDavid CARLIER   ExpectRealtimeDeath(Func, "recvmmsg");
131218d5d84dSDavid CARLIER   ExpectNonRealtimeSurvival(Func);
131318d5d84dSDavid CARLIER }
131418d5d84dSDavid CARLIER #endif
131518d5d84dSDavid CARLIER 
13161e07c480SChris Apple TEST(TestRtsanInterceptors, ShutdownOnASocketDiesWhenRealtime) {
13171e07c480SChris Apple   auto Func = [&]() { shutdown(0, 0); };
13181e07c480SChris Apple   ExpectRealtimeDeath(Func, "shutdown");
13191e07c480SChris Apple   ExpectNonRealtimeSurvival(Func);
13201e07c480SChris Apple }
13219ed6f7f9SChris Apple 
13224aedb970SDavid CARLIER #if SANITIZER_INTERCEPT_GETSOCKNAME
13234aedb970SDavid CARLIER TEST(TestRtsanInterceptors, GetsocknameOnASocketDiesWhenRealtime) {
13244aedb970SDavid CARLIER   sockaddr addr{};
13254aedb970SDavid CARLIER   socklen_t len{};
13264aedb970SDavid CARLIER   auto Func = [&]() { getsockname(0, &addr, &len); };
13274aedb970SDavid CARLIER   ExpectRealtimeDeath(Func, "getsockname");
13284aedb970SDavid CARLIER   ExpectNonRealtimeSurvival(Func);
13294aedb970SDavid CARLIER }
13304aedb970SDavid CARLIER #endif
13314aedb970SDavid CARLIER 
133218d5d84dSDavid CARLIER #if SANITIZER_INTERCEPT_GETPEERNAME
133318d5d84dSDavid CARLIER TEST(TestRtsanInterceptors, GetpeernameOnASocketDiesWhenRealtime) {
133418d5d84dSDavid CARLIER   sockaddr addr{};
133518d5d84dSDavid CARLIER   socklen_t len{};
133618d5d84dSDavid CARLIER   auto Func = [&]() { getpeername(0, &addr, &len); };
133718d5d84dSDavid CARLIER   ExpectRealtimeDeath(Func, "getpeername");
133818d5d84dSDavid CARLIER   ExpectNonRealtimeSurvival(Func);
133918d5d84dSDavid CARLIER }
134018d5d84dSDavid CARLIER #endif
134118d5d84dSDavid CARLIER 
1342939f2900SDavid CARLIER #if SANITIZER_INTERCEPT_GETSOCKOPT
1343939f2900SDavid CARLIER TEST(TestRtsanInterceptors, GetsockoptOnASocketDiesWhenRealtime) {
1344939f2900SDavid CARLIER   int val = 0;
1345939f2900SDavid CARLIER   socklen_t len = static_cast<socklen_t>(sizeof(val));
1346939f2900SDavid CARLIER   auto Func = [&val, &len]() {
1347939f2900SDavid CARLIER     getsockopt(0, SOL_SOCKET, SO_REUSEADDR, &val, &len);
1348939f2900SDavid CARLIER   };
1349939f2900SDavid CARLIER   ExpectRealtimeDeath(Func, "getsockopt");
1350939f2900SDavid CARLIER   ExpectNonRealtimeSurvival(Func);
1351939f2900SDavid CARLIER }
1352939f2900SDavid CARLIER 
1353939f2900SDavid CARLIER TEST(TestRtsanInterceptors, SetsockoptOnASocketDiesWhenRealtime) {
1354939f2900SDavid CARLIER   int val = 0;
1355939f2900SDavid CARLIER   socklen_t len = static_cast<socklen_t>(sizeof(val));
1356939f2900SDavid CARLIER   auto Func = [&val, &len]() {
1357939f2900SDavid CARLIER     setsockopt(0, SOL_SOCKET, SO_REUSEADDR, &val, len);
1358939f2900SDavid CARLIER   };
1359939f2900SDavid CARLIER   ExpectRealtimeDeath(Func, "setsockopt");
1360939f2900SDavid CARLIER   ExpectNonRealtimeSurvival(Func);
1361939f2900SDavid CARLIER }
1362939f2900SDavid CARLIER #endif
1363939f2900SDavid CARLIER 
1364e21b8046SDavid CARLIER TEST(TestRtsanInterceptors, SocketpairDiesWhenRealtime) {
1365e21b8046SDavid CARLIER   int pair[2]{};
1366e21b8046SDavid CARLIER   auto Func = [&pair]() { socketpair(0, 0, 0, pair); };
1367e21b8046SDavid CARLIER   ExpectRealtimeDeath(Func, "socketpair");
1368e21b8046SDavid CARLIER   ExpectNonRealtimeSurvival(Func);
1369e21b8046SDavid CARLIER }
1370e21b8046SDavid CARLIER 
13719c3665c8SChris Apple /*
13729c3665c8SChris Apple     I/O Multiplexing
13739c3665c8SChris Apple */
13749c3665c8SChris Apple 
13759c3665c8SChris Apple TEST(TestRtsanInterceptors, PollDiesWhenRealtime) {
13769c3665c8SChris Apple   struct pollfd fds[1];
13779c3665c8SChris Apple   fds[0].fd = 0;
13789c3665c8SChris Apple   fds[0].events = POLLIN;
13799c3665c8SChris Apple 
13809c3665c8SChris Apple   auto Func = [&fds]() { poll(fds, 1, 0); };
13819c3665c8SChris Apple 
13829c3665c8SChris Apple   ExpectRealtimeDeath(Func, "poll");
13839c3665c8SChris Apple   ExpectNonRealtimeSurvival(Func);
13849c3665c8SChris Apple }
13859c3665c8SChris Apple 
13869c3665c8SChris Apple #if !SANITIZER_APPLE
13879c3665c8SChris Apple // FIXME: This should work on Darwin as well
13889c3665c8SChris Apple // see the comment near the interceptor
13899c3665c8SChris Apple TEST(TestRtsanInterceptors, SelectDiesWhenRealtime) {
13909c3665c8SChris Apple   fd_set readfds;
13919c3665c8SChris Apple   FD_ZERO(&readfds);
13929c3665c8SChris Apple   FD_SET(0, &readfds);
13939c3665c8SChris Apple   struct timeval timeout = {0, 0};
13949c3665c8SChris Apple 
13959c3665c8SChris Apple   auto Func = [&readfds, &timeout]() {
13969c3665c8SChris Apple     select(1, &readfds, nullptr, nullptr, &timeout);
13979c3665c8SChris Apple   };
13989c3665c8SChris Apple   ExpectRealtimeDeath(Func, "select");
13999c3665c8SChris Apple   ExpectNonRealtimeSurvival(Func);
14009c3665c8SChris Apple }
14019c3665c8SChris Apple #endif
14029c3665c8SChris Apple 
14039c3665c8SChris Apple TEST(TestRtsanInterceptors, PSelectDiesWhenRealtime) {
14049c3665c8SChris Apple   fd_set readfds;
14059c3665c8SChris Apple   FD_ZERO(&readfds);
14069c3665c8SChris Apple   FD_SET(0, &readfds);
14079c3665c8SChris Apple   struct timespec timeout = {0, 0};
14089c3665c8SChris Apple 
14099c3665c8SChris Apple   auto Func = [&]() {
14109c3665c8SChris Apple     pselect(1, &readfds, nullptr, nullptr, &timeout, nullptr);
14119c3665c8SChris Apple   };
14129c3665c8SChris Apple   ExpectRealtimeDeath(Func, "pselect");
14139c3665c8SChris Apple   ExpectNonRealtimeSurvival(Func);
14149c3665c8SChris Apple }
14159c3665c8SChris Apple 
14169c3665c8SChris Apple #if SANITIZER_INTERCEPT_EPOLL
14179c3665c8SChris Apple TEST(TestRtsanInterceptors, EpollCreateDiesWhenRealtime) {
14189c3665c8SChris Apple   auto Func = []() { epoll_create(1); };
14199c3665c8SChris Apple   ExpectRealtimeDeath(Func, "epoll_create");
14209c3665c8SChris Apple   ExpectNonRealtimeSurvival(Func);
14219c3665c8SChris Apple }
14229c3665c8SChris Apple 
14239c3665c8SChris Apple TEST(TestRtsanInterceptors, EpollCreate1DiesWhenRealtime) {
14249c3665c8SChris Apple   auto Func = []() { epoll_create1(EPOLL_CLOEXEC); };
14259c3665c8SChris Apple   ExpectRealtimeDeath(Func, "epoll_create1");
14269c3665c8SChris Apple   ExpectNonRealtimeSurvival(Func);
14279c3665c8SChris Apple }
14289c3665c8SChris Apple 
14299c3665c8SChris Apple class EpollTest : public ::testing::Test {
14309c3665c8SChris Apple protected:
14319c3665c8SChris Apple   void SetUp() override {
14329c3665c8SChris Apple     epfd = epoll_create1(EPOLL_CLOEXEC);
14339c3665c8SChris Apple     ASSERT_GE(epfd, 0);
14349c3665c8SChris Apple   }
14359c3665c8SChris Apple 
14369c3665c8SChris Apple   void TearDown() override {
14379c3665c8SChris Apple     if (epfd >= 0)
14389c3665c8SChris Apple       close(epfd);
14399c3665c8SChris Apple   }
14409c3665c8SChris Apple 
14419c3665c8SChris Apple   int GetEpollFd() { return epfd; }
14429c3665c8SChris Apple 
14439c3665c8SChris Apple private:
14449c3665c8SChris Apple   int epfd = -1;
14459c3665c8SChris Apple };
14469c3665c8SChris Apple 
14479c3665c8SChris Apple TEST_F(EpollTest, EpollCtlDiesWhenRealtime) {
14489c3665c8SChris Apple   auto Func = [this]() {
14499c3665c8SChris Apple     struct epoll_event event = {.events = EPOLLIN, .data = {.fd = 0}};
14509c3665c8SChris Apple     epoll_ctl(GetEpollFd(), EPOLL_CTL_ADD, 0, &event);
14519c3665c8SChris Apple   };
14529c3665c8SChris Apple   ExpectRealtimeDeath(Func, "epoll_ctl");
14539c3665c8SChris Apple   ExpectNonRealtimeSurvival(Func);
14549c3665c8SChris Apple }
14559c3665c8SChris Apple 
14569c3665c8SChris Apple TEST_F(EpollTest, EpollWaitDiesWhenRealtime) {
14579c3665c8SChris Apple   auto Func = [this]() {
14589c3665c8SChris Apple     struct epoll_event events[1];
14599c3665c8SChris Apple     epoll_wait(GetEpollFd(), events, 1, 0);
14609c3665c8SChris Apple   };
14619c3665c8SChris Apple 
14629c3665c8SChris Apple   ExpectRealtimeDeath(Func, "epoll_wait");
14639c3665c8SChris Apple   ExpectNonRealtimeSurvival(Func);
14649c3665c8SChris Apple }
14659c3665c8SChris Apple 
14669c3665c8SChris Apple TEST_F(EpollTest, EpollPWaitDiesWhenRealtime) {
14679c3665c8SChris Apple   auto Func = [this]() {
14689c3665c8SChris Apple     struct epoll_event events[1];
14699c3665c8SChris Apple     epoll_pwait(GetEpollFd(), events, 1, 0, nullptr);
14709c3665c8SChris Apple   };
14719c3665c8SChris Apple 
14729c3665c8SChris Apple   ExpectRealtimeDeath(Func, "epoll_pwait");
14739c3665c8SChris Apple   ExpectNonRealtimeSurvival(Func);
14749c3665c8SChris Apple }
14759c3665c8SChris Apple #endif // SANITIZER_INTERCEPT_EPOLL
14769c3665c8SChris Apple 
1477adfef2a7SDavid CARLIER #if SANITIZER_INTERCEPT_PPOLL
1478adfef2a7SDavid CARLIER TEST(TestRtsanInterceptors, PpollDiesWhenRealtime) {
1479adfef2a7SDavid CARLIER   struct pollfd fds[1];
1480adfef2a7SDavid CARLIER   fds[0].fd = 0;
1481adfef2a7SDavid CARLIER   fds[0].events = POLLIN;
1482adfef2a7SDavid CARLIER 
1483d8e10d13SThurston Dang   timespec ts = {0, 0};
1484adfef2a7SDavid CARLIER 
1485adfef2a7SDavid CARLIER   auto Func = [&fds, &ts]() { ppoll(fds, 1, &ts, nullptr); };
1486adfef2a7SDavid CARLIER 
1487adfef2a7SDavid CARLIER   ExpectRealtimeDeath(Func, "ppoll");
1488adfef2a7SDavid CARLIER   ExpectNonRealtimeSurvival(Func);
1489adfef2a7SDavid CARLIER }
1490adfef2a7SDavid CARLIER #endif
1491adfef2a7SDavid CARLIER 
14929c3665c8SChris Apple #if SANITIZER_INTERCEPT_KQUEUE
14939c3665c8SChris Apple TEST(TestRtsanInterceptors, KqueueDiesWhenRealtime) {
14949c3665c8SChris Apple   auto Func = []() { kqueue(); };
14959c3665c8SChris Apple   ExpectRealtimeDeath(Func, "kqueue");
14969c3665c8SChris Apple   ExpectNonRealtimeSurvival(Func);
14979c3665c8SChris Apple }
14989c3665c8SChris Apple 
14999c3665c8SChris Apple class KqueueTest : public ::testing::Test {
15009c3665c8SChris Apple protected:
15019c3665c8SChris Apple   void SetUp() override {
15029c3665c8SChris Apple     kq = kqueue();
15039c3665c8SChris Apple     ASSERT_GE(kq, 0);
15049c3665c8SChris Apple   }
15059c3665c8SChris Apple 
15069c3665c8SChris Apple   void TearDown() override {
15079c3665c8SChris Apple     if (kq >= 0)
15089c3665c8SChris Apple       close(kq);
15099c3665c8SChris Apple   }
15109c3665c8SChris Apple 
15119c3665c8SChris Apple   int GetKqueueFd() { return kq; }
15129c3665c8SChris Apple 
15139c3665c8SChris Apple private:
15149c3665c8SChris Apple   int kq = -1;
15159c3665c8SChris Apple };
15169c3665c8SChris Apple 
15179c3665c8SChris Apple TEST_F(KqueueTest, KeventDiesWhenRealtime) {
15189c3665c8SChris Apple   struct kevent event;
15199c3665c8SChris Apple   EV_SET(&event, 0, EVFILT_READ, EV_ADD, 0, 0, nullptr);
15209c3665c8SChris Apple   struct timespec timeout = {0, 0};
15219c3665c8SChris Apple 
15229c3665c8SChris Apple   auto Func = [this, event, timeout]() {
15239c3665c8SChris Apple     kevent(GetKqueueFd(), &event, 1, nullptr, 0, &timeout);
15249c3665c8SChris Apple   };
15259c3665c8SChris Apple 
15269c3665c8SChris Apple   ExpectRealtimeDeath(Func, "kevent");
15279c3665c8SChris Apple   ExpectNonRealtimeSurvival(Func);
15289c3665c8SChris Apple }
15299c3665c8SChris Apple 
15309c3665c8SChris Apple TEST_F(KqueueTest, Kevent64DiesWhenRealtime) {
15319c3665c8SChris Apple   struct kevent64_s event;
15329c3665c8SChris Apple   EV_SET64(&event, 0, EVFILT_READ, EV_ADD, 0, 0, 0, 0, 0);
15339c3665c8SChris Apple   struct timespec timeout = {0, 0};
15349c3665c8SChris Apple 
15359c3665c8SChris Apple   auto Func = [this, event, timeout]() {
15369c3665c8SChris Apple     kevent64(GetKqueueFd(), &event, 1, nullptr, 0, 0, &timeout);
15379c3665c8SChris Apple   };
15389c3665c8SChris Apple 
15399c3665c8SChris Apple   ExpectRealtimeDeath(Func, "kevent64");
15409c3665c8SChris Apple   ExpectNonRealtimeSurvival(Func);
15419c3665c8SChris Apple }
15429c3665c8SChris Apple #endif // SANITIZER_INTERCEPT_KQUEUE
15439c3665c8SChris Apple 
1544f3d2e75eSDavid CARLIER #if SANITIZER_LINUX
1545f3d2e75eSDavid CARLIER TEST(TestRtsanInterceptors, InotifyInitDiesWhenRealtime) {
1546f3d2e75eSDavid CARLIER   auto Func = []() { inotify_init(); };
1547f3d2e75eSDavid CARLIER   ExpectRealtimeDeath(Func, "inotify_init");
1548f3d2e75eSDavid CARLIER   ExpectNonRealtimeSurvival(Func);
1549f3d2e75eSDavid CARLIER }
1550f3d2e75eSDavid CARLIER 
1551f3d2e75eSDavid CARLIER TEST(TestRtsanInterceptors, InotifyInit1DiesWhenRealtime) {
1552f3d2e75eSDavid CARLIER   auto Func = []() { inotify_init1(0); };
1553f3d2e75eSDavid CARLIER   ExpectRealtimeDeath(Func, "inotify_init1");
1554f3d2e75eSDavid CARLIER   ExpectNonRealtimeSurvival(Func);
1555f3d2e75eSDavid CARLIER }
1556f3d2e75eSDavid CARLIER 
1557f3d2e75eSDavid CARLIER TEST(TestRtsanInterceptors, InotifyAddWatchDiesWhenRealtime) {
1558f3d2e75eSDavid CARLIER   int fd = inotify_init();
1559f3d2e75eSDavid CARLIER   EXPECT_THAT(fd, Ne(-1));
1560f3d2e75eSDavid CARLIER   auto Func = [fd]() {
1561f3d2e75eSDavid CARLIER     inotify_add_watch(fd, "/tmp/rtsan_inotify", IN_CREATE);
1562f3d2e75eSDavid CARLIER   };
1563f3d2e75eSDavid CARLIER   ExpectRealtimeDeath(Func, "inotify_add_watch");
1564f3d2e75eSDavid CARLIER   ExpectNonRealtimeSurvival(Func);
1565f3d2e75eSDavid CARLIER }
1566f3d2e75eSDavid CARLIER 
1567f3d2e75eSDavid CARLIER TEST(TestRtsanInterceptors, InotifyRmWatchDiesWhenRealtime) {
1568f3d2e75eSDavid CARLIER   int fd = inotify_init();
1569f3d2e75eSDavid CARLIER   EXPECT_THAT(fd, Ne(-1));
1570f3d2e75eSDavid CARLIER   auto Func = [fd]() { inotify_rm_watch(fd, -1); };
1571f3d2e75eSDavid CARLIER   ExpectRealtimeDeath(Func, "inotify_rm_watch");
1572f3d2e75eSDavid CARLIER   ExpectNonRealtimeSurvival(Func);
1573f3d2e75eSDavid CARLIER }
1574f3d2e75eSDavid CARLIER #endif
1575f3d2e75eSDavid CARLIER 
1576fce917d3SChris Apple TEST(TestRtsanInterceptors, MkfifoDiesWhenRealtime) {
1577fce917d3SChris Apple   auto Func = []() { mkfifo("/tmp/rtsan_test_fifo", 0); };
1578fce917d3SChris Apple   ExpectRealtimeDeath(Func, "mkfifo");
1579fce917d3SChris Apple   ExpectNonRealtimeSurvival(Func);
1580fce917d3SChris Apple }
1581fce917d3SChris Apple 
1582fce917d3SChris Apple TEST(TestRtsanInterceptors, PipeDiesWhenRealtime) {
1583fce917d3SChris Apple   int fds[2];
1584fce917d3SChris Apple   auto Func = [&fds]() { pipe(fds); };
1585fce917d3SChris Apple   ExpectRealtimeDeath(Func, "pipe");
1586fce917d3SChris Apple   ExpectNonRealtimeSurvival(Func);
1587fce917d3SChris Apple }
1588fce917d3SChris Apple 
158902909a40SDavid CARLIER #if !SANITIZER_APPLE
159002909a40SDavid CARLIER TEST(TestRtsanInterceptors, Pipe2DiesWhenRealtime) {
159102909a40SDavid CARLIER   int fds[2];
159202909a40SDavid CARLIER   auto Func = [&fds]() { pipe2(fds, O_CLOEXEC); };
159302909a40SDavid CARLIER   ExpectRealtimeDeath(Func, "pipe2");
159402909a40SDavid CARLIER   ExpectNonRealtimeSurvival(Func);
159502909a40SDavid CARLIER }
159602909a40SDavid CARLIER #endif
159702909a40SDavid CARLIER 
1598eae30a24SChris Apple #pragma clang diagnostic push
1599eae30a24SChris Apple #pragma clang diagnostic ignored "-Wdeprecated-declarations"
1600eae30a24SChris Apple TEST(TestRtsanInterceptors, SyscallDiesWhenRealtime) {
1601eae30a24SChris Apple   auto Func = []() { syscall(SYS_getpid); };
1602eae30a24SChris Apple   ExpectRealtimeDeath(Func, "syscall");
1603eae30a24SChris Apple   ExpectNonRealtimeSurvival(Func);
1604eae30a24SChris Apple }
1605eae30a24SChris Apple 
1606eae30a24SChris Apple TEST(TestRtsanInterceptors, GetPidReturnsSame) {
1607eae30a24SChris Apple   int pid = syscall(SYS_getpid);
1608eae30a24SChris Apple   EXPECT_THAT(pid, Ne(-1));
1609eae30a24SChris Apple 
1610eae30a24SChris Apple   EXPECT_THAT(getpid(), Eq(pid));
1611eae30a24SChris Apple }
1612eae30a24SChris Apple #pragma clang diagnostic pop
1613eae30a24SChris Apple 
16149ed6f7f9SChris Apple #endif // SANITIZER_POSIX
1615