Index: include/sanitizer/dfsan_interface.h =================================================================== --- include/sanitizer/dfsan_interface.h +++ include/sanitizer/dfsan_interface.h @@ -79,6 +79,12 @@ /// Returns the number of labels allocated. size_t dfsan_get_label_count(void); +/// Flushes the DFSan shadow, i.e. forgets about all labels currently associated +/// with the application memory. Will work only if there are no other +/// threads executing DFSan-instrumented code concurrently. +/// Use this call to start over the taint tracking within the same procces. +void dfsan_flush(void); + /// Sets a callback to be invoked on calls to write(). The callback is invoked /// before the write is done. The write is not guaranteed to succeed when the /// callback executes. Pass in NULL to remove any callback. Index: lib/dfsan/dfsan.cc =================================================================== --- lib/dfsan/dfsan.cc +++ lib/dfsan/dfsan.cc @@ -421,6 +421,12 @@ } } +extern "C" void dfsan_flush() { + UnmapOrDie((void*)ShadowAddr(), UnusedAddr() - ShadowAddr()); + if (!MmapFixedNoReserve(ShadowAddr(), UnusedAddr() - ShadowAddr())) + Die(); +} + static void dfsan_init(int argc, char **argv, char **envp) { InitializeFlags(); Index: lib/dfsan/done_abilist.txt =================================================================== --- lib/dfsan/done_abilist.txt +++ lib/dfsan/done_abilist.txt @@ -26,6 +26,8 @@ fun:dfsan_has_label_with_desc=discard fun:dfsan_set_write_callback=uninstrumented fun:dfsan_set_write_callback=custom +fun:dfsan_flush=uninstrumented +fun:dfsan_flush=discard ############################################################################### # glibc Index: test/dfsan/flush.c =================================================================== --- /dev/null +++ test/dfsan/flush.c @@ -0,0 +1,28 @@ +// Tests dfsan_flush(). +// RUN: %clang_dfsan %s -o %t && %run %t +#include +#include +#include + +int global; + +int main() { + int local; + int *heap = (int*)malloc(sizeof(int)); + + dfsan_set_label(10, &global, sizeof(global)); + dfsan_set_label(20, &local, sizeof(local)); + dfsan_set_label(30, heap, sizeof(*heap)); + + assert(dfsan_get_label(global) == 10); + assert(dfsan_get_label(local) == 20); + assert(dfsan_get_label(*heap) == 30); + + dfsan_flush(); + + assert(dfsan_get_label(global) == 0); + assert(dfsan_get_label(local) == 0); + assert(dfsan_get_label(*heap) == 0); + + free(heap); +}