Skip to content

Commit 26448d0

Browse files
committed
[compiler-rt][rtsan] adding Linux's clone call interception.
1 parent 3026fa0 commit 26448d0

File tree

2 files changed

+55
-0
lines changed

2 files changed

+55
-0
lines changed

compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1411,6 +1411,31 @@ INTERCEPTOR(int, execve, const char *filename, char *const argv[],
14111411
return REAL(execve)(filename, argv, envp);
14121412
}
14131413

1414+
#if SANITIZER_GLIBC
1415+
INTERCEPTOR(int, clone, int (*f)(void *), void *stack, int flags, void *arg,
1416+
...) {
1417+
__rtsan_notify_intercepted_call("clone");
1418+
1419+
if ((flags & CLONE_PIDFD) || (flags & CLONE_SETTLS) ||
1420+
(flags & CLONE_PARENT_SETTID) || (flags & CLONE_CHILD_SETTID) ||
1421+
(flags & CLONE_CHILD_CLEARTID)) {
1422+
va_list args;
1423+
va_start(args, arg);
1424+
pid_t *parent = va_arg(args, pid_t *);
1425+
void *tls = va_arg(args, void *);
1426+
pid_t *child = va_arg(args, pid_t *);
1427+
va_end(args);
1428+
1429+
return REAL(clone)(f, stack, flags, arg, parent, tls, child);
1430+
}
1431+
1432+
return REAL(clone)(f, stack, flags, arg);
1433+
}
1434+
#define RTSAN_MAYBE_INTERCEPT_CLONE INTERCEPT_FUNCTION(clone)
1435+
#else
1436+
#define RTSAN_MAYBE_INTERCEPT_CLONE
1437+
#endif
1438+
14141439
#if SANITIZER_INTERCEPT_PROCESS_VM_READV
14151440
INTERCEPTOR(ssize_t, process_vm_readv, pid_t pid, const struct iovec *local_iov,
14161441
unsigned long liovcnt, const struct iovec *remote_iov,
@@ -1650,6 +1675,7 @@ void __rtsan::InitializeInterceptors() {
16501675

16511676
INTERCEPT_FUNCTION(fork);
16521677
INTERCEPT_FUNCTION(execve);
1678+
RTSAN_MAYBE_INTERCEPT_CLONE;
16531679

16541680
RTSAN_MAYBE_INTERCEPT_PROCESS_VM_READV;
16551681
RTSAN_MAYBE_INTERCEPT_PROCESS_VM_WRITEV;

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1273,6 +1273,35 @@ TEST_F(PthreadRwlockTest, PthreadRwlockWrlockSurvivesWhenNonRealtime) {
12731273
ExpectNonRealtimeSurvival(Func);
12741274
}
12751275

1276+
#if SANITIZER_GLIBC
1277+
TEST(TestRtsanInterceptors, CloneDiesWhenRealtime) {
1278+
std::vector<char> buf;
1279+
buf.resize(1024 * 1024);
1280+
auto Call = [](void *a) { return 0; };
1281+
auto Func = [&buf, &Call]() {
1282+
clone(Call, buf.data() + buf.size(), 0, nullptr);
1283+
};
1284+
1285+
ExpectRealtimeDeath(Func, "clone");
1286+
ExpectNonRealtimeSurvival(Func);
1287+
}
1288+
1289+
TEST(TestRtsanInterceptors, CloneWithTldDiesWhenRealtime) {
1290+
std::vector<char> buf;
1291+
pid_t pidfd;
1292+
void *tls = ::operator new(4096, std::align_val_t(16));
1293+
buf.resize(1024 * 1024);
1294+
auto Call = [](void *a) { return 0; };
1295+
auto Func = [&buf, &Call, &pidfd, &tls]() {
1296+
clone(Call, buf.data() + buf.size(), CLONE_PIDFD | CLONE_SETTLS, &pidfd,
1297+
tls, nullptr);
1298+
};
1299+
1300+
ExpectRealtimeDeath(Func, "clone");
1301+
ExpectNonRealtimeSurvival(Func);
1302+
}
1303+
#endif
1304+
12761305
/*
12771306
Sockets
12781307
*/

0 commit comments

Comments
 (0)