[compiler-rt] [compiler-rt][rtsan] prctl for Linux interception. (PR #124880)

David CARLIER via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 28 21:52:18 PST 2025


https://github.com/devnexen created https://github.com/llvm/llvm-project/pull/124880

None

>From a9b1e33c30646f0910d1466d42f1fa89cc7d63a2 Mon Sep 17 00:00:00 2001
From: David Carlier <devnexen at gmail.com>
Date: Wed, 29 Jan 2025 05:50:18 +0000
Subject: [PATCH] [compiler-rt][rtsan] prctl for Linux interception.

---
 .../lib/rtsan/rtsan_interceptors_posix.cpp    | 27 +++++++++++++++++++
 .../tests/rtsan_test_interceptors_posix.cpp   | 12 +++++++++
 2 files changed, 39 insertions(+)

diff --git a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp
index 3ea9e54a046cf8..38a8423e99acec 100644
--- a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp
+++ b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp
@@ -1319,6 +1319,32 @@ INTERCEPTOR(ssize_t, process_vm_writev, pid_t pid,
 #define RTSAN_MAYBE_INTERCEPT_PROCESS_VM_WRITEV
 #endif
 
+#if SANITIZER_INTERCEPT_PRCTL
+INTERCEPTOR(int, prctl, int operation, ...) {
+  __rtsan_notify_intercepted_call("prctl");
+
+  va_list args;
+  va_start(args, operation);
+
+  // in practice, prctl syscall accepts up to 4 additional arguments.
+  // With an operation like PR_SET_NAME however
+  // call does not have to set beyond the 2nd but
+  // it is good practice to set to NULL the rest.
+  using arg_type = unsigned long;
+  arg_type arg1 = va_arg(args, arg_type);
+  arg_type arg2 = va_arg(args, arg_type);
+  arg_type arg3 = va_arg(args, arg_type);
+  arg_type arg4 = va_arg(args, arg_type);
+
+  va_end(args);
+
+  return REAL(prctl)(operation, arg1, arg2, arg3, arg4);
+}
+#define RTSAN_MAYBE_INTERCEPT_PRCTL INTERCEPT_FUNCTION(prctl)
+#else
+#define RTSAN_MAYBE_INTERCEPT_PRCTL
+#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
@@ -1520,6 +1546,7 @@ void __rtsan::InitializeInterceptors() {
 
   RTSAN_MAYBE_INTERCEPT_PROCESS_VM_READV;
   RTSAN_MAYBE_INTERCEPT_PROCESS_VM_WRITEV;
+  RTSAN_MAYBE_INTERCEPT_PRCTL;
 
   INTERCEPT_FUNCTION(syscall);
 }
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 e3688157a842c7..dc7428690250a3 100644
--- a/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp
+++ b/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp
@@ -36,6 +36,10 @@
 #include <sys/time.h>
 #endif
 
+#if SANITIZER_INTERCEPT_PRCTL
+#include <sys/prctl.h>
+#endif
+
 #include <fcntl.h>
 #include <ifaddrs.h>
 #include <net/if.h>
@@ -781,6 +785,14 @@ TEST(TestRtsanInterceptors, ProcessVmWritevDiesWhenRealtime) {
 }
 #endif
 
+#if SANITIZER_INTERCEPT_PRCTL
+TEST(TestRtsanInterceptors, PrctlDiesWhenRealtime) {
+  auto Func = []() { prctl(PR_GET_DUMPABLE, 0, 0, 0, 0); };
+  ExpectRealtimeDeath(Func, "prctl");
+  ExpectNonRealtimeSurvival(Func);
+}
+#endif
+
 class RtsanDirectoryTest : public ::testing::Test {
 protected:
   void SetUp() override {



More information about the llvm-commits mailing list