forked from OSchip/llvm-project
[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
This commit is contained in:
parent
9b39737129
commit
ed6c757d5c
|
@ -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.
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]]
|
||||
}
|
Loading…
Reference in New Issue