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