Skip to content

Commit 3934b3e

Browse files
authored
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 fcd2752 commit 3934b3e

File tree

2 files changed

+36
-4
lines changed

2 files changed

+36
-4
lines changed

compiler-rt/lib/radsan/radsan_interceptors.cpp

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

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

94-
return fcntl(filedes, cmd, arg);
104+
return result;
95105
}
96106

97107
INTERCEPTOR(int, close, int filedes) {

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

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,11 +213,11 @@ TEST(TestRadsanInterceptors, fcntlFlockDiesWhenRealtime) {
213213
ASSERT_THAT(fd, Ne(-1));
214214

215215
auto func = [fd]() {
216-
struct flock lock{};
216+
struct flock lock {};
217217
lock.l_type = F_RDLCK;
218218
lock.l_whence = SEEK_SET;
219219
lock.l_start = 0;
220-
lock.l_len = 0;
220+
lock.l_len = 0;
221221
lock.l_pid = ::getpid();
222222

223223
ASSERT_THAT(fcntl(fd, F_GETLK, &lock), Eq(0));
@@ -230,6 +230,28 @@ TEST(TestRadsanInterceptors, fcntlFlockDiesWhenRealtime) {
230230
std::remove(temporary_file_path());
231231
}
232232

233+
TEST(TestRadsanInterceptors, fcntlSetFdDiesWhenRealtime) {
234+
int fd = creat(temporary_file_path(), S_IRUSR | S_IWUSR);
235+
ASSERT_THAT(fd, Ne(-1));
236+
237+
auto func = [fd]() {
238+
int old_flags = fcntl(fd, F_GETFD);
239+
ASSERT_THAT(fcntl(fd, F_SETFD, FD_CLOEXEC), Eq(0));
240+
241+
int flags = fcntl(fd, F_GETFD);
242+
ASSERT_THAT(flags, Ne(-1));
243+
ASSERT_THAT(flags & FD_CLOEXEC, Eq(FD_CLOEXEC));
244+
245+
ASSERT_THAT(fcntl(fd, F_SETFD, old_flags), Eq(0));
246+
ASSERT_THAT(fcntl(fd, F_GETFD), Eq(old_flags));
247+
};
248+
249+
expectRealtimeDeath(func, "fcntl");
250+
expectNonrealtimeSurvival(func);
251+
252+
close(fd);
253+
}
254+
233255
TEST(TestRadsanInterceptors, closeDiesWhenRealtime) {
234256
auto func = []() { close(0); };
235257
expectRealtimeDeath(func, "close");

0 commit comments

Comments
 (0)