[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:25:17 PST 2025
https://github.com/devnexen created https://github.com/llvm/llvm-project/pull/123941
None
>From 878e3f5f6b8f01ba10b070fae3093da8cb426002 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 | 36 +++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp
index 71938d3edba38d..dd707b581f0658 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,37 @@ 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
+ 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 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 +1382,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