diff --git a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp index 5b9e992639f55..d41af795db724 100644 --- a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp +++ b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp @@ -285,6 +285,33 @@ INTERCEPTOR(int, unlinkat, int fd, const char *pathname, int flag) { return REAL(unlinkat)(fd, pathname, flag); } +INTERCEPTOR(int, truncate, const char *pathname, off_t length) { + __rtsan_notify_intercepted_call("truncate"); + return REAL(truncate)(pathname, length); +} + +INTERCEPTOR(int, ftruncate, int fd, off_t length) { + __rtsan_notify_intercepted_call("ftruncate"); + return REAL(ftruncate)(fd, length); +} + +#if SANITIZER_LINUX +INTERCEPTOR(int, truncate64, const char *pathname, off64_t length) { + __rtsan_notify_intercepted_call("truncate64"); + return REAL(truncate64)(pathname, length); +} + +INTERCEPTOR(int, ftruncate64, int fd, off64_t length) { + __rtsan_notify_intercepted_call("ftruncate64"); + return REAL(ftruncate64)(fd, length); +} +#define RTSAN_MAYBE_INTERCEPT_TRUNCATE64 INTERCEPT_FUNCTION(truncate64) +#define RTSAN_MAYBE_INTERCEPT_FTRUNCATE64 INTERCEPT_FUNCTION(ftruncate64) +#else +#define RTSAN_MAYBE_INTERCEPT_TRUNCATE64 +#define RTSAN_MAYBE_INTERCEPT_FTRUNCATE64 +#endif + // Streams INTERCEPTOR(FILE *, fopen, const char *path, const char *mode) { @@ -1437,6 +1464,10 @@ void __rtsan::InitializeInterceptors() { RTSAN_MAYBE_INTERCEPT_READLINKAT; INTERCEPT_FUNCTION(unlink); INTERCEPT_FUNCTION(unlinkat); + INTERCEPT_FUNCTION(truncate); + INTERCEPT_FUNCTION(ftruncate); + RTSAN_MAYBE_INTERCEPT_TRUNCATE64; + RTSAN_MAYBE_INTERCEPT_FTRUNCATE64; 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..47bcafff51a4d 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,18 @@ TEST_F(RtsanOpenedFileTest, UnlinkatDiesWhenRealtime) { ExpectNonRealtimeSurvival(Func); } +TEST_F(RtsanOpenedFileTest, TruncateDiesWhenRealtime) { + auto Func = [&]() { truncate(GetTemporaryFilePath(), 16); }; + ExpectRealtimeDeath(Func, MAYBE_APPEND_64("truncate")); + ExpectNonRealtimeSurvival(Func); +} + +TEST_F(RtsanOpenedFileTest, FtruncateDiesWhenRealtime) { + auto Func = [&]() { ftruncate(GetOpenFd(), 16); }; + ExpectRealtimeDeath(Func, MAYBE_APPEND_64("ftruncate")); + ExpectNonRealtimeSurvival(Func); +} + TEST_F(RtsanFileTest, FcloseDiesWhenRealtime) { FILE *f = fopen(GetTemporaryFilePath(), "w"); EXPECT_THAT(f, Ne(nullptr));