[compiler-rt] [compiler-rt][rtsan] ptrace interception on Linux. (PR #123941)

David CARLIER via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 22 05:37:18 PST 2025


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

>From 4c1262faa93b216cebc294998eb587cc82f362eb Mon Sep 17 00:00:00 2001
From: David Carlier <devnexen at gmail.com>
Date: Wed, 22 Jan 2025 13:24:05 +0000
Subject: [PATCH] [compiler-rt][rtsan] ptrace interception on Linux.

---
 .../lib/rtsan/rtsan_interceptors_posix.cpp    | 38 +++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp
index 71938d3edba38d..f9d8a9b597b1b9 100644
--- a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp
+++ b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp
@@ -41,6 +41,10 @@ void OSSpinLockLock(volatile OSSpinLock *__lock);
 #include <malloc.h>
 #endif
 
+#if SANITIZER_INTERCEPT_PTRACE
+#include <sys/ptrace.h>
+#endif
+
 #include <fcntl.h>
 #include <poll.h>
 #include <pthread.h>
@@ -1161,6 +1165,39 @@ INTERCEPTOR(ssize_t, process_vm_writev, pid_t pid,
 #define RTSAN_MAYBE_INTERCEPT_PROCESS_VM_WRITEV
 #endif
 
+#if SANITIZER_INTERCEPT_PTRACE
+#if SANITIZER_MUSL
+INTERCEPTOR(long, ptrace, int request, ...) {
+#else
+INTERCEPTOR(long, ptrace, enum __ptrace_request request, ...) {
+#endif
+  __rtsan_notify_intercepted_call("ptrace");
+  va_list args;
+
+  // A handful of ptrace requests need an additional argument on Linux/sparc
+  // (e.g. PTRACE_READDATA) but we only intercept the standard calls at the
+  // moment. We might need to rework all if rtsan is supported on BSD,
+  // interfaces differ vastly, data is read in word size on Linux vs large
+  // chunks on freebsd and so on ...
+  va_start(args, request);
+  pid_t pid = va_arg(args, pid_t);
+
+  // addr and data types depend on the request, either of these are ignored in
+  // some cases too. using intptr_t to be able to hold accepted ptrace types.
+  using arg_type = intptr_t;
+  static_assert(sizeof(arg_type) >= sizeof(struct ptrace_seekinfo_args *));
+  static_assert(sizeof(arg_type) >= sizeof(int));
+  arg_type addr = va_arg(args, arg_type);
+  arg_type priv = va_arg(args, arg_type);
+  va_end(args);
+
+  return REAL(ptrace)(request, pid, addr, priv);
+}
+#define RTSAN_MAYBE_INTERCEPT_PTRACE INTERCEPT_FUNCTION(ptrace)
+#else
+#define RTSAN_MAYBE_INTERCEPT_PTRACE
+#endif
+
 // TODO: the `wait` family of functions is an oddity. In testing, if you
 // intercept them, Darwin seemingly ignores them, and linux never returns from
 // the test. Revisit this in the future, but hopefully intercepting fork/exec is
@@ -1347,6 +1384,7 @@ void __rtsan::InitializeInterceptors() {
 
   RTSAN_MAYBE_INTERCEPT_PROCESS_VM_READV;
   RTSAN_MAYBE_INTERCEPT_PROCESS_VM_WRITEV;
+  RTSAN_MAYBE_INTERCEPT_PTRACE;
 
   INTERCEPT_FUNCTION(syscall);
 }



More information about the llvm-commits mailing list