[compiler-rt] [compiler-rt][rtsan] adding Linux's clone call interception. (PR #130423)

David CARLIER via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 28 14:41:16 PDT 2025


https://github.com/devnexen updated https://github.com/llvm/llvm-project/pull/130423

>From 26448d09097ca6ab3ace29ec475f471564565dd4 Mon Sep 17 00:00:00 2001
From: David Carlier <devnexen at gmail.com>
Date: Sat, 8 Mar 2025 15:57:40 +0000
Subject: [PATCH] [compiler-rt][rtsan] adding Linux's clone call interception.

---
 .../lib/rtsan/rtsan_interceptors_posix.cpp    | 26 +++++++++++++++++
 .../tests/rtsan_test_interceptors_posix.cpp   | 29 +++++++++++++++++++
 2 files changed, 55 insertions(+)

diff --git a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp
index 9d1a689a5a070..53d7d1b87ba7a 100644
--- a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp
+++ b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp
@@ -1411,6 +1411,31 @@ INTERCEPTOR(int, execve, const char *filename, char *const argv[],
   return REAL(execve)(filename, argv, envp);
 }
 
+#if SANITIZER_GLIBC
+INTERCEPTOR(int, clone, int (*f)(void *), void *stack, int flags, void *arg,
+            ...) {
+  __rtsan_notify_intercepted_call("clone");
+
+  if ((flags & CLONE_PIDFD) || (flags & CLONE_SETTLS) ||
+      (flags & CLONE_PARENT_SETTID) || (flags & CLONE_CHILD_SETTID) ||
+      (flags & CLONE_CHILD_CLEARTID)) {
+    va_list args;
+    va_start(args, arg);
+    pid_t *parent = va_arg(args, pid_t *);
+    void *tls = va_arg(args, void *);
+    pid_t *child = va_arg(args, pid_t *);
+    va_end(args);
+
+    return REAL(clone)(f, stack, flags, arg, parent, tls, child);
+  }
+
+  return REAL(clone)(f, stack, flags, arg);
+}
+#define RTSAN_MAYBE_INTERCEPT_CLONE INTERCEPT_FUNCTION(clone)
+#else
+#define RTSAN_MAYBE_INTERCEPT_CLONE
+#endif
+
 #if SANITIZER_INTERCEPT_PROCESS_VM_READV
 INTERCEPTOR(ssize_t, process_vm_readv, pid_t pid, const struct iovec *local_iov,
             unsigned long liovcnt, const struct iovec *remote_iov,
@@ -1650,6 +1675,7 @@ void __rtsan::InitializeInterceptors() {
 
   INTERCEPT_FUNCTION(fork);
   INTERCEPT_FUNCTION(execve);
+  RTSAN_MAYBE_INTERCEPT_CLONE;
 
   RTSAN_MAYBE_INTERCEPT_PROCESS_VM_READV;
   RTSAN_MAYBE_INTERCEPT_PROCESS_VM_WRITEV;
diff --git a/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp b/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp
index f12df9ea90855..4f94dd4bde5bd 100644
--- a/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp
+++ b/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp
@@ -1273,6 +1273,35 @@ TEST_F(PthreadRwlockTest, PthreadRwlockWrlockSurvivesWhenNonRealtime) {
   ExpectNonRealtimeSurvival(Func);
 }
 
+#if SANITIZER_GLIBC
+TEST(TestRtsanInterceptors, CloneDiesWhenRealtime) {
+  std::vector<char> buf;
+  buf.resize(1024 * 1024);
+  auto Call = [](void *a) { return 0; };
+  auto Func = [&buf, &Call]() {
+    clone(Call, buf.data() + buf.size(), 0, nullptr);
+  };
+
+  ExpectRealtimeDeath(Func, "clone");
+  ExpectNonRealtimeSurvival(Func);
+}
+
+TEST(TestRtsanInterceptors, CloneWithTldDiesWhenRealtime) {
+  std::vector<char> buf;
+  pid_t pidfd;
+  void *tls = ::operator new(4096, std::align_val_t(16));
+  buf.resize(1024 * 1024);
+  auto Call = [](void *a) { return 0; };
+  auto Func = [&buf, &Call, &pidfd, &tls]() {
+    clone(Call, buf.data() + buf.size(), CLONE_PIDFD | CLONE_SETTLS, &pidfd,
+          tls, nullptr);
+  };
+
+  ExpectRealtimeDeath(Func, "clone");
+  ExpectNonRealtimeSurvival(Func);
+}
+#endif
+
 /*
     Sockets
 */



More information about the llvm-commits mailing list