[compiler-rt] [rtsan] Introduce blocking-fn-name and intercepted-fn-name suppressions (PR #112108)

Chris Apple via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 16 07:01:26 PDT 2024


https://github.com/cjappl updated https://github.com/llvm/llvm-project/pull/112108

>From b5dc1aa16882facd426a50902eba50b2753b7be9 Mon Sep 17 00:00:00 2001
From: Chris Apple <cja-private at pm.me>
Date: Sat, 12 Oct 2024 12:10:26 -0700
Subject: [PATCH 1/3] [rtsan] Introduce blocking-fn-name and
 intercepted-fn-name suppressions

---
 compiler-rt/lib/rtsan/rtsan_assertions.h      |  6 +++++
 compiler-rt/lib/rtsan/rtsan_checks.inc        |  2 ++
 compiler-rt/lib/rtsan/rtsan_suppressions.cpp  | 22 +++++++++++++++++++
 compiler-rt/lib/rtsan/rtsan_suppressions.h    |  2 ++
 compiler-rt/test/rtsan/stack_suppressions.cpp | 18 ++++++++++-----
 .../test/rtsan/stack_suppressions.cpp.supp    |  6 +++--
 6 files changed, 49 insertions(+), 7 deletions(-)

diff --git a/compiler-rt/lib/rtsan/rtsan_assertions.h b/compiler-rt/lib/rtsan/rtsan_assertions.h
index 8183a8202478ff..2e7cb8ffc729a7 100644
--- a/compiler-rt/lib/rtsan/rtsan_assertions.h
+++ b/compiler-rt/lib/rtsan/rtsan_assertions.h
@@ -28,6 +28,12 @@ void ExpectNotRealtime(Context &context, const DiagnosticsInfo &info,
   if (context.InRealtimeContext() && !context.IsBypassed()) {
     ScopedBypass sb{context};
 
+    if ((info.type == DiagnosticsInfoType::InterceptedCall &&
+         IsInterceptorSuppressed(info.func_name)) ||
+        (info.type == DiagnosticsInfoType::BlockingCall &&
+         IsBlockingFnSuppressed(info.func_name)))
+      return;
+
     __sanitizer::BufferedStackTrace stack;
 
     // We use the unwind_on_fatal flag here because of precedent with other
diff --git a/compiler-rt/lib/rtsan/rtsan_checks.inc b/compiler-rt/lib/rtsan/rtsan_checks.inc
index f5f23e044bd5d7..d9639fda7d9816 100644
--- a/compiler-rt/lib/rtsan/rtsan_checks.inc
+++ b/compiler-rt/lib/rtsan/rtsan_checks.inc
@@ -17,3 +17,5 @@
 // SummaryKind should be a string literal.
 
 RTSAN_CHECK(CallStackContains, "call-stack-contains")
+RTSAN_CHECK(InterceptedFnName, "intercepted-fn-name")
+RTSAN_CHECK(BlockingFnName, "blocking-fn-name")
diff --git a/compiler-rt/lib/rtsan/rtsan_suppressions.cpp b/compiler-rt/lib/rtsan/rtsan_suppressions.cpp
index c5051dd1910236..a356f97517568d 100644
--- a/compiler-rt/lib/rtsan/rtsan_suppressions.cpp
+++ b/compiler-rt/lib/rtsan/rtsan_suppressions.cpp
@@ -92,3 +92,25 @@ bool __rtsan::IsStackTraceSuppressed(const StackTrace &stack) {
   }
   return false;
 }
+
+static bool IsFunctionSuppressed(const char *interceptor_name,
+                                 const char *flag_name) {
+  if (suppression_ctx == nullptr)
+    return false;
+
+  if (!suppression_ctx->HasSuppressionType(flag_name))
+    return false;
+
+  Suppression *s;
+  return suppression_ctx->Match(interceptor_name, flag_name, &s);
+}
+
+bool __rtsan::IsInterceptorSuppressed(const char *interceptor_name) {
+  return IsFunctionSuppressed(
+      interceptor_name, ConvertTypeToFlagName(ErrorType::InterceptedFnName));
+}
+
+bool __rtsan::IsBlockingFnSuppressed(const char *blocking_fn_name) {
+  return IsFunctionSuppressed(blocking_fn_name,
+                              ConvertTypeToFlagName(ErrorType::BlockingFnName));
+}
diff --git a/compiler-rt/lib/rtsan/rtsan_suppressions.h b/compiler-rt/lib/rtsan/rtsan_suppressions.h
index 45545f8c0e0b65..e2997c6e2e755b 100644
--- a/compiler-rt/lib/rtsan/rtsan_suppressions.h
+++ b/compiler-rt/lib/rtsan/rtsan_suppressions.h
@@ -18,5 +18,7 @@ namespace __rtsan {
 
 void InitializeSuppressions();
 bool IsStackTraceSuppressed(const __sanitizer::StackTrace &stack);
+bool IsInterceptorSuppressed(const char *interceptor_name);
+bool IsBlockingFnSuppressed(const char *blocking_fn_name);
 
 } // namespace __rtsan
diff --git a/compiler-rt/test/rtsan/stack_suppressions.cpp b/compiler-rt/test/rtsan/stack_suppressions.cpp
index 2aceedbb313b11..024b1e75fda806 100644
--- a/compiler-rt/test/rtsan/stack_suppressions.cpp
+++ b/compiler-rt/test/rtsan/stack_suppressions.cpp
@@ -1,4 +1,5 @@
 // RUN: %clangxx -fsanitize=realtime %s -o %t
+// RUN: %env_rtsan_opts=halt_on_error=false %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NOSUPPRESSIONS
 // RUN: %env_rtsan_opts=suppressions='%s.supp' not %run %t 2>&1 | FileCheck %s
 // UNSUPPORTED: ios
 
@@ -22,13 +23,14 @@ void VectorViolations() {
   v.reserve(10);
 }
 
-void BlockFunc() [[clang::blocking]] { usleep(1); }
+void BlockFunc() [[clang::blocking]] { /* do something blocking */
+}
 
 void *process() [[clang::nonblocking]] {
-  void *ptr = MallocViolation();
-  VectorViolations();
-  BlockFunc();
-  free(ptr);
+  void *ptr = MallocViolation(); // Suppressed call-stack-contains
+  VectorViolations();            // Suppressed call-stack-contains with regex
+  BlockFunc();                   // Suppressed blocking-fn-name
+  free(ptr);                     // Suppressed intercepted-fn-name
 
   // This is the one that should abort the program
   // Everything else is suppressed
@@ -51,3 +53,9 @@ int main() {
 // CHECK-NOT: vector
 // CHECK-NOT: free
 // CHECK-NOT: BlockFunc
+
+// CHECK-NOSUPPRESSIONS: malloc
+// CHECK-NOSUPPRESSIONS: vector
+// CHECK-NOSUPPRESSIONS: free
+// CHECK-NOSUPPRESSIONS: BlockFunc
+// CHECK-NOSUPPRESSIONS: usleep
diff --git a/compiler-rt/test/rtsan/stack_suppressions.cpp.supp b/compiler-rt/test/rtsan/stack_suppressions.cpp.supp
index bec4db259a3e0e..6640f5690776d2 100644
--- a/compiler-rt/test/rtsan/stack_suppressions.cpp.supp
+++ b/compiler-rt/test/rtsan/stack_suppressions.cpp.supp
@@ -1,4 +1,6 @@
 call-stack-contains:MallocViolation
 call-stack-contains:std::*vector
-call-stack-contains:free
-call-stack-contains:BlockFunc
+
+intercepted-fn-name:free
+
+blocking-fn-name:BlockFunc

>From 95b54aebfa301a03a2e2a719a28a2e7d5a547466 Mon Sep 17 00:00:00 2001
From: Chris Apple <cja-private at pm.me>
Date: Sun, 13 Oct 2024 06:56:57 -0700
Subject: [PATCH 2/3] [PR] self - add CAS loop in test so empty BlockFunc
 doesn't get removed by compiler

---
 compiler-rt/test/rtsan/stack_suppressions.cpp | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/compiler-rt/test/rtsan/stack_suppressions.cpp b/compiler-rt/test/rtsan/stack_suppressions.cpp
index 024b1e75fda806..f81573b9bc5eb8 100644
--- a/compiler-rt/test/rtsan/stack_suppressions.cpp
+++ b/compiler-rt/test/rtsan/stack_suppressions.cpp
@@ -9,8 +9,11 @@
 #include <stdlib.h>
 #include <unistd.h>
 
+#include <atomic>
 #include <vector>
 
+std::atomic<int> cas_atomic{0};
+
 void *MallocViolation() { return malloc(10); }
 
 void VectorViolations() {
@@ -23,7 +26,11 @@ void VectorViolations() {
   v.reserve(10);
 }
 
-void BlockFunc() [[clang::blocking]] { /* do something blocking */
+void BlockFunc() [[clang::blocking]] {
+  int expected = 0;
+  while (!cas_atomic.compare_exchange_weak(expected, 1)) {
+    expected = cas_atomic.load();
+  }
 }
 
 void *process() [[clang::nonblocking]] {

>From 2c98c517ba9cf75f7b78ff778aa6db6bd51bae3d Mon Sep 17 00:00:00 2001
From: Chris Apple <cja-private at pm.me>
Date: Wed, 16 Oct 2024 07:01:13 -0700
Subject: [PATCH 3/3] [PR] - move to function-name-is

---
 compiler-rt/lib/rtsan/rtsan_assertions.h        |  5 +----
 compiler-rt/lib/rtsan/rtsan_checks.inc          |  3 +--
 compiler-rt/lib/rtsan/rtsan_suppressions.cpp    | 17 ++++-------------
 compiler-rt/lib/rtsan/rtsan_suppressions.h      |  3 +--
 compiler-rt/test/rtsan/stack_suppressions.cpp   |  4 ++--
 .../test/rtsan/stack_suppressions.cpp.supp      |  5 ++---
 6 files changed, 11 insertions(+), 26 deletions(-)

diff --git a/compiler-rt/lib/rtsan/rtsan_assertions.h b/compiler-rt/lib/rtsan/rtsan_assertions.h
index 2e7cb8ffc729a7..927b32e03cf026 100644
--- a/compiler-rt/lib/rtsan/rtsan_assertions.h
+++ b/compiler-rt/lib/rtsan/rtsan_assertions.h
@@ -28,10 +28,7 @@ void ExpectNotRealtime(Context &context, const DiagnosticsInfo &info,
   if (context.InRealtimeContext() && !context.IsBypassed()) {
     ScopedBypass sb{context};
 
-    if ((info.type == DiagnosticsInfoType::InterceptedCall &&
-         IsInterceptorSuppressed(info.func_name)) ||
-        (info.type == DiagnosticsInfoType::BlockingCall &&
-         IsBlockingFnSuppressed(info.func_name)))
+    if (IsFunctionSuppressed(info.func_name))
       return;
 
     __sanitizer::BufferedStackTrace stack;
diff --git a/compiler-rt/lib/rtsan/rtsan_checks.inc b/compiler-rt/lib/rtsan/rtsan_checks.inc
index d9639fda7d9816..3edaa8f5b52a26 100644
--- a/compiler-rt/lib/rtsan/rtsan_checks.inc
+++ b/compiler-rt/lib/rtsan/rtsan_checks.inc
@@ -17,5 +17,4 @@
 // SummaryKind should be a string literal.
 
 RTSAN_CHECK(CallStackContains, "call-stack-contains")
-RTSAN_CHECK(InterceptedFnName, "intercepted-fn-name")
-RTSAN_CHECK(BlockingFnName, "blocking-fn-name")
+RTSAN_CHECK(FunctionNameIs, "function-name-is")
diff --git a/compiler-rt/lib/rtsan/rtsan_suppressions.cpp b/compiler-rt/lib/rtsan/rtsan_suppressions.cpp
index a356f97517568d..e840446fac3494 100644
--- a/compiler-rt/lib/rtsan/rtsan_suppressions.cpp
+++ b/compiler-rt/lib/rtsan/rtsan_suppressions.cpp
@@ -93,24 +93,15 @@ bool __rtsan::IsStackTraceSuppressed(const StackTrace &stack) {
   return false;
 }
 
-static bool IsFunctionSuppressed(const char *interceptor_name,
-                                 const char *flag_name) {
+bool __rtsan::IsFunctionSuppressed(const char *function_name) {
   if (suppression_ctx == nullptr)
     return false;
 
+  const char *flag_name = ConvertTypeToFlagName(ErrorType::FunctionNameIs);
+
   if (!suppression_ctx->HasSuppressionType(flag_name))
     return false;
 
   Suppression *s;
-  return suppression_ctx->Match(interceptor_name, flag_name, &s);
-}
-
-bool __rtsan::IsInterceptorSuppressed(const char *interceptor_name) {
-  return IsFunctionSuppressed(
-      interceptor_name, ConvertTypeToFlagName(ErrorType::InterceptedFnName));
-}
-
-bool __rtsan::IsBlockingFnSuppressed(const char *blocking_fn_name) {
-  return IsFunctionSuppressed(blocking_fn_name,
-                              ConvertTypeToFlagName(ErrorType::BlockingFnName));
+  return suppression_ctx->Match(function_name, flag_name, &s);
 }
diff --git a/compiler-rt/lib/rtsan/rtsan_suppressions.h b/compiler-rt/lib/rtsan/rtsan_suppressions.h
index e2997c6e2e755b..9990b99f3b52cd 100644
--- a/compiler-rt/lib/rtsan/rtsan_suppressions.h
+++ b/compiler-rt/lib/rtsan/rtsan_suppressions.h
@@ -18,7 +18,6 @@ namespace __rtsan {
 
 void InitializeSuppressions();
 bool IsStackTraceSuppressed(const __sanitizer::StackTrace &stack);
-bool IsInterceptorSuppressed(const char *interceptor_name);
-bool IsBlockingFnSuppressed(const char *blocking_fn_name);
+bool IsFunctionSuppressed(const char *function_name);
 
 } // namespace __rtsan
diff --git a/compiler-rt/test/rtsan/stack_suppressions.cpp b/compiler-rt/test/rtsan/stack_suppressions.cpp
index f81573b9bc5eb8..d449ea925b3c36 100644
--- a/compiler-rt/test/rtsan/stack_suppressions.cpp
+++ b/compiler-rt/test/rtsan/stack_suppressions.cpp
@@ -36,8 +36,8 @@ void BlockFunc() [[clang::blocking]] {
 void *process() [[clang::nonblocking]] {
   void *ptr = MallocViolation(); // Suppressed call-stack-contains
   VectorViolations();            // Suppressed call-stack-contains with regex
-  BlockFunc();                   // Suppressed blocking-fn-name
-  free(ptr);                     // Suppressed intercepted-fn-name
+  BlockFunc();                   // Suppressed function-name-is
+  free(ptr);                     // Suppressed function-name-is
 
   // This is the one that should abort the program
   // Everything else is suppressed
diff --git a/compiler-rt/test/rtsan/stack_suppressions.cpp.supp b/compiler-rt/test/rtsan/stack_suppressions.cpp.supp
index 6640f5690776d2..cf380c140cfdca 100644
--- a/compiler-rt/test/rtsan/stack_suppressions.cpp.supp
+++ b/compiler-rt/test/rtsan/stack_suppressions.cpp.supp
@@ -1,6 +1,5 @@
 call-stack-contains:MallocViolation
 call-stack-contains:std::*vector
 
-intercepted-fn-name:free
-
-blocking-fn-name:BlockFunc
+function-name-is:free
+function-name-is:BlockFunc



More information about the llvm-commits mailing list