Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[compiler-rt][rtsan] stat api interception. #128430

Merged
merged 1 commit into from
Feb 23, 2025
Merged

Conversation

devnexen
Copy link
Member

No description provided.

@llvmbot
Copy link
Member

llvmbot commented Feb 23, 2025

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

Author: David CARLIER (devnexen)

Changes

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

2 Files Affected:

  • (modified) compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp (+36)
  • (modified) compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp (+29-2)
diff --git a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp
index 5b9e992639f55..ee602bcad68f9 100644
--- a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp
+++ b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp
@@ -285,6 +285,36 @@ INTERCEPTOR(int, unlinkat, int fd, const char *pathname, int flag) {
   return REAL(unlinkat)(fd, pathname, flag);
 }
 
+INTERCEPTOR(int, stat, const char *pathname, struct stat *s) {
+  __rtsan_notify_intercepted_call("stat");
+  return REAL(stat)(pathname, s);
+}
+
+INTERCEPTOR(int, lstat, const char *pathname, struct stat *s) {
+  __rtsan_notify_intercepted_call("lstat");
+  return REAL(lstat)(pathname, s);
+}
+
+INTERCEPTOR(int, fstat, int fd, struct stat *s) {
+  __rtsan_notify_intercepted_call("fstat");
+  return REAL(fstat)(fd, s);
+}
+
+INTERCEPTOR(int, stat64, const char *pathname, struct stat64 *s) {
+  __rtsan_notify_intercepted_call("stat64");
+  return REAL(stat64)(pathname, s);
+}
+
+INTERCEPTOR(int, lstat64, const char *pathname, struct stat64 *s) {
+  __rtsan_notify_intercepted_call("lstat64");
+  return REAL(lstat64)(pathname, s);
+}
+
+INTERCEPTOR(int, fstat64, int fd, struct stat64 *s) {
+  __rtsan_notify_intercepted_call("fstat64");
+  return REAL(fstat64)(fd, s);
+}
+
 // Streams
 
 INTERCEPTOR(FILE *, fopen, const char *path, const char *mode) {
@@ -1437,6 +1467,12 @@ void __rtsan::InitializeInterceptors() {
   RTSAN_MAYBE_INTERCEPT_READLINKAT;
   INTERCEPT_FUNCTION(unlink);
   INTERCEPT_FUNCTION(unlinkat);
+  INTERCEPT_FUNCTION(stat);
+  INTERCEPT_FUNCTION(lstat);
+  INTERCEPT_FUNCTION(fstat);
+  INTERCEPT_FUNCTION(stat64);
+  INTERCEPT_FUNCTION(lstat64);
+  INTERCEPT_FUNCTION(fstat64);
   INTERCEPT_FUNCTION(fopen);
   RTSAN_MAYBE_INTERCEPT_FOPEN64;
   RTSAN_MAYBE_INTERCEPT_FREOPEN64;
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 d1c5a94c12213..301f4e2694962 100644
--- a/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp
+++ b/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp
@@ -401,7 +401,7 @@ TEST_F(RtsanFileTest, FcntlFlockDiesWhenRealtime) {
   ASSERT_THAT(fd, Ne(-1));
 
   auto Func = [fd]() {
-    struct flock lock {};
+    struct flock lock{};
     lock.l_type = F_RDLCK;
     lock.l_whence = SEEK_SET;
     lock.l_start = 0;
@@ -735,7 +735,7 @@ TEST(TestRtsanInterceptors, IoctlBehavesWithOutputPointer) {
     GTEST_SKIP();
   }
 
-  struct ifreq ifr {};
+  struct ifreq ifr{};
   strncpy(ifr.ifr_name, ifaddr->ifa_name, IFNAMSIZ - 1);
 
   int retval = ioctl(sock, SIOCGIFADDR, &ifr);
@@ -875,6 +875,33 @@ TEST_F(RtsanOpenedFileTest, UnlinkatDiesWhenRealtime) {
   ExpectNonRealtimeSurvival(Func);
 }
 
+TEST_F(RtsanOpenedFileTest, StatDiesWhenRealtime) {
+  auto Func = [&]() {
+    struct stat s{};
+    stat(GetTemporaryFilePath(), &s);
+  };
+  ExpectRealtimeDeath(Func, MAYBE_APPEND_64("stat"));
+  ExpectNonRealtimeSurvival(Func);
+}
+
+TEST_F(RtsanOpenedFileTest, LtatDiesWhenRealtime) {
+  auto Func = [&]() {
+    struct stat s{};
+    lstat(GetTemporaryFilePath(), &s);
+  };
+  ExpectRealtimeDeath(Func, MAYBE_APPEND_64("lstat"));
+  ExpectNonRealtimeSurvival(Func);
+}
+
+TEST_F(RtsanOpenedFileTest, FstatDiesWhenRealtime) {
+  auto Func = [&]() {
+    struct stat s{};
+    fstat(GetOpenFd(), &s);
+  };
+  ExpectRealtimeDeath(Func, MAYBE_APPEND_64("fstat"));
+  ExpectNonRealtimeSurvival(Func);
+}
+
 TEST_F(RtsanFileTest, FcloseDiesWhenRealtime) {
   FILE *f = fopen(GetTemporaryFilePath(), "w");
   EXPECT_THAT(f, Ne(nullptr));

@devnexen devnexen changed the title [compiler-rt][rtsan] [compiler-rt][rtsan] stat api interception. Feb 23, 2025
Copy link
Contributor

@cjappl cjappl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just double checking: Did you run these tests on mac? I only ask because I remember trying to implement these earlier last year and I had some problems on mac. The details are fuzzy now though...

LGTM if tests are happy on mac :)

return REAL(lstat)(pathname, s);
}

INTERCEPTOR(int, fstat, int fd, struct stat *s) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

another one you could consider in this PR is fstatat

@devnexen
Copy link
Member Author

Just double checking: Did you run these tests on mac? I only ask because I remember trying to implement these earlier last year and I had some problems on mac. The details are fuzzy now though...

LGTM if tests are happy on mac :)

I tested on mac and only this unrelated test fails:

Input file: <stdin>
Check file: /Users/dcarlier/Contribs/llvm-project/compiler-rt/test/rtsan/fork_exec.cpp

-dump-input=help explains the following input dump.

Input was:
<<<<<<
            1: ==73392==ERROR: RealtimeSanitizer: unsafe-library-call 
            2: Intercepted call to real-time unsafe function `fork` in real-time context! 
check:48'0                                                                               X error: no match found
            3:  #0 0x0001029cfc28 in fork rtsan_interceptors_posix.cpp:1366 
check:48'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            4:  #1 0x000102587d70 in main+0x24 (fork_exec.cpp.tmp:arm64+0x100003d70) 
check:48'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            5:  #2 0x0001937e4270 (<unknown module>) 
check:48'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            6:  
check:48'0     ~
            7: SUMMARY: RealtimeSanitizer: unsafe-library-call (fork_exec.cpp.tmp:arm64+0x100003d70) in main+0x24 
check:48'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            8: ==73392==ERROR: RealtimeSanitizer: unsafe-library-call 
check:48'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            9: Intercepted call to real-time unsafe function `pthread_mutex_lock` in real-time context! 
check:48'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
check:48'1     ?                                                                                         possible intended match
           10:  #0 0x0001029ceb6c in pthread_mutex_lock rtsan_interceptors_posix.cpp:750 
check:48'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           11:  #1 0x000193b639ec in _pthread_atfork_prepare_handlers+0x58 (libsystem_pthread.dylib:arm64+0x69ec) 
check:48'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           12:  #2 0x0001a172d498 in libSystem_atfork_prepare+0x1c (libSystem.B.dylib:arm64+0x1498) 
check:48'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           13:  #3 0x000193a1b404 in fork+0x20 (libsystem_c.dylib:arm64+0x24404) 
check:48'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           14:  #4 0x000102587d70 in main+0x24 (fork_exec.cpp.tmp:arm64+0x100003d70) 
check:48'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            .
            .
            .
>>>>>>

--

@cjappl
Copy link
Contributor

cjappl commented Feb 23, 2025

Is that a regression with this change, or that test always fails on your machine?

@devnexen
Copy link
Member Author

devnexen commented Feb 23, 2025

not a regression :) I just retried with main to be sure. Do not know which macos release runs on buildbot but I have always last version.

@devnexen devnexen merged commit 4d928d5 into llvm:main Feb 23, 2025
10 checks passed
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.

3 participants