[compiler-rt] [rtsan][compiler-rt] Add read, write, pread, pwrite, readv, and writev interceptors (PR #106161)
Chris Apple via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 26 17:11:06 PDT 2024
https://github.com/cjappl created https://github.com/llvm/llvm-project/pull/106161
None
>From cc91637484649fa882fd0c53af19506a9682331a Mon Sep 17 00:00:00 2001
From: Chris Apple <cja-private at pm.me>
Date: Thu, 18 Jul 2024 17:29:01 +0200
Subject: [PATCH] [rtsan][compiler-rt] Add read and write interceptors
---
compiler-rt/lib/rtsan/rtsan_interceptors.cpp | 37 ++++++
.../rtsan/tests/rtsan_test_interceptors.cpp | 109 +++++++++++++++---
2 files changed, 129 insertions(+), 17 deletions(-)
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);
}
/*
More information about the llvm-commits
mailing list