[compiler-rt] [msan] Support prctl PR_GET_NAME call (PR #98951)

Chris Cotter via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 15 20:05:21 PDT 2024


https://github.com/ccotter updated https://github.com/llvm/llvm-project/pull/98951

>From 32b4ef6652494776c3be63721e296b08a5e37007 Mon Sep 17 00:00:00 2001
From: Chris Cotter <ccotter14 at bloomberg.net>
Date: Mon, 15 Jul 2024 14:25:27 -0400
Subject: [PATCH 1/2] [msan] Support prctl PR_GET_NAME call

Per the man page, PR_GET_NAME stores a null terminated string
into the input `char name[16]`.

This also adds prctl support in ASAN to detect freed memory being passed
to `prctl(PR_GET_NAME, ...)`:
---
 .../sanitizer_common_interceptors.inc         | 14 ++++++++++-
 compiler-rt/test/msan/prctl.cpp               | 24 +++++++++++++++++++
 2 files changed, 37 insertions(+), 1 deletion(-)
 create mode 100644 compiler-rt/test/msan/prctl.cpp

diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
index 1df61e79f7d84..8efde0d234088 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -1251,6 +1251,7 @@ INTERCEPTOR(int, prctl, int option, unsigned long arg2, unsigned long arg3,
   void *ctx;
   COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5);
   static const int PR_SET_NAME = 15;
+  static const int PR_GET_NAME = 16;
   static const int PR_SET_VMA = 0x53564d41;
   static const int PR_SCHED_CORE = 62;
   static const int PR_SCHED_CORE_GET = 0;
@@ -1264,7 +1265,18 @@ INTERCEPTOR(int, prctl, int option, unsigned long arg2, unsigned long arg3,
     internal_strncpy(buff, (char *)arg2, 15);
     buff[15] = 0;
     COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff);
-  } else if (res != -1 && option == PR_SCHED_CORE && arg2 == PR_SCHED_CORE_GET) {
+  } else if (res != 1 && option == PR_GET_NAME) {
+    unsigned long null_index = 0;
+    char *name = (char *)arg2;
+    while (null_index < 16 && name[null_index]) {
+      ++null_index;
+    }
+    if (null_index > 15) {
+      null_index = 15;
+    }
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (u64 *)arg2, null_index + 1);
+  } else if (res != -1 && option == PR_SCHED_CORE &&
+             arg2 == PR_SCHED_CORE_GET) {
     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (u64*)(arg5), sizeof(u64));
   }
   return res;
diff --git a/compiler-rt/test/msan/prctl.cpp b/compiler-rt/test/msan/prctl.cpp
new file mode 100644
index 0000000000000..7b8e60c98c13b
--- /dev/null
+++ b/compiler-rt/test/msan/prctl.cpp
@@ -0,0 +1,24 @@
+// RUN: %clangxx_msan -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s
+// REQUIRES: linux
+
+#include <linux/prctl.h>
+#include <sys/prctl.h>
+
+int main(void) {
+  prctl(PR_SET_NAME, "tname");
+  char name[16];
+  prctl(PR_GET_NAME, name);
+
+  if (name[0] == 'A') {
+    return 0;
+  }
+  if (name[5] != '\0') {
+    return 0;
+  }
+  if (name[6] != '\0') {
+    return 0;
+  }
+  // CHECK: SUMMARY: MemorySanitizer: use-of-uninitialized-value {{.*prctl.cpp}}:[[@LINE-3]]
+
+  return 0;
+}

>From 547ef8a53b9e830f4631d9c15308520c2117d819 Mon Sep 17 00:00:00 2001
From: Chris Cotter <ccotter14 at bloomberg.net>
Date: Mon, 15 Jul 2024 23:03:55 -0400
Subject: [PATCH 2/2] Feedback; add sanitizer_common test

---
 .../sanitizer_common_interceptors.inc                 | 11 ++---------
 compiler-rt/test/msan/{ => Linux}/prctl.cpp           |  1 -
 .../test/sanitizer_common/TestCases/Linux/prctl.cpp   | 10 ++++++++++
 3 files changed, 12 insertions(+), 10 deletions(-)
 rename compiler-rt/test/msan/{ => Linux}/prctl.cpp (95%)

diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
index 8efde0d234088..735faa205dd2d 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -1265,16 +1265,9 @@ INTERCEPTOR(int, prctl, int option, unsigned long arg2, unsigned long arg3,
     internal_strncpy(buff, (char *)arg2, 15);
     buff[15] = 0;
     COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff);
-  } else if (res != 1 && option == PR_GET_NAME) {
-    unsigned long null_index = 0;
+  } else if (res == 0 && option == PR_GET_NAME) {
     char *name = (char *)arg2;
-    while (null_index < 16 && name[null_index]) {
-      ++null_index;
-    }
-    if (null_index > 15) {
-      null_index = 15;
-    }
-    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (u64 *)arg2, null_index + 1);
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (u64*)arg2, internal_strlen(name) + 1);
   } else if (res != -1 && option == PR_SCHED_CORE &&
              arg2 == PR_SCHED_CORE_GET) {
     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (u64*)(arg5), sizeof(u64));
diff --git a/compiler-rt/test/msan/prctl.cpp b/compiler-rt/test/msan/Linux/prctl.cpp
similarity index 95%
rename from compiler-rt/test/msan/prctl.cpp
rename to compiler-rt/test/msan/Linux/prctl.cpp
index 7b8e60c98c13b..1af4000de8a0c 100644
--- a/compiler-rt/test/msan/prctl.cpp
+++ b/compiler-rt/test/msan/Linux/prctl.cpp
@@ -1,5 +1,4 @@
 // RUN: %clangxx_msan -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s
-// REQUIRES: linux
 
 #include <linux/prctl.h>
 #include <sys/prctl.h>
diff --git a/compiler-rt/test/sanitizer_common/TestCases/Linux/prctl.cpp b/compiler-rt/test/sanitizer_common/TestCases/Linux/prctl.cpp
index 581739500e7a9..3d51600538e6d 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/Linux/prctl.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/Linux/prctl.cpp
@@ -3,6 +3,7 @@
 #include <assert.h>
 #include <errno.h>
 #include <stdint.h>
+#include <string.h>
 #include <sys/mman.h>
 #include <sys/prctl.h>
 
@@ -60,5 +61,14 @@ int main() {
   }
   munmap(p, 128);
 
+  res = prctl(PR_SET_NAME, "tname");
+  if (res == 0) {
+    char name[16];
+    res = prctl(PR_GET_NAME, name);
+    if (res == 0) {
+        assert(!strcmp(name, "tname"));
+    }
+  }
+
   return 0;
 }



More information about the llvm-commits mailing list