Skip to content

Commit eb69bc9

Browse files
committed
[compiler-rt][rtsan] process_vm_readv/process_vm_writev interception.
1 parent c912e98 commit eb69bc9

File tree

2 files changed

+50
-1
lines changed

2 files changed

+50
-1
lines changed

compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -933,7 +933,7 @@ INTERCEPTOR(int, recvmmsg, int socket, struct mmsghdr *message,
933933
#else
934934
INTERCEPTOR(int, recvmmsg, int socket, struct mmsghdr *message,
935935
unsigned int len, int flags, struct timespec *timeout) {
936-
#endif
936+
#endif // defined(__GLIBC_MINOR) && __GLIBC_MINOR__ < 21
937937
__rtsan_notify_intercepted_call("recvmmsg");
938938
return REAL(recvmmsg)(socket, message, len, flags, timeout);
939939
}
@@ -1098,6 +1098,30 @@ INTERCEPTOR(int, execve, const char *filename, char *const argv[],
10981098
return REAL(execve)(filename, argv, envp);
10991099
}
11001100

1101+
#if SANITIZER_INTERCEPT_PROCESS_VM_READV
1102+
INTERCEPTOR(ssize_t, process_vm_readv, const struct iovec *local_iov,
1103+
unsigned long liovcnt, const struct iovec *remote_iov,
1104+
unsigned long riovcnt, unsigned long flags) {
1105+
__rtsan_notify_intercepted_call("process_vm_readv");
1106+
return REAL(process_vm_readv)(local_iov, liovcnt, remote_iov, riovcnt, flags);
1107+
}
1108+
1109+
INTERCEPTOR(ssize_t, process_vm_writev, const struct iovec *local_iov,
1110+
unsigned long liovcnt, const struct iovec *remote_iov,
1111+
unsigned long riovcnt, unsigned long flags) {
1112+
__rtsan_notify_intercepted_call("process_vm_writev");
1113+
return REAL(process_vm_writev)(local_iov, liovcnt, remote_iov, riovcnt,
1114+
flags);
1115+
}
1116+
#define RTSAN_MAYBE_INTERCEPT_PROCESS_VM_READV \
1117+
INTERCEPT_FUNCTION(process_vm_readv)
1118+
#define RTSAN_MAYBE_INTERCEPT_PROCESS_VM_WRITEV \
1119+
INTERCEPT_FUNCTION(process_vm_writev)
1120+
#else
1121+
#define RTSAN_MAYBE_INTERCEPT_PROCESS_VM_READV
1122+
#define RTSAN_MAYBE_INTERCEPT_PROCESS_VM_WRITEV
1123+
#endif
1124+
11011125
// TODO: the `wait` family of functions is an oddity. In testing, if you
11021126
// intercept them, Darwin seemingly ignores them, and linux never returns from
11031127
// the test. Revisit this in the future, but hopefully intercepting fork/exec is
@@ -1277,6 +1301,9 @@ void __rtsan::InitializeInterceptors() {
12771301
INTERCEPT_FUNCTION(fork);
12781302
INTERCEPT_FUNCTION(execve);
12791303

1304+
RTSAN_MAYBE_INTERCEPT_PROCESS_VM_READV;
1305+
RTSAN_MAYBE_INTERCEPT_PROCESS_VM_WRITEV;
1306+
12801307
INTERCEPT_FUNCTION(syscall);
12811308
}
12821309

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,28 @@ TEST(TestRtsanInterceptors, UmaskDiesWhenRealtime) {
657657
ExpectNonRealtimeSurvival(Func);
658658
}
659659

660+
#if SANITIZER_INTERCEPT_PROCESS_VM_READV
661+
TEST(TestRtsanInterceptors, ProcessVmReadvDiesWhenRealtime) {
662+
char stack[1024];
663+
int p;
664+
iovec lcl{&stack, sizeof(stack)};
665+
iovec rmt{&p, sizeof(p)};
666+
auto Func = [&lcl, &rmt]() { process_vm_readv(0, &lcl, 1, &rmt, 1, 0); };
667+
ExpectRealtimeDeath(Func, "process_vm_readv");
668+
ExpectNonRealtimeSurvival(Func);
669+
}
670+
671+
TEST(TestRtsanInterceptors, ProcessVmWritevDiesWhenRealtime) {
672+
char stack[1024];
673+
int p;
674+
iovec lcl{&p, sizeof(p)};
675+
iovec rmt{&stack, sizeof(stack)};
676+
auto Func = [&lcl, &rmt]() { process_vm_writev(0, &lcl, 1, &rmt, 1, 0); };
677+
ExpectRealtimeDeath(Func, "process_vm_writev");
678+
ExpectNonRealtimeSurvival(Func);
679+
}
680+
#endif
681+
660682
class RtsanDirectoryTest : public ::testing::Test {
661683
protected:
662684
void SetUp() override {

0 commit comments

Comments
 (0)