Skip to content

Conversation

@cjappl
Copy link
Contributor

@cjappl cjappl commented Aug 27, 2024

No description provided.

@cjappl cjappl requested review from MaskRay and vitalybuka August 27, 2024 00:10
@cjappl
Copy link
Contributor Author

cjappl commented Aug 27, 2024

CC @davidtrevelyan

@llvmbot
Copy link
Member

llvmbot commented Aug 27, 2024

@llvm/pr-subscribers-compiler-rt-sanitizer

Author: Chris Apple (cjappl)

Changes

Full diff: https://github.com/llvm/llvm-project/pull/106161.diff

2 Files Affected:

  • (modified) compiler-rt/lib/rtsan/rtsan_interceptors.cpp (+37)
  • (modified) compiler-rt/lib/rtsan/tests/rtsan_test_interceptors.cpp (+92-17)
diff --git a/compiler-rt/lib/rtsan/rtsan_interceptors.cpp b/compiler-rt/lib/rtsan/rtsan_interceptors.cpp
index e451ea6b03622a..1b1655f94eaa5a 100644
--- a/compiler-rt/lib/rtsan/rtsan_interceptors.cpp
+++ b/compiler-rt/lib/rtsan/rtsan_interceptors.cpp
@@ -161,6 +161,37 @@ INTERCEPTOR(int, puts, const char *s) {
   return REAL(puts)(s);
 }
 
+INTERCEPTOR(ssize_t, read, int fd, void *buf, size_t count) {
+  ExpectNotRealtime("read");
+  return REAL(read)(fd, buf, count);
+}
+
+INTERCEPTOR(ssize_t, write, int fd, const void *buf, size_t count) {
+  ExpectNotRealtime("write");
+  return REAL(write)(fd, buf, count);
+}
+
+INTERCEPTOR(ssize_t, pread, int fd, void *buf, size_t count, off_t offset) {
+  ExpectNotRealtime("pread");
+  return REAL(pread)(fd, buf, count, offset);
+}
+
+INTERCEPTOR(ssize_t, readv, int fd, const struct iovec *iov, int iovcnt) {
+  ExpectNotRealtime("readv");
+  return REAL(readv)(fd, iov, iovcnt);
+}
+
+INTERCEPTOR(ssize_t, pwrite, int fd, const void *buf, size_t count,
+            off_t offset) {
+  ExpectNotRealtime("pwrite");
+  return REAL(pwrite)(fd, buf, count, offset);
+}
+
+INTERCEPTOR(ssize_t, writev, int fd, const struct iovec *iov, int iovcnt) {
+  ExpectNotRealtime("writev");
+  return REAL(writev)(fd, iov, iovcnt);
+}
+
 // Concurrency
 #if SANITIZER_APPLE
 #pragma clang diagnostic push
@@ -400,6 +431,12 @@ void __rtsan::InitializeInterceptors() {
   INTERCEPT_FUNCTION(close);
   INTERCEPT_FUNCTION(fopen);
   INTERCEPT_FUNCTION(fread);
+  INTERCEPT_FUNCTION(read);
+  INTERCEPT_FUNCTION(write);
+  INTERCEPT_FUNCTION(pread);
+  INTERCEPT_FUNCTION(readv);
+  INTERCEPT_FUNCTION(pwrite);
+  INTERCEPT_FUNCTION(writev);
   INTERCEPT_FUNCTION(fwrite);
   INTERCEPT_FUNCTION(fclose);
   INTERCEPT_FUNCTION(fcntl);
diff --git a/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors.cpp b/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors.cpp
index 5b88cf64612942..c21707d9846d3a 100644
--- a/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors.cpp
+++ b/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors.cpp
@@ -18,6 +18,8 @@
 #if SANITIZER_APPLE
 #include <libkern/OSAtomic.h>
 #include <os/lock.h>
+#include <sys/types.h>
+#include <unistd.h>
 #endif
 
 #if SANITIZER_INTERCEPT_MEMALIGN || SANITIZER_INTERCEPT_PVALLOC
@@ -33,6 +35,7 @@
 #include <pthread.h>
 #include <stdio.h>
 #include <sys/socket.h>
+#include <sys/uio.h>
 
 using namespace testing;
 using namespace rtsan_testing;
@@ -274,23 +277,43 @@ TEST_F(RtsanFileTest, FopenDiesWhenRealtime) {
   ExpectNonRealtimeSurvival(func);
 }
 
-TEST_F(RtsanFileTest, FreadDiesWhenRealtime) {
-  auto fd = fopen(GetTemporaryFilePath(), "w");
-  auto func = [fd]() {
+class RtsanOpenedFileTest : public RtsanFileTest {
+protected:
+  void SetUp() override {
+    RtsanFileTest::SetUp();
+    file = fopen(GetTemporaryFilePath(), "w");
+    ASSERT_THAT(file, Ne(nullptr));
+    fd = fileno(file);
+    ASSERT_THAT(fd, Ne(-1));
+  }
+
+  void TearDown() override {
+    if (file != nullptr)
+      fclose(file);
+    RtsanFileTest::TearDown();
+  }
+
+  FILE *GetOpenFile() { return file; }
+
+  int GetOpenFd() { return fd; }
+
+private:
+  FILE *file = nullptr;
+  int fd = -1;
+};
+
+TEST_F(RtsanOpenedFileTest, FreadDiesWhenRealtime) {
+  auto func = [this]() {
     char c{};
-    fread(&c, 1, 1, fd);
+    fread(&c, 1, 1, GetOpenFile());
   };
   ExpectRealtimeDeath(func, "fread");
   ExpectNonRealtimeSurvival(func);
-  if (fd != nullptr)
-    fclose(fd);
 }
 
-TEST_F(RtsanFileTest, FwriteDiesWhenRealtime) {
-  auto fd = fopen(GetTemporaryFilePath(), "w");
-  ASSERT_NE(nullptr, fd);
-  auto message = "Hello, world!";
-  auto func = [&]() { fwrite(&message, 1, 4, fd); };
+TEST_F(RtsanOpenedFileTest, FwriteDiesWhenRealtime) {
+  const char *message = "Hello, world!";
+  auto func = [&]() { fwrite(&message, 1, 4, GetOpenFile()); };
   ExpectRealtimeDeath(func, "fwrite");
   ExpectNonRealtimeSurvival(func);
 }
@@ -309,14 +332,66 @@ TEST(TestRtsanInterceptors, PutsDiesWhenRealtime) {
   ExpectNonRealtimeSurvival(func);
 }
 
-TEST_F(RtsanFileTest, FputsDiesWhenRealtime) {
-  auto fd = fopen(GetTemporaryFilePath(), "w");
-  ASSERT_THAT(fd, Ne(nullptr)) << errno;
-  auto func = [fd]() { fputs("Hello, world!\n", fd); };
+TEST_F(RtsanOpenedFileTest, FputsDiesWhenRealtime) {
+  auto func = [this]() { fputs("Hello, world!\n", GetOpenFile()); };
   ExpectRealtimeDeath(func);
   ExpectNonRealtimeSurvival(func);
-  if (fd != nullptr)
-    fclose(fd);
+}
+
+TEST_F(RtsanOpenedFileTest, ReadDiesWhenRealtime) {
+  auto Func = [this]() {
+    char c{};
+    read(GetOpenFd(), &c, 1);
+  };
+  ExpectRealtimeDeath(Func, "read");
+  ExpectNonRealtimeSurvival(Func);
+}
+
+TEST_F(RtsanOpenedFileTest, WriteDiesWhenRealtime) {
+  auto Func = [this]() {
+    char c = 'a';
+    write(GetOpenFd(), &c, 1);
+  };
+  ExpectRealtimeDeath(Func, "write");
+  ExpectNonRealtimeSurvival(Func);
+}
+
+TEST_F(RtsanOpenedFileTest, PreadDiesWhenRealtime) {
+  auto Func = [this]() {
+    char c{};
+    pread(GetOpenFd(), &c, 1, 0);
+  };
+  ExpectRealtimeDeath(Func, "pread");
+  ExpectNonRealtimeSurvival(Func);
+}
+
+TEST_F(RtsanOpenedFileTest, ReadvDiesWhenRealtime) {
+  auto Func = [this]() {
+    char c{};
+    iovec iov{&c, 1};
+    readv(GetOpenFd(), &iov, 1);
+  };
+  ExpectRealtimeDeath(Func, "readv");
+  ExpectNonRealtimeSurvival(Func);
+}
+
+TEST_F(RtsanOpenedFileTest, PwriteDiesWhenRealtime) {
+  auto Func = [this]() {
+    char c = 'a';
+    pwrite(GetOpenFd(), &c, 1, 0);
+  };
+  ExpectRealtimeDeath(Func, "pwrite");
+  ExpectNonRealtimeSurvival(Func);
+}
+
+TEST_F(RtsanOpenedFileTest, WritevDiesWhenRealtime) {
+  auto Func = [this]() {
+    char c = 'a';
+    iovec iov{&c, 1};
+    writev(GetOpenFd(), &iov, 1);
+  };
+  ExpectRealtimeDeath(Func, "writev");
+  ExpectNonRealtimeSurvival(Func);
 }
 
 /*

@cjappl cjappl merged commit 556e9d0 into llvm:main Aug 27, 2024
@cjappl cjappl deleted the AddReadWriteInterceptors branch August 27, 2024 14:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants