Skip to content

Commit 33e23ca

Browse files
committed
[compiler-rt][rtsan] fdopen/freopen(64) support.
1 parent aebd338 commit 33e23ca

File tree

2 files changed

+43
-2
lines changed

2 files changed

+43
-2
lines changed

compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,14 +244,28 @@ 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, FILE *stream) {
261+
__rtsan_notify_intercepted_call("freopen64");
262+
return REAL(freopen64)(path, mode, stream);
263+
}
264+
#define RTSAN_MAYBE_INTERCEPT_FOPEN64 INTERCEPT_FUNCTION(fopen64);
265+
#define RTSAN_MAYBE_INTERCEPT_FREOPEN64 INTERCEPT_FUNCTION(freopen64);
253266
#else
254267
#define RTSAN_MAYBE_INTERCEPT_FOPEN64
268+
#define RTSAN_MAYBE_INTERCEPT_FREOPEN64
255269
#endif // SANITIZER_INTERCEPT_FOPEN64
256270

257271
INTERCEPTOR(size_t, fread, void *ptr, size_t size, size_t nitems,
@@ -276,7 +290,11 @@ INTERCEPTOR(int, fputs, const char *s, FILE *stream) {
276290
return REAL(fputs)(s, stream);
277291
}
278292

279-
// Streams
293+
INTERCEPTOR(FILE *, fdopen, int fd, const char *mode) {
294+
__rtsan_notify_intercepted_call("fdopen");
295+
return REAL(fdopen)(fd, mode);
296+
}
297+
280298
INTERCEPTOR(int, puts, const char *s) {
281299
__rtsan_notify_intercepted_call("puts");
282300
return REAL(puts)(s);
@@ -904,6 +922,7 @@ void __rtsan::InitializeInterceptors() {
904922
INTERCEPT_FUNCTION(close);
905923
INTERCEPT_FUNCTION(fopen);
906924
RTSAN_MAYBE_INTERCEPT_FOPEN64;
925+
RTSAN_MAYBE_INTERCEPT_FREOPEN64;
907926
INTERCEPT_FUNCTION(fread);
908927
INTERCEPT_FUNCTION(read);
909928
INTERCEPT_FUNCTION(write);
@@ -921,6 +940,8 @@ void __rtsan::InitializeInterceptors() {
921940
RTSAN_MAYBE_INTERCEPT_CREAT64;
922941
INTERCEPT_FUNCTION(puts);
923942
INTERCEPT_FUNCTION(fputs);
943+
INTERCEPT_FUNCTION(fdopen);
944+
INTERCEPT_FUNCTION(freopen);
924945
INTERCEPT_FUNCTION(lseek);
925946
RTSAN_MAYBE_INTERCEPT_LSEEK64;
926947
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)