Skip to content

Commit 4a07433

Browse files
authored
[rtsan] Intercept various file system functions (#118183)
Adds interceptors for * chmod * fchmod * mkdir * rmdir * umask
1 parent 1a3eace commit 4a07433

File tree

2 files changed

+86
-0
lines changed

2 files changed

+86
-0
lines changed

compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ void OSSpinLockLock(volatile OSSpinLock *__lock);
4747
#include <stdarg.h>
4848
#include <stdio.h>
4949
#include <sys/socket.h>
50+
#include <sys/stat.h>
5051
#include <time.h>
5152
#include <unistd.h>
5253

@@ -358,6 +359,31 @@ INTERCEPTOR(int, dup2, int oldfd, int newfd) {
358359
return REAL(dup2)(oldfd, newfd);
359360
}
360361

362+
INTERCEPTOR(int, chmod, const char *path, mode_t mode) {
363+
__rtsan_notify_intercepted_call("chmod");
364+
return REAL(chmod)(path, mode);
365+
}
366+
367+
INTERCEPTOR(int, fchmod, int fd, mode_t mode) {
368+
__rtsan_notify_intercepted_call("fchmod");
369+
return REAL(fchmod)(fd, mode);
370+
}
371+
372+
INTERCEPTOR(int, mkdir, const char *path, mode_t mode) {
373+
__rtsan_notify_intercepted_call("mkdir");
374+
return REAL(mkdir)(path, mode);
375+
}
376+
377+
INTERCEPTOR(int, rmdir, const char *path) {
378+
__rtsan_notify_intercepted_call("rmdir");
379+
return REAL(rmdir)(path);
380+
}
381+
382+
INTERCEPTOR(mode_t, umask, mode_t cmask) {
383+
__rtsan_notify_intercepted_call("umask");
384+
return REAL(umask)(cmask);
385+
}
386+
361387
// Concurrency
362388
#if SANITIZER_APPLE
363389
#pragma clang diagnostic push
@@ -835,6 +861,11 @@ void __rtsan::InitializeInterceptors() {
835861
RTSAN_MAYBE_INTERCEPT_LSEEK64;
836862
INTERCEPT_FUNCTION(dup);
837863
INTERCEPT_FUNCTION(dup2);
864+
INTERCEPT_FUNCTION(chmod);
865+
INTERCEPT_FUNCTION(fchmod);
866+
INTERCEPT_FUNCTION(mkdir);
867+
INTERCEPT_FUNCTION(rmdir);
868+
INTERCEPT_FUNCTION(umask);
838869
INTERCEPT_FUNCTION(ioctl);
839870

840871
RTSAN_MAYBE_INTERCEPT_OSSPINLOCKLOCK;

compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#include <sys/ioctl.h>
4747
#include <sys/mman.h>
4848
#include <sys/socket.h>
49+
#include <sys/stat.h>
4950
#include <sys/types.h>
5051
#include <sys/uio.h>
5152

@@ -442,6 +443,60 @@ TEST_F(RtsanOpenedFileTest, Dup2DiesWhenRealtime) {
442443
ExpectNonRealtimeSurvival(Func);
443444
}
444445

446+
TEST_F(RtsanFileTest, ChmodDiesWhenRealtime) {
447+
auto Func = [this]() { chmod(GetTemporaryFilePath(), 0777); };
448+
ExpectRealtimeDeath(Func, "chmod");
449+
ExpectNonRealtimeSurvival(Func);
450+
}
451+
452+
TEST_F(RtsanOpenedFileTest, FchmodDiesWhenRealtime) {
453+
auto Func = [this]() { fchmod(GetOpenFd(), 0777); };
454+
ExpectRealtimeDeath(Func, "fchmod");
455+
ExpectNonRealtimeSurvival(Func);
456+
}
457+
458+
TEST(TestRtsanInterceptors, UmaskDiesWhenRealtime) {
459+
auto Func = []() { umask(0); };
460+
ExpectRealtimeDeath(Func, "umask");
461+
ExpectNonRealtimeSurvival(Func);
462+
}
463+
464+
class RtsanDirectoryTest : public ::testing::Test {
465+
protected:
466+
void SetUp() override {
467+
const ::testing::TestInfo *const test_info =
468+
::testing::UnitTest::GetInstance()->current_test_info();
469+
directory_path_ = std::string("/tmp/rtsan_temp_dir_") + test_info->name();
470+
RemoveTemporaryDirectory();
471+
}
472+
473+
const char *GetTemporaryDirectoryPath() const {
474+
return directory_path_.c_str();
475+
}
476+
477+
void TearDown() override { RemoveTemporaryDirectory(); }
478+
479+
private:
480+
void RemoveTemporaryDirectory() const {
481+
std::remove(GetTemporaryDirectoryPath());
482+
}
483+
std::string directory_path_;
484+
};
485+
486+
TEST_F(RtsanDirectoryTest, MkdirDiesWhenRealtime) {
487+
auto Func = [this]() { mkdir(GetTemporaryDirectoryPath(), 0777); };
488+
ExpectRealtimeDeath(Func, "mkdir");
489+
ExpectNonRealtimeSurvival(Func);
490+
}
491+
492+
TEST_F(RtsanDirectoryTest, RmdirDiesWhenRealtime) {
493+
// We don't actually create this directory before we try to remove it
494+
// Thats OK - we are just making sure the call gets intercepted
495+
auto Func = [this]() { rmdir(GetTemporaryDirectoryPath()); };
496+
ExpectRealtimeDeath(Func, "rmdir");
497+
ExpectNonRealtimeSurvival(Func);
498+
}
499+
445500
TEST_F(RtsanOpenedFileTest, FreadDiesWhenRealtime) {
446501
auto Func = [this]() {
447502
char c{};

0 commit comments

Comments
 (0)