diff --git a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp index f99d68defa613..f076c7eae9a22 100644 --- a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp +++ b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp @@ -244,14 +244,29 @@ INTERCEPTOR(FILE *, fopen, const char *path, const char *mode) { return REAL(fopen)(path, mode); } +INTERCEPTOR(FILE *, freopen, const char *path, const char *mode, FILE *stream) { + __rtsan_notify_intercepted_call("freopen"); + return REAL(freopen)(path, mode, stream); +} + +// Streams + #if SANITIZER_INTERCEPT_FOPEN64 INTERCEPTOR(FILE *, fopen64, const char *path, const char *mode) { __rtsan_notify_intercepted_call("fopen64"); return REAL(fopen64)(path, mode); } -#define RTSAN_MAYBE_INTERCEPT_FOPEN64 INTERCEPT_FUNCTION(fopen64) + +INTERCEPTOR(FILE *, freopen64, const char *path, const char *mode, + FILE *stream) { + __rtsan_notify_intercepted_call("freopen64"); + return REAL(freopen64)(path, mode, stream); +} +#define RTSAN_MAYBE_INTERCEPT_FOPEN64 INTERCEPT_FUNCTION(fopen64); +#define RTSAN_MAYBE_INTERCEPT_FREOPEN64 INTERCEPT_FUNCTION(freopen64); #else #define RTSAN_MAYBE_INTERCEPT_FOPEN64 +#define RTSAN_MAYBE_INTERCEPT_FREOPEN64 #endif // SANITIZER_INTERCEPT_FOPEN64 INTERCEPTOR(size_t, fread, void *ptr, size_t size, size_t nitems, @@ -276,7 +291,11 @@ INTERCEPTOR(int, fputs, const char *s, FILE *stream) { return REAL(fputs)(s, stream); } -// Streams +INTERCEPTOR(FILE *, fdopen, int fd, const char *mode) { + __rtsan_notify_intercepted_call("fdopen"); + return REAL(fdopen)(fd, mode); +} + INTERCEPTOR(int, puts, const char *s) { __rtsan_notify_intercepted_call("puts"); return REAL(puts)(s); @@ -904,6 +923,7 @@ void __rtsan::InitializeInterceptors() { INTERCEPT_FUNCTION(close); INTERCEPT_FUNCTION(fopen); RTSAN_MAYBE_INTERCEPT_FOPEN64; + RTSAN_MAYBE_INTERCEPT_FREOPEN64; INTERCEPT_FUNCTION(fread); INTERCEPT_FUNCTION(read); INTERCEPT_FUNCTION(write); @@ -921,6 +941,8 @@ void __rtsan::InitializeInterceptors() { RTSAN_MAYBE_INTERCEPT_CREAT64; INTERCEPT_FUNCTION(puts); INTERCEPT_FUNCTION(fputs); + INTERCEPT_FUNCTION(fdopen); + INTERCEPT_FUNCTION(freopen); INTERCEPT_FUNCTION(lseek); RTSAN_MAYBE_INTERCEPT_LSEEK64; INTERCEPT_FUNCTION(dup); 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 6e7cc3b3b3481..b3fb32ee8dcd4 100644 --- a/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp +++ b/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp @@ -391,6 +391,26 @@ TEST_F(RtsanOpenedFileTest, IoctlBehavesWithOutputArg) { EXPECT_THAT(arg, Ge(0)); } +TEST_F(RtsanOpenedFileTest, FdopenDiesWhenRealtime) { + auto Func = [&]() { + FILE *f = fdopen(GetOpenFd(), "w"); + EXPECT_THAT(f, Ne(nullptr)); + }; + + ExpectRealtimeDeath(Func, "fdopen"); + ExpectNonRealtimeSurvival(Func); +} + +TEST_F(RtsanOpenedFileTest, FreopenDiesWhenRealtime) { + auto Func = [&]() { + FILE *newfile = freopen(GetTemporaryFilePath(), "w", GetOpenFile()); + EXPECT_THAT(newfile, Ne(nullptr)); + }; + + ExpectRealtimeDeath(Func, MAYBE_APPEND_64("freopen")); + ExpectNonRealtimeSurvival(Func); +} + TEST(TestRtsanInterceptors, IoctlBehavesWithOutputPointer) { // These initial checks just see if we CAN run these tests. // If we can't (can't open a socket, or can't find an interface, just