[compiler-rt] [rtsan] Intercept various file system functions (PR #118183)
Chris Apple via llvm-commits
llvm-commits at lists.llvm.org
Sat Nov 30 11:18:44 PST 2024
https://github.com/cjappl created https://github.com/llvm/llvm-project/pull/118183
Adds interceptors for
* chmod
* fchmod
* mkdir
* rmdir
* umask
>From 7ee4264457374c87f4ba1795fbffdea83b9f01e3 Mon Sep 17 00:00:00 2001
From: Chris Apple <cja-private at pm.me>
Date: Sat, 30 Nov 2024 09:24:21 -0800
Subject: [PATCH] Chmod
---
.../lib/rtsan/rtsan_interceptors_posix.cpp | 31 +++++++++++
.../tests/rtsan_test_interceptors_posix.cpp | 55 +++++++++++++++++++
2 files changed, 86 insertions(+)
diff --git a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp
index 5debf13ab9815c..64f9ff082d542c 100644
--- a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp
+++ b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp
@@ -47,6 +47,7 @@ void OSSpinLockLock(volatile OSSpinLock *__lock);
#include <stdarg.h>
#include <stdio.h>
#include <sys/socket.h>
+#include <sys/stat.h>
#include <time.h>
#include <unistd.h>
@@ -358,6 +359,31 @@ INTERCEPTOR(int, dup2, int oldfd, int newfd) {
return REAL(dup2)(oldfd, newfd);
}
+INTERCEPTOR(int, chmod, const char *path, mode_t mode) {
+ __rtsan_notify_intercepted_call("chmod");
+ return REAL(chmod)(path, mode);
+}
+
+INTERCEPTOR(int, fchmod, int fd, mode_t mode) {
+ __rtsan_notify_intercepted_call("fchmod");
+ return REAL(fchmod)(fd, mode);
+}
+
+INTERCEPTOR(int, mkdir, const char *path, mode_t mode) {
+ __rtsan_notify_intercepted_call("mkdir");
+ return REAL(mkdir)(path, mode);
+}
+
+INTERCEPTOR(int, rmdir, const char *path) {
+ __rtsan_notify_intercepted_call("rmdir");
+ return REAL(rmdir)(path);
+}
+
+INTERCEPTOR(mode_t, umask, mode_t cmask) {
+ __rtsan_notify_intercepted_call("umask");
+ return REAL(umask)(cmask);
+}
+
// Concurrency
#if SANITIZER_APPLE
#pragma clang diagnostic push
@@ -818,6 +844,11 @@ void __rtsan::InitializeInterceptors() {
RTSAN_MAYBE_INTERCEPT_LSEEK64;
INTERCEPT_FUNCTION(dup);
INTERCEPT_FUNCTION(dup2);
+ INTERCEPT_FUNCTION(chmod);
+ INTERCEPT_FUNCTION(fchmod);
+ INTERCEPT_FUNCTION(mkdir);
+ INTERCEPT_FUNCTION(rmdir);
+ INTERCEPT_FUNCTION(umask);
INTERCEPT_FUNCTION(ioctl);
#if SANITIZER_APPLE
diff --git a/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp b/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp
index 8551424717de6d..f715b0b11b2885 100644
--- a/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp
+++ b/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp
@@ -46,6 +46,7 @@
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/socket.h>
+#include <sys/stat.h>
#include <sys/types.h>
#include <sys/uio.h>
@@ -442,6 +443,60 @@ TEST_F(RtsanOpenedFileTest, Dup2DiesWhenRealtime) {
ExpectNonRealtimeSurvival(Func);
}
+TEST_F(RtsanFileTest, ChmodDiesWhenRealtime) {
+ auto Func = [this]() { chmod(GetTemporaryFilePath(), 0777); };
+ ExpectRealtimeDeath(Func, "chmod");
+ ExpectNonRealtimeSurvival(Func);
+}
+
+TEST_F(RtsanOpenedFileTest, FchmodDiesWhenRealtime) {
+ auto Func = [this]() { fchmod(GetOpenFd(), 0777); };
+ ExpectRealtimeDeath(Func, "fchmod");
+ ExpectNonRealtimeSurvival(Func);
+}
+
+TEST(TestRtsanInterceptors, UmaskDiesWhenRealtime) {
+ auto Func = []() { umask(0); };
+ ExpectRealtimeDeath(Func, "umask");
+ ExpectNonRealtimeSurvival(Func);
+}
+
+class RtsanDirectoryTest : public ::testing::Test {
+protected:
+ void SetUp() override {
+ const ::testing::TestInfo *const test_info =
+ ::testing::UnitTest::GetInstance()->current_test_info();
+ directory_path_ = std::string("/tmp/rtsan_temp_dir_") + test_info->name();
+ RemoveTemporaryDirectory();
+ }
+
+ const char *GetTemporaryDirectoryPath() const {
+ return directory_path_.c_str();
+ }
+
+ void TearDown() override { RemoveTemporaryDirectory(); }
+
+private:
+ void RemoveTemporaryDirectory() const {
+ std::remove(GetTemporaryDirectoryPath());
+ }
+ std::string directory_path_;
+};
+
+TEST_F(RtsanDirectoryTest, MkdirDiesWhenRealtime) {
+ auto Func = [this]() { mkdir(GetTemporaryDirectoryPath(), 0777); };
+ ExpectRealtimeDeath(Func, "mkdir");
+ ExpectNonRealtimeSurvival(Func);
+}
+
+TEST_F(RtsanDirectoryTest, RmdirDiesWhenRealtime) {
+ // We don't actually create this directory before we try to remove it
+ // Thats OK - we are just making sure the call gets intercepted
+ auto Func = [this]() { rmdir(GetTemporaryDirectoryPath()); };
+ ExpectRealtimeDeath(Func, "rmdir");
+ ExpectNonRealtimeSurvival(Func);
+}
+
TEST_F(RtsanOpenedFileTest, FreadDiesWhenRealtime) {
auto Func = [this]() {
char c{};
More information about the llvm-commits
mailing list