From c4443a1be4e4e68fff894ba659bc157bf30c8d26 Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Wed, 15 Jan 2025 18:31:27 +0000 Subject: [PATCH] [compiler-rt][rtsan] fseek api interception. (#122163) --- .../lib/rtsan/rtsan_interceptors_posix.cpp | 100 ++++++++++++++++++ .../tests/rtsan_test_interceptors_posix.cpp | 74 +++++++++++++ 2 files changed, 174 insertions(+) diff --git a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp index 6a5f4b91d11d..e3f3d12d7e52 100644 --- a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp +++ b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp @@ -376,6 +376,95 @@ INTERCEPTOR(void, setbuffer, FILE *stream, char *buf, int size) { #define RTSAN_MAYBE_INTERCEPT_SETBUFFER #endif +#if SANITIZER_INTERCEPT_FSEEK +INTERCEPTOR(int, fgetpos, FILE *stream, fpos_t *pos) { + __rtsan_notify_intercepted_call("fgetpos"); + return REAL(fgetpos)(stream, pos); +} + +INTERCEPTOR(int, fseek, FILE *stream, long offset, int whence) { + __rtsan_notify_intercepted_call("fseek"); + return REAL(fseek)(stream, offset, whence); +} + +INTERCEPTOR(int, fseeko, FILE *stream, off_t offset, int whence) { + __rtsan_notify_intercepted_call("fseeko"); + return REAL(fseeko)(stream, offset, whence); +} + +INTERCEPTOR(int, fsetpos, FILE *stream, const fpos_t *pos) { + __rtsan_notify_intercepted_call("fsetpos"); + return REAL(fsetpos)(stream, pos); +} + +INTERCEPTOR(long, ftell, FILE *stream) { + __rtsan_notify_intercepted_call("ftell"); + return REAL(ftell)(stream); +} + +INTERCEPTOR(off_t, ftello, FILE *stream) { + __rtsan_notify_intercepted_call("ftello"); + return REAL(ftello)(stream); +} + +#if SANITIZER_LINUX && !SANITIZER_MUSL +INTERCEPTOR(int, fgetpos64, FILE *stream, fpos64_t *pos) { + __rtsan_notify_intercepted_call("fgetpos64"); + return REAL(fgetpos64)(stream, pos); +} + +INTERCEPTOR(int, fseeko64, FILE *stream, off64_t offset, int whence) { + __rtsan_notify_intercepted_call("fseeko64"); + return REAL(fseeko64)(stream, offset, whence); +} + +INTERCEPTOR(int, fsetpos64, FILE *stream, const fpos64_t *pos) { + __rtsan_notify_intercepted_call("fsetpos64"); + return REAL(fsetpos64)(stream, pos); +} + +INTERCEPTOR(off64_t, ftello64, FILE *stream) { + __rtsan_notify_intercepted_call("ftello64"); + return REAL(ftello64)(stream); +} +#endif + +INTERCEPTOR(void, rewind, FILE *stream) { + __rtsan_notify_intercepted_call("rewind"); + return REAL(rewind)(stream); +} +#define RTSAN_MAYBE_INTERCEPT_FGETPOS INTERCEPT_FUNCTION(fgetpos) +#define RTSAN_MAYBE_INTERCEPT_FSEEK INTERCEPT_FUNCTION(fseek) +#define RTSAN_MAYBE_INTERCEPT_FSEEKO INTERCEPT_FUNCTION(fseeko) +#define RTSAN_MAYBE_INTERCEPT_FSETPOS INTERCEPT_FUNCTION(fsetpos) +#define RTSAN_MAYBE_INTERCEPT_FTELL INTERCEPT_FUNCTION(ftell) +#define RTSAN_MAYBE_INTERCEPT_FTELLO INTERCEPT_FUNCTION(ftello) +#define RTSAN_MAYBE_INTERCEPT_REWIND INTERCEPT_FUNCTION(rewind) +#if SANITIZER_LINUX && !SANITIZER_MUSL +#define RTSAN_MAYBE_INTERCEPT_FGETPOS64 INTERCEPT_FUNCTION(fgetpos64) +#define RTSAN_MAYBE_INTERCEPT_FSEEKO64 INTERCEPT_FUNCTION(fseeko64) +#define RTSAN_MAYBE_INTERCEPT_FSETPOS64 INTERCEPT_FUNCTION(fsetpos64) +#define RTSAN_MAYBE_INTERCEPT_FTELLO64 INTERCEPT_FUNCTION(ftello64) +#else +#define RTSAN_MAYBE_INTERCEPT_FGETPOS64 +#define RTSAN_MAYBE_INTERCEPT_FSEEKO64 +#define RTSAN_MAYBE_INTERCEPT_FSETPOS64 +#define RTSAN_MAYBE_INTERCEPT_FTELLO64 +#endif +#else +#define RTSAN_MAYBE_INTERCEPT_FGETPOS +#define RTSAN_MAYBE_INTERCEPT_FSEEK +#define RTSAN_MAYBE_INTERCEPT_FSEEKO +#define RTSAN_MAYBE_INTERCEPT_FSETPOS +#define RTSAN_MAYBE_INTERCEPT_FTELL +#define RTSAN_MAYBE_INTERCEPT_FTELLO +#define RTSAN_MAYBE_INTERCEPT_REWIND +#define RTSAN_MAYBE_INTERCEPT_FGETPOS64 +#define RTSAN_MAYBE_INTERCEPT_FSEEKO64 +#define RTSAN_MAYBE_INTERCEPT_FSETPOS64 +#define RTSAN_MAYBE_INTERCEPT_FTELLO64 +#endif + INTERCEPTOR(int, puts, const char *s) { __rtsan_notify_intercepted_call("puts"); return REAL(puts)(s); @@ -1042,6 +1131,17 @@ void __rtsan::InitializeInterceptors() { RTSAN_MAYBE_INTERCEPT_SETVBUF; RTSAN_MAYBE_INTERCEPT_SETLINEBUF; RTSAN_MAYBE_INTERCEPT_SETBUFFER; + RTSAN_MAYBE_INTERCEPT_FGETPOS; + RTSAN_MAYBE_INTERCEPT_FSEEK; + RTSAN_MAYBE_INTERCEPT_FSEEKO; + RTSAN_MAYBE_INTERCEPT_FSETPOS; + RTSAN_MAYBE_INTERCEPT_FTELL; + RTSAN_MAYBE_INTERCEPT_FTELLO; + RTSAN_MAYBE_INTERCEPT_REWIND; + RTSAN_MAYBE_INTERCEPT_FGETPOS64; + RTSAN_MAYBE_INTERCEPT_FSEEKO64; + RTSAN_MAYBE_INTERCEPT_FSETPOS64; + RTSAN_MAYBE_INTERCEPT_FTELLO64; 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 5488d3c7e205..e72b810dd8c3 100644 --- a/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp +++ b/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp @@ -478,6 +478,80 @@ private: int fd = -1; }; +#if SANITIZER_INTERCEPT_FSEEK +TEST_F(RtsanOpenedFileTest, FgetposDieWhenRealtime) { + auto Func = [this]() { + fpos_t pos; + int ret = fgetpos(GetOpenFile(), &pos); + ASSERT_THAT(ret, Eq(0)); + }; + + ExpectRealtimeDeath(Func, MAYBE_APPEND_64("fgetpos")); + ExpectNonRealtimeSurvival(Func); +} + +TEST_F(RtsanOpenedFileTest, FsetposDieWhenRealtime) { + fpos_t pos; + int ret = fgetpos(GetOpenFile(), &pos); + ASSERT_THAT(ret, Eq(0)); + auto Func = [this, pos]() { + int ret = fsetpos(GetOpenFile(), &pos); + ASSERT_THAT(ret, Eq(0)); + }; + + ExpectRealtimeDeath(Func, MAYBE_APPEND_64("fsetpos")); + ExpectNonRealtimeSurvival(Func); +} + +TEST_F(RtsanOpenedFileTest, FseekDieWhenRealtime) { + auto Func = [this]() { + int ret = fseek(GetOpenFile(), 0, SEEK_CUR); + ASSERT_THAT(ret, Eq(0)); + }; + + ExpectRealtimeDeath(Func, "fseek"); + ExpectNonRealtimeSurvival(Func); +} + +TEST_F(RtsanOpenedFileTest, FseekoDieWhenRealtime) { + auto Func = [this]() { + int ret = fseeko(GetOpenFile(), 0, SEEK_CUR); + ASSERT_THAT(ret, Eq(0)); + }; + + ExpectRealtimeDeath(Func, MAYBE_APPEND_64("fseeko")); + ExpectNonRealtimeSurvival(Func); +} + +TEST_F(RtsanOpenedFileTest, FtellDieWhenRealtime) { + auto Func = [this]() { + long ret = ftell(GetOpenFile()); + ASSERT_THAT(ret, Eq(0)); + }; + + ExpectRealtimeDeath(Func, "ftell"); + ExpectNonRealtimeSurvival(Func); +} + +TEST_F(RtsanOpenedFileTest, FtelloDieWhenRealtime) { + auto Func = [this]() { + off_t ret = ftello(GetOpenFile()); + ASSERT_THAT(ret, Eq(0)); + }; + + ExpectRealtimeDeath(Func, MAYBE_APPEND_64("ftello")); + ExpectNonRealtimeSurvival(Func); +} + +TEST_F(RtsanOpenedFileTest, RewindDieWhenRealtime) { + int end = fseek(GetOpenFile(), 0, SEEK_END); + auto Func = [this]() { rewind(GetOpenFile()); }; + + ExpectRealtimeDeath(Func, "rewind"); + ExpectNonRealtimeSurvival(Func); +} +#endif + TEST(TestRtsanInterceptors, IoctlDiesWhenRealtime) { auto Func = []() { ioctl(0, FIONREAD); }; ExpectRealtimeDeath(Func, "ioctl");