Skip to content

Commit 2f84934

Browse files
committed
Fix issue where fcntl was not using last arg correctly (#24)
* Fix issue where fcntl was not using last arg correctly * Comment update
1 parent d30cc80 commit 2f84934

File tree

2 files changed

+34
-2
lines changed

2 files changed

+34
-2
lines changed

compiler-rt/lib/radsan/radsan_interceptors.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,20 @@ INTERCEPTOR(int, fcntl, int filedes, int cmd, ...) {
8989

9090
va_list args;
9191
va_start(args, cmd);
92-
void *arg = va_arg(args, void *);
92+
93+
// Following precedent here. The linux source (fcntl.c, do_fcntl) accepts the
94+
// final argument in a variable that will hold the largest of the possible
95+
// argument types (pointers and ints are typical in fcntl) It is then assumed
96+
// that the implementation of fcntl will cast it properly depending on cmd.
97+
//
98+
// This is also similar to what is done in
99+
// sanitizer_common/sanitizer_common_syscalls.inc
100+
const unsigned long arg = va_arg(args, unsigned long);
101+
int result = REAL(fcntl)(filedes, cmd, arg);
102+
93103
va_end(args);
94104

95-
return fcntl(filedes, cmd, arg);
105+
return result;
96106
}
97107

98108
INTERCEPTOR(int, close, int filedes) {

compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,28 @@ TEST(TestRadsanInterceptors, CloseDiesWhenRealtime) {
261261
expectNonrealtimeSurvival(Func);
262262
}
263263

264+
TEST(TestRadsanInterceptors, fcntlSetFdDiesWhenRealtime) {
265+
int fd = creat(TemporaryFilePath(), S_IRUSR | S_IWUSR);
266+
ASSERT_THAT(fd, Ne(-1));
267+
268+
auto func = [fd]() {
269+
int old_flags = fcntl(fd, F_GETFD);
270+
ASSERT_THAT(fcntl(fd, F_SETFD, FD_CLOEXEC), Eq(0));
271+
272+
int flags = fcntl(fd, F_GETFD);
273+
ASSERT_THAT(flags, Ne(-1));
274+
ASSERT_THAT(flags & FD_CLOEXEC, Eq(FD_CLOEXEC));
275+
276+
ASSERT_THAT(fcntl(fd, F_SETFD, old_flags), Eq(0));
277+
ASSERT_THAT(fcntl(fd, F_GETFD), Eq(old_flags));
278+
};
279+
280+
ExpectRealtimeDeath(func, "fcntl");
281+
ExpectNonRealtimeSurvival(func);
282+
283+
close(fd);
284+
}
285+
264286
TEST(TestRadsanInterceptors, FopenDiesWhenRealtime) {
265287
auto Func = []() {
266288
FILE *fd = fopen(TemporaryFilePath(), "w");

0 commit comments

Comments
 (0)