diff --git a/compiler-rt/include/sanitizer/dfsan_interface.h b/compiler-rt/include/sanitizer/dfsan_interface.h --- a/compiler-rt/include/sanitizer/dfsan_interface.h +++ b/compiler-rt/include/sanitizer/dfsan_interface.h @@ -141,6 +141,9 @@ /// Retrieves the very first origin associated with the data at the given /// address. dfsan_origin dfsan_get_init_origin(const void *addr); + +/// Returns non-zero if tracking origins. +int dfsan_get_track_origins(void); #ifdef __cplusplus } // extern "C" diff --git a/compiler-rt/lib/dfsan/dfsan.cpp b/compiler-rt/lib/dfsan/dfsan.cpp --- a/compiler-rt/lib/dfsan/dfsan.cpp +++ b/compiler-rt/lib/dfsan/dfsan.cpp @@ -55,10 +55,11 @@ // Instrumented code may set this value in terms of -dfsan-track-origins. // * undefined or 0: do not track origins. // * 1: track origins at memory store operations. -// * 2: TODO: track origins at memory store operations and callsites. +// * 2: track origins at memory load and store operations. +// TODO: track callsites. extern "C" SANITIZER_WEAK_ATTRIBUTE const int __dfsan_track_origins; -int __dfsan_get_track_origins() { +extern "C" SANITIZER_INTERFACE_ATTRIBUTE int dfsan_get_track_origins() { return &__dfsan_track_origins ? __dfsan_track_origins : 0; } @@ -446,7 +447,7 @@ internal_memcpy(dst, src, size); internal_memcpy((void *)shadow_for(dst), (const void *)shadow_for(src), size * sizeof(dfsan_label)); - if (__dfsan_get_track_origins()) + if (dfsan_get_track_origins()) dfsan_mem_origin_transfer(dst, src, size); } @@ -514,12 +515,12 @@ if (0 != label) { const uptr beg_shadow_addr = (uptr)__dfsan::shadow_for(addr); WriteShadowWithSize(label, beg_shadow_addr, size); - if (__dfsan_get_track_origins()) + if (dfsan_get_track_origins()) SetOrigin(addr, size, origin); return; } - if (__dfsan_get_track_origins()) + if (dfsan_get_track_origins()) ReleaseOrigins(addr, size); ReleaseOrClearShadows(addr, size); @@ -533,7 +534,7 @@ SANITIZER_INTERFACE_ATTRIBUTE void dfsan_set_label(dfsan_label label, void *addr, uptr size) { dfsan_origin init_origin = 0; - if (label && __dfsan_get_track_origins()) { + if (label && dfsan_get_track_origins()) { GET_CALLER_PC_BP; GET_STORE_STACK_TRACE_PC_BP(pc, bp); init_origin = ChainOrigin(0, &stack, true); @@ -546,7 +547,7 @@ if (0 == label) return; - if (__dfsan_get_track_origins()) { + if (dfsan_get_track_origins()) { GET_CALLER_PC_BP; GET_STORE_STACK_TRACE_PC_BP(pc, bp); dfsan_origin init_origin = ChainOrigin(0, &stack, true); @@ -648,7 +649,7 @@ bool PrintOriginTraceToStr(const void *addr, const char *description, InternalScopedString *out) { CHECK(out); - CHECK(__dfsan_get_track_origins()); + CHECK(dfsan_get_track_origins()); Decorator d; const dfsan_label label = *__dfsan::shadow_for(addr); @@ -687,7 +688,7 @@ extern "C" SANITIZER_INTERFACE_ATTRIBUTE void dfsan_print_origin_trace( const void *addr, const char *description) { - if (!__dfsan_get_track_origins()) { + if (!dfsan_get_track_origins()) { PrintNoOriginTrackingWarning(); return; } @@ -713,7 +714,7 @@ char *out_buf, size_t out_buf_size) { CHECK(out_buf); - if (!__dfsan_get_track_origins()) { + if (!dfsan_get_track_origins()) { PrintNoOriginTrackingWarning(); return 0; } @@ -742,7 +743,7 @@ extern "C" SANITIZER_INTERFACE_ATTRIBUTE dfsan_origin dfsan_get_init_origin(const void *addr) { - if (!__dfsan_get_track_origins()) + if (!dfsan_get_track_origins()) return 0; const dfsan_label label = *__dfsan::shadow_for(addr); @@ -829,7 +830,7 @@ internal_memset(__dfsan_arg_tls, 0, sizeof(__dfsan_arg_tls)); internal_memset(__dfsan_retval_tls, 0, sizeof(__dfsan_retval_tls)); - if (__dfsan_get_track_origins()) { + if (dfsan_get_track_origins()) { internal_memset(__dfsan_arg_origin_tls, 0, sizeof(__dfsan_arg_origin_tls)); internal_memset(&__dfsan_retval_origin_tls, 0, sizeof(__dfsan_retval_origin_tls)); @@ -995,7 +996,7 @@ CheckASLR(); - InitShadow(__dfsan_get_track_origins()); + InitShadow(dfsan_get_track_origins()); initialize_interceptors(); diff --git a/compiler-rt/lib/dfsan/done_abilist.txt b/compiler-rt/lib/dfsan/done_abilist.txt --- a/compiler-rt/lib/dfsan/done_abilist.txt +++ b/compiler-rt/lib/dfsan/done_abilist.txt @@ -38,7 +38,8 @@ fun:dfsan_get_origin=custom fun:dfsan_get_init_origin=uninstrumented fun:dfsan_get_init_origin=discard - +fun:dfsan_get_track_origins=uninstrumented +fun:dfsan_get_track_origins=discard ############################################################################### # glibc diff --git a/compiler-rt/test/dfsan/dfsan_get_track_origins.c b/compiler-rt/test/dfsan/dfsan_get_track_origins.c new file mode 100644 --- /dev/null +++ b/compiler-rt/test/dfsan/dfsan_get_track_origins.c @@ -0,0 +1,13 @@ +// RUN: %clang_dfsan -DTRACK_ORIGINS=2 -mllvm -dfsan-track-origins=2 %s -o %t && %run %t +// RUN: %clang_dfsan -DTRACK_ORIGINS=1 -mllvm -dfsan-track-origins=1 %s -o %t && %run %t +// RUN: %clang_dfsan -DTRACK_ORIGINS=0 %s -o %t && %run %t +// +// REQUIRES: x86_64-target-arch + +#include + +#include + +int main(int argc, char *argv[]) { + assert(dfsan_get_track_origins() == TRACK_ORIGINS); +} diff --git a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp --- a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp @@ -1397,7 +1397,8 @@ Changed = true; return new GlobalVariable( M, OriginTy, true, GlobalValue::WeakODRLinkage, - ConstantInt::getSigned(OriginTy, shouldTrackOrigins()), + ConstantInt::getSigned(OriginTy, + shouldTrackOrigins() ? ClTrackOrigins : 0), "__dfsan_track_origins"); }); diff --git a/llvm/test/Instrumentation/DataFlowSanitizer/basic.ll b/llvm/test/Instrumentation/DataFlowSanitizer/basic.ll --- a/llvm/test/Instrumentation/DataFlowSanitizer/basic.ll +++ b/llvm/test/Instrumentation/DataFlowSanitizer/basic.ll @@ -1,5 +1,6 @@ ; RUN: opt < %s -dfsan -S | FileCheck %s --check-prefixes=CHECK,CHECK_NO_ORIGIN -DSHADOW_XOR_MASK=87960930222080 --dump-input-context=100 -; RUN: opt < %s -dfsan -dfsan-track-origins=1 -S | FileCheck %s --check-prefixes=CHECK,CHECK_ORIGIN -DSHADOW_XOR_MASK=87960930222080 --dump-input-context=100 +; RUN: opt < %s -dfsan -dfsan-track-origins=1 -S | FileCheck %s --check-prefixes=CHECK,CHECK_ORIGIN1 -DSHADOW_XOR_MASK=87960930222080 --dump-input-context=100 +; RUN: opt < %s -dfsan -dfsan-track-origins=2 -S | FileCheck %s --check-prefixes=CHECK_ORIGIN2 -DSHADOW_XOR_MASK=87960930222080 --dump-input-context=100 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" @@ -8,7 +9,8 @@ ; CHECK: @__dfsan_arg_origin_tls = external thread_local(initialexec) global [200 x i32] ; CHECK: @__dfsan_retval_origin_tls = external thread_local(initialexec) global i32 ; CHECK_NO_ORIGIN: @__dfsan_track_origins = weak_odr constant i32 0 -; CHECK_ORIGIN: @__dfsan_track_origins = weak_odr constant i32 1 +; CHECK_ORIGIN1: @__dfsan_track_origins = weak_odr constant i32 1 +; CHECK_ORIGIN2: @__dfsan_track_origins = weak_odr constant i32 2 ; CHECK: @__dfsan_shadow_width_bits = weak_odr constant i32 [[#SBITS:]] ; CHECK: @__dfsan_shadow_width_bytes = weak_odr constant i32 [[#SBYTES:]]