[compiler-rt] ed6c757 - [DFSan] Add functions to print origin trace from origin id instead of address.

Andrew Browne via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 22 16:46:05 PST 2021


Author: Andrew Browne
Date: 2021-12-22T16:45:54-08:00
New Revision: ed6c757d5c5926a72183cdd15a5b1efc54111db0

URL: https://github.com/llvm/llvm-project/commit/ed6c757d5c5926a72183cdd15a5b1efc54111db0
DIFF: https://github.com/llvm/llvm-project/commit/ed6c757d5c5926a72183cdd15a5b1efc54111db0.diff

LOG: [DFSan] Add functions to print origin trace from origin id instead of address.

dfsan_print_origin_id_trace
dfsan_sprint_origin_id_trace

Reviewed By: vitalybuka

Differential Revision: https://reviews.llvm.org/D116184

Added: 
    compiler-rt/test/dfsan/origin_id_stack_trace.c

Modified: 
    compiler-rt/include/sanitizer/dfsan_interface.h
    compiler-rt/lib/dfsan/dfsan.cpp
    compiler-rt/lib/dfsan/done_abilist.txt

Removed: 
    


################################################################################
diff  --git a/compiler-rt/include/sanitizer/dfsan_interface.h b/compiler-rt/include/sanitizer/dfsan_interface.h
index d6209a3ea2b29..769aecfb0d705 100644
--- a/compiler-rt/include/sanitizer/dfsan_interface.h
+++ b/compiler-rt/include/sanitizer/dfsan_interface.h
@@ -87,6 +87,9 @@ void dfsan_weak_hook_strncmp(void *caller_pc, const char *s1, const char *s2,
 /// prints description at the beginning of the trace. If origin tracking is not
 /// on, or the address is not labeled, it prints nothing.
 void dfsan_print_origin_trace(const void *addr, const char *description);
+/// As above, but use an origin id from dfsan_get_origin() instead of address.
+/// Does not include header line with taint label and address information.
+void dfsan_print_origin_id_trace(dfsan_origin origin);
 
 /// Prints the origin trace of the label at the address \p addr to a
 /// pre-allocated output buffer. If origin tracking is not on, or the address is
@@ -124,6 +127,10 @@ void dfsan_print_origin_trace(const void *addr, const char *description);
 /// return value is not less than \p out_buf_size.
 size_t dfsan_sprint_origin_trace(const void *addr, const char *description,
                                  char *out_buf, size_t out_buf_size);
+/// As above, but use an origin id from dfsan_get_origin() instead of address.
+/// Does not include header line with taint label and address information.
+size_t dfsan_sprint_origin_id_trace(dfsan_origin origin, char *out_buf,
+                                    size_t out_buf_size);
 
 /// Prints the stack trace leading to this call to a pre-allocated output
 /// buffer.

diff  --git a/compiler-rt/lib/dfsan/dfsan.cpp b/compiler-rt/lib/dfsan/dfsan.cpp
index ce2c04df83a8b..ee7221c7b9a84 100644
--- a/compiler-rt/lib/dfsan/dfsan.cpp
+++ b/compiler-rt/lib/dfsan/dfsan.cpp
@@ -630,22 +630,16 @@ void PrintInvalidOriginWarning(dfsan_label label, const void *address) {
       d.Warning(), label, address, d.Default());
 }
 
-bool PrintOriginTraceToStr(const void *addr, const char *description,
-                           InternalScopedString *out) {
-  CHECK(out);
-  CHECK(dfsan_get_track_origins());
+void PrintInvalidOriginIdWarning(dfsan_origin origin) {
   Decorator d;
+  Printf(
+      "  %sOrigin Id %d has invalid origin tracking. This can "
+      "be a DFSan bug.%s\n",
+      d.Warning(), origin, d.Default());
+}
 
-  const dfsan_label label = *__dfsan::shadow_for(addr);
-  CHECK(label);
-
-  const dfsan_origin origin = *__dfsan::origin_for(addr);
-
-  out->append("  %sTaint value 0x%x (at %p) origin tracking (%s)%s\n",
-              d.Origin(), label, addr, description ? description : "",
-              d.Default());
-
-  Origin o = Origin::FromRawId(origin);
+bool PrintOriginTraceFramesToStr(Origin o, InternalScopedString *out) {
+  Decorator d;
   bool found = false;
 
   while (o.isChainedOrigin()) {
@@ -668,6 +662,25 @@ bool PrintOriginTraceToStr(const void *addr, const char *description,
   return found;
 }
 
+bool PrintOriginTraceToStr(const void *addr, const char *description,
+                           InternalScopedString *out) {
+  CHECK(out);
+  CHECK(dfsan_get_track_origins());
+  Decorator d;
+
+  const dfsan_label label = *__dfsan::shadow_for(addr);
+  CHECK(label);
+
+  const dfsan_origin origin = *__dfsan::origin_for(addr);
+
+  out->append("  %sTaint value 0x%x (at %p) origin tracking (%s)%s\n",
+              d.Origin(), label, addr, description ? description : "",
+              d.Default());
+
+  Origin o = Origin::FromRawId(origin);
+  return PrintOriginTraceFramesToStr(o, out);
+}
+
 }  // namespace
 
 extern "C" SANITIZER_INTERFACE_ATTRIBUTE void dfsan_print_origin_trace(
@@ -725,6 +738,50 @@ dfsan_sprint_origin_trace(const void *addr, const char *description,
   return trace.length();
 }
 
+extern "C" SANITIZER_INTERFACE_ATTRIBUTE void dfsan_print_origin_id_trace(
+    dfsan_origin origin) {
+  if (!dfsan_get_track_origins()) {
+    PrintNoOriginTrackingWarning();
+    return;
+  }
+  Origin o = Origin::FromRawId(origin);
+
+  InternalScopedString trace;
+  bool success = PrintOriginTraceFramesToStr(o, &trace);
+
+  if (trace.length())
+    Printf("%s", trace.data());
+
+  if (!success)
+    PrintInvalidOriginIdWarning(origin);
+}
+
+extern "C" SANITIZER_INTERFACE_ATTRIBUTE uptr dfsan_sprint_origin_id_trace(
+    dfsan_origin origin, char *out_buf, uptr out_buf_size) {
+  CHECK(out_buf);
+
+  if (!dfsan_get_track_origins()) {
+    PrintNoOriginTrackingWarning();
+    return 0;
+  }
+  Origin o = Origin::FromRawId(origin);
+
+  InternalScopedString trace;
+  bool success = PrintOriginTraceFramesToStr(o, &trace);
+
+  if (!success) {
+    PrintInvalidOriginIdWarning(origin);
+    return 0;
+  }
+
+  if (out_buf_size) {
+    internal_strncpy(out_buf, trace.data(), out_buf_size - 1);
+    out_buf[out_buf_size - 1] = '\0';
+  }
+
+  return trace.length();
+}
+
 extern "C" SANITIZER_INTERFACE_ATTRIBUTE dfsan_origin
 dfsan_get_init_origin(const void *addr) {
   if (!dfsan_get_track_origins())

diff  --git a/compiler-rt/lib/dfsan/done_abilist.txt b/compiler-rt/lib/dfsan/done_abilist.txt
index eef7c48948cc3..b944b799b152a 100644
--- a/compiler-rt/lib/dfsan/done_abilist.txt
+++ b/compiler-rt/lib/dfsan/done_abilist.txt
@@ -30,8 +30,12 @@ fun:dfsan_flush=uninstrumented
 fun:dfsan_flush=discard
 fun:dfsan_print_origin_trace=uninstrumented
 fun:dfsan_print_origin_trace=discard
+fun:dfsan_print_origin_id_trace=uninstrumented
+fun:dfsan_print_origin_id_trace=discard
 fun:dfsan_sprint_origin_trace=uninstrumented
 fun:dfsan_sprint_origin_trace=discard
+fun:dfsan_sprint_origin_id_trace=uninstrumented
+fun:dfsan_sprint_origin_id_trace=discard
 fun:dfsan_sprint_stack_trace=uninstrumented
 fun:dfsan_sprint_stack_trace=discard
 fun:dfsan_get_origin=uninstrumented

diff  --git a/compiler-rt/test/dfsan/origin_id_stack_trace.c b/compiler-rt/test/dfsan/origin_id_stack_trace.c
new file mode 100644
index 0000000000000..5958a8a3bea22
--- /dev/null
+++ b/compiler-rt/test/dfsan/origin_id_stack_trace.c
@@ -0,0 +1,74 @@
+// RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=1 %s -o %t && \
+// RUN:     %run %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out
+//
+// RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=1 -mllvm -dfsan-instrument-with-call-threshold=0 %s -o %t && \
+// RUN:     %run %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out
+//
+// REQUIRES: x86_64-target-arch
+
+#include <sanitizer/dfsan_interface.h>
+#include <stdio.h>
+#include <string.h>
+
+__attribute__((noinline)) int foo(int a, int b) { return a + b; }
+
+__attribute__((noinline)) void bar(int depth, void *addr, int size) {
+  if (depth) {
+    bar(depth - 1, addr, size);
+  } else {
+    dfsan_set_label(1, addr, size);
+  }
+}
+
+__attribute__((noinline)) void baz(int depth, void *addr, int size) {
+  bar(depth, addr, size);
+}
+
+int main(int argc, char *argv[]) {
+  int a = 10;
+  int b = 20;
+  baz(8, &a, sizeof(a));
+  int c = foo(a, b);
+  dfsan_origin c_o = dfsan_get_origin(c);
+  dfsan_print_origin_id_trace(c_o);
+  // CHECK: Origin value: {{.*}}, Taint value was created at
+  // CHECK: #0 {{.*}} in bar.dfsan {{.*}}origin_id_stack_trace.c:[[@LINE-16]]
+  // CHECK-COUNT-8: #{{[0-9]+}} {{.*}} in bar.dfsan {{.*}}origin_id_stack_trace.c:[[@LINE-19]]
+  // CHECK: #9 {{.*}} in baz.dfsan {{.*}}origin_id_stack_trace.c:[[@LINE-13]]
+
+  char buf[3000];
+  size_t length = dfsan_sprint_origin_id_trace(c_o, buf, sizeof(buf));
+
+  printf("==OUTPUT==\n\n%s==EOS==\n", buf);
+  // CHECK: ==OUTPUT==
+  // CHECK: Origin value: {{.*}}, Taint value was created at
+  // CHECK: #0 {{.*}} in bar.dfsan {{.*}}origin_id_stack_trace.c:[[@LINE-26]]
+  // CHECK-COUNT-8: #{{[0-9]+}} {{.*}} in bar.dfsan {{.*}}origin_id_stack_trace.c:[[@LINE-29]]
+  // CHECK: #9 {{.*}} in baz.dfsan {{.*}}origin_id_stack_trace.c:[[@LINE-23]]
+  // CHECK: ==EOS==
+
+  char tinybuf[20];
+  size_t same_length =
+      dfsan_sprint_origin_id_trace(c_o, tinybuf, sizeof(tinybuf));
+
+  printf("==TRUNCATED OUTPUT==\n\n%s==EOS==\n", tinybuf);
+  // CHECK: ==TRUNCATED OUTPUT==
+  // CHECK: Origin value: 0x1==EOS==
+
+  printf("Returned length: %zu\n", length);
+  printf("Actual length: %zu\n", strlen(buf));
+  printf("Returned length with truncation: %zu\n", same_length);
+
+  // CHECK: Returned length: [[#LEN:]]
+  // CHECK: Actual length: [[#LEN]]
+  // CHECK: Returned length with truncation: [[#LEN]]
+
+  buf[0] = '\0';
+  length = dfsan_sprint_origin_id_trace(c_o, buf, 0);
+  printf("Output=\"%s\"\n", buf);
+  printf("Returned length: %zu\n", length);
+  // CHECK: Output=""
+  // CHECK: Returned length: [[#LEN]]
+}


        


More information about the llvm-commits mailing list