diff --git a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp index 83e6cdd4a0094..410da0748b433 100644 --- a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp +++ b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp @@ -254,6 +254,27 @@ INTERCEPTOR(int, fchdir, int fd) { return REAL(fchdir)(fd); } +#if SANITIZER_INTERCEPT_READLINK +INTERCEPTOR(ssize_t, readlink, const char *pathname, char *buf, size_t size) { + __rtsan_notify_intercepted_call("readlink"); + return REAL(readlink)(pathname, buf, size); +} +#define RTSAN_MAYBE_INTERCEPT_READLINK INTERCEPT_FUNCTION(readlink) +#else +#define RTSAN_MAYBE_INTERCEPT_READLINK +#endif + +#if SANITIZER_INTERCEPT_READLINKAT +INTERCEPTOR(ssize_t, readlinkat, int dirfd, const char *pathname, char *buf, + size_t size) { + __rtsan_notify_intercepted_call("readlinkat"); + return REAL(readlinkat)(dirfd, pathname, buf, size); +} +#define RTSAN_MAYBE_INTERCEPT_READLINKAT INTERCEPT_FUNCTION(readlinkat) +#else +#define RTSAN_MAYBE_INTERCEPT_READLINKAT +#endif + // Streams INTERCEPTOR(FILE *, fopen, const char *path, const char *mode) { @@ -1402,6 +1423,8 @@ void __rtsan::InitializeInterceptors() { INTERCEPT_FUNCTION(close); INTERCEPT_FUNCTION(chdir); INTERCEPT_FUNCTION(fchdir); + RTSAN_MAYBE_INTERCEPT_READLINK; + RTSAN_MAYBE_INTERCEPT_READLINKAT; 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 075f5974b7562..98d27caae94b8 100644 --- a/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp +++ b/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp @@ -457,6 +457,24 @@ TEST(TestRtsanInterceptors, FchdirDiesWhenRealtime) { ExpectNonRealtimeSurvival(Func); } +#if SANITIZER_INTERCEPT_READLINK +TEST(TestRtsanInterceptors, ReadlinkDiesWhenRealtime) { + char buf[1024]; + auto Func = [&buf]() { readlink("/proc/self", buf, sizeof(buf)); }; + ExpectRealtimeDeath(Func, "readlink"); + ExpectNonRealtimeSurvival(Func); +} +#endif + +#if SANITIZER_INTERCEPT_READLINKAT +TEST(TestRtsanInterceptors, ReadlinkatDiesWhenRealtime) { + char buf[1024]; + auto Func = [&buf]() { readlinkat(0, "/proc/self", buf, sizeof(buf)); }; + ExpectRealtimeDeath(Func, "readlinkat"); + ExpectNonRealtimeSurvival(Func); +} +#endif + TEST_F(RtsanFileTest, FopenDiesWhenRealtime) { auto Func = [this]() { FILE *f = fopen(GetTemporaryFilePath(), "w");