diff --git a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp index f000deb3039a8..def8efaf05eea 100644 --- a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp +++ b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp @@ -297,6 +297,23 @@ INTERCEPTOR(FILE *, fdopen, int fd, const char *mode) { return REAL(fdopen)(fd, mode); } +#if SANITIZER_INTERCEPT_OPEN_MEMSTREAM +INTERCEPTOR(FILE *, open_memstream, char **buf, size_t *size) { + __rtsan_notify_intercepted_call("open_memstream"); + return REAL(open_memstream)(buf, size); +} + +INTERCEPTOR(FILE *, fmemopen, void *buf, size_t size, const char *mode) { + __rtsan_notify_intercepted_call("fmemopen"); + return REAL(fmemopen)(buf, size, mode); +} +#define RTSAN_MAYBE_INTERCEPT_OPEN_MEMSTREAM INTERCEPT_FUNCTION(open_memstream) +#define RTSAN_MAYBE_INTERCEPT_FMEMOPEN INTERCEPT_FUNCTION(fmemopen) +#else +#define RTSAN_MAYBE_INTERCEPT_OPEN_MEMSTREAM +#define RTSAN_MAYBE_INTERCEPT_FMEMOPEN +#endif + INTERCEPTOR(int, puts, const char *s) { __rtsan_notify_intercepted_call("puts"); return REAL(puts)(s); @@ -944,6 +961,8 @@ void __rtsan::InitializeInterceptors() { INTERCEPT_FUNCTION(fputs); INTERCEPT_FUNCTION(fdopen); INTERCEPT_FUNCTION(freopen); + RTSAN_MAYBE_INTERCEPT_OPEN_MEMSTREAM; + RTSAN_MAYBE_INTERCEPT_FMEMOPEN; 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 b3fb32ee8dcd4..f140ce7a3e78d 100644 --- a/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp +++ b/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp @@ -353,6 +353,31 @@ TEST_F(RtsanFileTest, FopenDiesWhenRealtime) { ExpectNonRealtimeSurvival(Func); } +#if SANITIZER_INTERCEPT_OPEN_MEMSTREAM +TEST_F(RtsanFileTest, OpenMemstreamDiesWhenRealtime) { + char *buffer; + size_t size; + auto Func = [&buffer, &size]() { + FILE *f = open_memstream(&buffer, &size); + EXPECT_THAT(f, Ne(nullptr)); + }; + + ExpectRealtimeDeath(Func, "open_memstream"); + ExpectNonRealtimeSurvival(Func); +} + +TEST_F(RtsanFileTest, FmemOpenDiesWhenRealtime) { + char buffer[1024]; + auto Func = [&buffer]() { + FILE *f = fmemopen(&buffer, sizeof(buffer), "w"); + EXPECT_THAT(f, Ne(nullptr)); + }; + + ExpectRealtimeDeath(Func, "fmemopen"); + ExpectNonRealtimeSurvival(Func); +} +#endif + class RtsanOpenedFileTest : public RtsanFileTest { protected: void SetUp() override {