[compiler-rt] [compiler-rt][tysan] adding posix strndup interception. (PR #122255)

David CARLIER via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 9 11:13:23 PST 2025


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

>From 1bf6954a353ee4a9a484d22248dd055699e7c81c Mon Sep 17 00:00:00 2001
From: David Carlier <devnexen at gmail.com>
Date: Thu, 9 Jan 2025 11:33:38 +0000
Subject: [PATCH 1/2] [compiler-rt][tysan] adding posix strndup interception.

---
 compiler-rt/lib/tysan/tysan_interceptors.cpp | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/compiler-rt/lib/tysan/tysan_interceptors.cpp b/compiler-rt/lib/tysan/tysan_interceptors.cpp
index 08b1010a48ecf0..2dd4f1d8271f97 100644
--- a/compiler-rt/lib/tysan/tysan_interceptors.cpp
+++ b/compiler-rt/lib/tysan/tysan_interceptors.cpp
@@ -22,6 +22,12 @@
 #define TYSAN_INTERCEPT___STRDUP 0
 #endif
 
+#if SANITIZER_POSIX
+#define TYSAN_INTERCEPT___STRNDUP 1
+#else
+#define TYSAN_INTERCEPT___STRNDUP 0
+#endif
+
 #if SANITIZER_LINUX
 extern "C" int mallopt(int param, int value);
 #endif
@@ -99,6 +105,15 @@ INTERCEPTOR(char *, __strdup, const char *s) {
 }
 #endif // TYSAN_INTERCEPT___STRDUP
 
+#if TYSAN_INTERCEPT___STRNDUP
+INTERCEPTOR(char *, strndup, const char *s, SIZE_T slen) {
+  char *res = REAL(strndup)(s, slen);
+  if (res)
+    tysan_copy_types(res, const_cast<char *>(s), Min(internal_strlen(s), slen));
+  return res;
+}
+#endif
+
 INTERCEPTOR(void *, malloc, uptr size) {
   if (DlsymAlloc::Use())
     return DlsymAlloc::Allocate(size);

>From cf5e994ca26c6d908b79b00af16171d431320aa7 Mon Sep 17 00:00:00 2001
From: David Carlier <devnexen at gmail.com>
Date: Thu, 9 Jan 2025 19:00:43 +0000
Subject: [PATCH 2/2] remove const_cast usage on str*dup and add test.

---
 compiler-rt/lib/tysan/tysan_interceptors.cpp |  9 ++++++---
 compiler-rt/test/tysan/strndup.c             | 14 ++++++++++++++
 2 files changed, 20 insertions(+), 3 deletions(-)
 create mode 100644 compiler-rt/test/tysan/strndup.c

diff --git a/compiler-rt/lib/tysan/tysan_interceptors.cpp b/compiler-rt/lib/tysan/tysan_interceptors.cpp
index 2dd4f1d8271f97..c1692d4fed9a9d 100644
--- a/compiler-rt/lib/tysan/tysan_interceptors.cpp
+++ b/compiler-rt/lib/tysan/tysan_interceptors.cpp
@@ -92,7 +92,7 @@ INTERCEPTOR(void *, mmap64, void *addr, SIZE_T length, int prot, int flags,
 INTERCEPTOR(char *, strdup, const char *s) {
   char *res = REAL(strdup)(s);
   if (res)
-    tysan_copy_types(res, const_cast<char *>(s), internal_strlen(s));
+    tysan_copy_types(res, s, internal_strlen(s));
   return res;
 }
 
@@ -100,7 +100,7 @@ INTERCEPTOR(char *, strdup, const char *s) {
 INTERCEPTOR(char *, __strdup, const char *s) {
   char *res = REAL(__strdup)(s);
   if (res)
-    tysan_copy_types(res, const_cast<char *>(s), internal_strlen(s));
+    tysan_copy_types(res, s, internal_strlen(s));
   return res;
 }
 #endif // TYSAN_INTERCEPT___STRDUP
@@ -109,7 +109,7 @@ INTERCEPTOR(char *, __strdup, const char *s) {
 INTERCEPTOR(char *, strndup, const char *s, SIZE_T slen) {
   char *res = REAL(strndup)(s, slen);
   if (res)
-    tysan_copy_types(res, const_cast<char *>(s), Min(internal_strlen(s), slen));
+    tysan_copy_types(res, s, Min(internal_strlen(s), slen));
   return res;
 }
 #endif
@@ -231,6 +231,9 @@ void InitializeInterceptors() {
 #if TYSAN_INTERCEPT___STRDUP
   INTERCEPT_FUNCTION(__strdup);
 #endif
+#if TYSAN_INTERCEPT___STRNDUP
+  INTERCEPT_FUNCTION(strndup);
+#endif
 
   INTERCEPT_FUNCTION(malloc);
   INTERCEPT_FUNCTION(calloc);
diff --git a/compiler-rt/test/tysan/strndup.c b/compiler-rt/test/tysan/strndup.c
new file mode 100644
index 00000000000000..f232c632af1d68
--- /dev/null
+++ b/compiler-rt/test/tysan/strndup.c
@@ -0,0 +1,14 @@
+// RUN: %clang_tysan -O0 %s -o %t && %run %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out
+#include <stdlib.h>
+#include <string.h>
+
+int main() {
+  long val = 32167;
+  char *p = strndup((const char *)&val, sizeof(val));
+  // CHECK: ERROR: TypeSanitizer: type-aliasing-violation
+  // CHECK: READ of size 4 at {{.*}} with type int accesses an existing object of type long
+  int inc = ((*(int *)p) + 1);
+  free(p);
+  return 0;
+}



More information about the llvm-commits mailing list