Skip to content

Commit 2ab687e

Browse files
authored
[compiler-rt][rtsan] fdopen/freopen(64) support. (#119100)
1 parent b1d4246 commit 2ab687e

File tree

2 files changed

+44
-2
lines changed

2 files changed

+44
-2
lines changed

compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,14 +244,29 @@ INTERCEPTOR(FILE *, fopen, const char *path, const char *mode) {
244244
return REAL(fopen)(path, mode);
245245
}
246246

247+
INTERCEPTOR(FILE *, freopen, const char *path, const char *mode, FILE *stream) {
248+
__rtsan_notify_intercepted_call("freopen");
249+
return REAL(freopen)(path, mode, stream);
250+
}
251+
252+
// Streams
253+
247254
#if SANITIZER_INTERCEPT_FOPEN64
248255
INTERCEPTOR(FILE *, fopen64, const char *path, const char *mode) {
249256
__rtsan_notify_intercepted_call("fopen64");
250257
return REAL(fopen64)(path, mode);
251258
}
252-
#define RTSAN_MAYBE_INTERCEPT_FOPEN64 INTERCEPT_FUNCTION(fopen64)
259+
260+
INTERCEPTOR(FILE *, freopen64, const char *path, const char *mode,
261+
FILE *stream) {
262+
__rtsan_notify_intercepted_call("freopen64");
263+
return REAL(freopen64)(path, mode, stream);
264+
}
265+
#define RTSAN_MAYBE_INTERCEPT_FOPEN64 INTERCEPT_FUNCTION(fopen64);
266+
#define RTSAN_MAYBE_INTERCEPT_FREOPEN64 INTERCEPT_FUNCTION(freopen64);
253267
#else
254268
#define RTSAN_MAYBE_INTERCEPT_FOPEN64
269+
#define RTSAN_MAYBE_INTERCEPT_FREOPEN64
255270
#endif // SANITIZER_INTERCEPT_FOPEN64
256271

257272
INTERCEPTOR(size_t, fread, void *ptr, size_t size, size_t nitems,
@@ -276,7 +291,11 @@ INTERCEPTOR(int, fputs, const char *s, FILE *stream) {
276291
return REAL(fputs)(s, stream);
277292
}
278293

279-
// Streams
294+
INTERCEPTOR(FILE *, fdopen, int fd, const char *mode) {
295+
__rtsan_notify_intercepted_call("fdopen");
296+
return REAL(fdopen)(fd, mode);
297+
}
298+
280299
INTERCEPTOR(int, puts, const char *s) {
281300
__rtsan_notify_intercepted_call("puts");
282301
return REAL(puts)(s);
@@ -904,6 +923,7 @@ void __rtsan::InitializeInterceptors() {
904923
INTERCEPT_FUNCTION(close);
905924
INTERCEPT_FUNCTION(fopen);
906925
RTSAN_MAYBE_INTERCEPT_FOPEN64;
926+
RTSAN_MAYBE_INTERCEPT_FREOPEN64;
907927
INTERCEPT_FUNCTION(fread);
908928
INTERCEPT_FUNCTION(read);
909929
INTERCEPT_FUNCTION(write);
@@ -921,6 +941,8 @@ void __rtsan::InitializeInterceptors() {
921941
RTSAN_MAYBE_INTERCEPT_CREAT64;
922942
INTERCEPT_FUNCTION(puts);
923943
INTERCEPT_FUNCTION(fputs);
944+
INTERCEPT_FUNCTION(fdopen);
945+
INTERCEPT_FUNCTION(freopen);
924946
INTERCEPT_FUNCTION(lseek);
925947
RTSAN_MAYBE_INTERCEPT_LSEEK64;
926948
INTERCEPT_FUNCTION(dup);

compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,26 @@ TEST_F(RtsanOpenedFileTest, IoctlBehavesWithOutputArg) {
391391
EXPECT_THAT(arg, Ge(0));
392392
}
393393

394+
TEST_F(RtsanOpenedFileTest, FdopenDiesWhenRealtime) {
395+
auto Func = [&]() {
396+
FILE *f = fdopen(GetOpenFd(), "w");
397+
EXPECT_THAT(f, Ne(nullptr));
398+
};
399+
400+
ExpectRealtimeDeath(Func, "fdopen");
401+
ExpectNonRealtimeSurvival(Func);
402+
}
403+
404+
TEST_F(RtsanOpenedFileTest, FreopenDiesWhenRealtime) {
405+
auto Func = [&]() {
406+
FILE *newfile = freopen(GetTemporaryFilePath(), "w", GetOpenFile());
407+
EXPECT_THAT(newfile, Ne(nullptr));
408+
};
409+
410+
ExpectRealtimeDeath(Func, MAYBE_APPEND_64("freopen"));
411+
ExpectNonRealtimeSurvival(Func);
412+
}
413+
394414
TEST(TestRtsanInterceptors, IoctlBehavesWithOutputPointer) {
395415
// These initial checks just see if we CAN run these tests.
396416
// If we can't (can't open a socket, or can't find an interface, just

0 commit comments

Comments
 (0)