-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[compiler-rt][rtsan] fseek api interception. #122163
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-compiler-rt-sanitizer Author: David CARLIER (devnexen) ChangesFull diff: https://github.com/llvm/llvm-project/pull/122163.diff 2 Files Affected:
diff --git a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp
index 6a5f4b91d11d7e..6b7a6d15f05b64 100644
--- a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp
+++ b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp
@@ -376,6 +376,58 @@ 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(fgetpos)(stream, offset, whence);
+}
+
+INTERCEPTOR(int, fseeko, FILE *stream, long offset, int whence) {
+ __rtsan_notify_intercepted_call("fseeko");
+ return REAL(fgetpos)(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);
+}
+
+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)
+#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
+#endif
+
INTERCEPTOR(int, puts, const char *s) {
__rtsan_notify_intercepted_call("puts");
return REAL(puts)(s);
@@ -1042,6 +1094,13 @@ 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;
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 5488d3c7e2056c..f27ff1f7a350f0 100644
--- a/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp
+++ b/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp
@@ -453,6 +453,68 @@ TEST_F(RtsanFileTest, SetbufferDieWhenRealtime) {
}
#endif
+#if SANITIZER_INTERCEPT_FSEEK
+TEST_F(RtsanOpenedFileTest, FgetposDieWhenRealtime) {
+ auto Func = [this]() {
+ int pos = fgetpos(GetOpenFile());
+ ASSERT_THAT(pos, Eq(0));
+ };
+
+ ExpectRealtimeDeath(Func, MAYBE_APPEND_64("fgetpos"));
+ ExpectNonRealtimeSurvival(Func);
+}
+
+TEST_F(RtsanOpenedFileTest, FseekDieWhenRealtime) {
+ auto Func = [this]() {
+ int ret = fseek(GetOpenFile(), 0, SEEK_CUR);
+ ASSERT_THAT(ret, Eq(0));
+ };
+
+ ExpectRealtimeDeath(Func, MAYBE_APPEND_64("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, MAYBE_APPEND_64("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
+
class RtsanOpenedFileTest : public RtsanFileTest {
protected:
void SetUp() override {
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
ASSERT_THAT(pos, Eq(0)); | ||
}; | ||
|
||
ExpectRealtimeDeath(Func, MAYBE_APPEND_64("fgetpos")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where are the interceptors for fseek64, fgetpos64, ...64 etc? I'm surprised these tests pass on linux
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
does not seem there is any fseek64 but fseeko64/ftello64/fgetpos64 and fsetpos64 however ...
@@ -376,6 +376,95 @@ INTERCEPTOR(void, setbuffer, FILE *stream, char *buf, int size) { | |||
#define RTSAN_MAYBE_INTERCEPT_SETBUFFER | |||
#endif | |||
|
|||
#if SANITIZER_INTERCEPT_FSEEK |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is more of a question - I don't have the answer. Should all of these be inside this ifdef? Should some of them be outside of it?
For instance, on my mac, I have access to many of these:
FSEEK(3) Library Functions Manual FSEEK(3)
NAME
fgetpos, fseek, fseeko, fsetpos, ftell, ftello, rewind – reposition a
stream
And it seems like these only have support for BSD flavors:
#define SANITIZER_INTERCEPT_FSEEK (SI_NETBSD || SI_FREEBSD)
Even normally flavored linux has many of these https://www.man7.org/linux/man-pages/man3/fseek.3.html
Maybe this macro needs updating?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh yes weird, I m pretty sure even fuchsia has it too, but setting as SI_POSIX should do at first.
1b0187a
to
8ba332c
Compare
@@ -593,7 +593,7 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment, | |||
#define SANITIZER_INTERCEPT_SHA1 SI_NETBSD | |||
#define SANITIZER_INTERCEPT_MD4 SI_NETBSD | |||
#define SANITIZER_INTERCEPT_RMD160 SI_NETBSD | |||
#define SANITIZER_INTERCEPT_FSEEK (SI_NETBSD || SI_FREEBSD) | |||
#define SANITIZER_INTERCEPT_FSEEK SI_POSIX |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@fmayer wanted to get your eyes on this change in particular, as it may have ramifications for other sanitizers.
Maybe we should do this change first as a separate PR to see if there is any test fallout, then commit the rest?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems fseek
is POSIX since 2001
HISTORY top
POSIX.1-2001, C89.
https://man7.org/linux/man-pages/man3/fseek.3.html
But splitting this off SGTM.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes. to be fair the folk who implemented the interception was a pure BSD guy though. Ok will split soon-ish.
fseek api is POSIX. to also address llvm#122163
fseek api is POSIX. to also address #122163
@@ -593,7 +593,7 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment, | |||
#define SANITIZER_INTERCEPT_SHA1 SI_NETBSD | |||
#define SANITIZER_INTERCEPT_MD4 SI_NETBSD | |||
#define SANITIZER_INTERCEPT_RMD160 SI_NETBSD | |||
#define SANITIZER_INTERCEPT_FSEEK SI_POSIX | |||
#define SANITIZER_INTERCEPT_FSEEK (SI_NETBSD || SI_FREEBSD) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line appears to undo the change from https://github.com/llvm/llvm-project/pull/122795/files - is this deliberate?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah no, good catch !
random driveby: the rtsan_interceptors_posix file doesn't seem to use the preprocessor macro indentation for |
If I get what you mean, I tried that earlier but the clang-format did not like it very much. |
} | ||
|
||
TEST_F(RtsanOpenedFileTest, RewindDieWhenRealtime) { | ||
int end = fseek(GetOpenFile(), 0, SEEK_END); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@devnexen this is causing unused variable warning, which ends up an error in the sanitizer bot. Could you please fix that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure, doing it now.
No description provided.