diff --git a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp index 4e51f464b5730..9f89ab6bf1fc7 100644 --- a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp +++ b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp @@ -297,6 +297,17 @@ INTERCEPTOR(FILE *, fdopen, int fd, const char *mode) { return REAL(fdopen)(fd, mode); } +#if SANITIZER_INTERCEPT_FOPENCOOKIE +INTERCEPTOR(FILE *, fopencookie, void *cookie, const char *mode, + cookie_io_functions_t funcs) { + __rtsan_notify_intercepted_call("fopencookie"); + return REAL(fopencookie)(cookie, mode, funcs); +} +#define RTSAN_MAYBE_INTERCEPT_FOPENCOOKIE INTERCEPT_FUNCTION(fopencookie) +#else +#define RTSAN_MAYBE_INTERCEPT_FOPENCOOKIE +#endif + #if SANITIZER_INTERCEPT_OPEN_MEMSTREAM INTERCEPTOR(FILE *, open_memstream, char **buf, size_t *size) { __rtsan_notify_intercepted_call("open_memstream"); @@ -972,6 +983,7 @@ void __rtsan::InitializeInterceptors() { INTERCEPT_FUNCTION(fputs); INTERCEPT_FUNCTION(fdopen); INTERCEPT_FUNCTION(freopen); + RTSAN_MAYBE_INTERCEPT_FOPENCOOKIE; RTSAN_MAYBE_INTERCEPT_OPEN_MEMSTREAM; RTSAN_MAYBE_INTERCEPT_FMEMOPEN; INTERCEPT_FUNCTION(lseek); 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 b052dd859dcdf..5adbf0fb63de8 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_FOPENCOOKIE +TEST_F(RtsanFileTest, FopenCookieDieWhenRealtime) { + FILE *f = fopen(GetTemporaryFilePath(), "w"); + EXPECT_THAT(f, Ne(nullptr)); + struct fholder { + FILE *fp; + size_t read; + } fh = {f, 0}; + auto CookieRead = [this](void *cookie, char *buf, size_t size) { + fholder *p = reinterpret_cast(cookie); + p->read = fread(static_cast(buf), 1, size, p->fp); + EXPECT_NE(0, p->read); + }; + cookie_io_functions_t funcs = {(cookie_read_function_t *)&CookieRead, nullptr, + nullptr, nullptr}; + auto Func = [&fh, &funcs]() { + FILE *f = fopencookie(&fh, "w", funcs); + EXPECT_THAT(f, Ne(nullptr)); + }; + + ExpectRealtimeDeath(Func, "fopencookie"); + ExpectNonRealtimeSurvival(Func); +} +#endif + #if SANITIZER_INTERCEPT_OPEN_MEMSTREAM TEST_F(RtsanFileTest, OpenMemstreamDiesWhenRealtime) { char *buffer;