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 @@ -158,6 +158,12 @@ } } +static void ReportUnsupportedFast16(const char *func) { + Report("FATAL: DataFlowSanitizer: %s is unsupported in fast16labels mode\n", + func); + Die(); +} + // Resolves the union of two unequal labels. Nonequality is a precondition for // this function (the instrumentation pass inlines the equality test). extern "C" SANITIZER_INTERFACE_ATTRIBUTE @@ -253,8 +259,10 @@ extern "C" SANITIZER_INTERFACE_ATTRIBUTE dfsan_label dfsan_create_label(const char *desc, void *userdata) { + if (flags().fast16labels) + ReportUnsupportedFast16("dfsan_create_label"); dfsan_label label = - atomic_fetch_add(&__dfsan_last_label, 1, memory_order_relaxed) + 1; + atomic_fetch_add(&__dfsan_last_label, 1, memory_order_relaxed) + 1; dfsan_check_label(label); __dfsan_label_info[label].l1 = __dfsan_label_info[label].l2 = 0; __dfsan_label_info[label].desc = desc; @@ -311,11 +319,15 @@ extern "C" SANITIZER_INTERFACE_ATTRIBUTE const struct dfsan_label_info *dfsan_get_label_info(dfsan_label label) { + if (flags().fast16labels) + ReportUnsupportedFast16("dfsan_get_label_info"); return &__dfsan_label_info[label]; } extern "C" SANITIZER_INTERFACE_ATTRIBUTE int dfsan_has_label(dfsan_label label, dfsan_label elem) { + if (flags().fast16labels) + return label & elem; if (label == elem) return true; const dfsan_label_info *info = dfsan_get_label_info(label); @@ -328,6 +340,8 @@ extern "C" SANITIZER_INTERFACE_ATTRIBUTE dfsan_label dfsan_has_label_with_desc(dfsan_label label, const char *desc) { + if (flags().fast16labels) + ReportUnsupportedFast16("dfsan_has_label_with_desc"); const dfsan_label_info *info = dfsan_get_label_info(label); if (info->l1 != 0) { return dfsan_has_label_with_desc(info->l1, desc) || @@ -347,9 +361,11 @@ extern "C" SANITIZER_INTERFACE_ATTRIBUTE void dfsan_dump_labels(int fd) { + if (flags().fast16labels) + ReportUnsupportedFast16("dfsan_dump_labels"); + dfsan_label last_label = atomic_load(&__dfsan_last_label, memory_order_relaxed); - for (uptr l = 1; l <= last_label; ++l) { char buf[64]; internal_snprintf(buf, sizeof(buf), "%u %u %u ", l, diff --git a/compiler-rt/test/dfsan/fast16labels.c b/compiler-rt/test/dfsan/fast16labels.c --- a/compiler-rt/test/dfsan/fast16labels.c +++ b/compiler-rt/test/dfsan/fast16labels.c @@ -1,4 +1,13 @@ -// RUN: %clang_dfsan %s -o %t && DFSAN_OPTIONS=fast16labels=1 %run %t +// RUN: %clang_dfsan %s -o %t +// RUN: DFSAN_OPTIONS=fast16labels=1 %run %t +// RUN: DFSAN_OPTIONS=fast16labels=1 not %run %t dfsan_create_label 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CREATE-LABEL +// RUN: DFSAN_OPTIONS=fast16labels=1 not %run %t dfsan_get_label_info 2>&1 \ +// RUN: | FileCheck %s --check-prefix=GET-LABEL-INFO +// RUN: DFSAN_OPTIONS=fast16labels=1 not %run %t dfsan_has_label_with_desc \ +// RUN: 2>&1 | FileCheck %s --check-prefix=HAS-LABEL-WITH-DESC +// RUN: DFSAN_OPTIONS=fast16labels=1:dump_labels_at_exit=/dev/stdout not %run \ +// RUN: %t 2>&1 | FileCheck %s --check-prefix=DUMP-LABELS // // Tests DFSAN_OPTIONS=fast16labels=1 // @@ -6,12 +15,27 @@ #include #include +#include int foo(int a, int b) { return a + b; } -int main() { +int main(int argc, char *argv[]) { + // Death tests for unsupported API usage. + const char *command = (argc < 2) ? "" : argv[1]; + // CREATE-LABEL: FATAL: DataFlowSanitizer: dfsan_create_label is unsupported + if (strcmp(command, "dfsan_create_label") == 0) + dfsan_create_label("", NULL); + // GET-LABEL-INFO: FATAL: DataFlowSanitizer: dfsan_get_label_info is unsupported + if (strcmp(command, "dfsan_get_label_info") == 0) + dfsan_get_label_info(1); + // HAS-LABEL-WITH-DESC: FATAL: DataFlowSanitizer: dfsan_has_label_with_desc is unsupported + if (strcmp(command, "dfsan_has_label_with_desc") == 0) + dfsan_has_label_with_desc(1, ""); + // DUMP-LABELS: FATAL: DataFlowSanitizer: dfsan_dump_labels is unsupported + + // Supported usage. int a = 10; int b = 20; dfsan_set_label(8, &a, sizeof(a)); @@ -22,4 +46,7 @@ dfsan_label l = dfsan_get_label(c); printf("C: 0x%x\n", l); assert(l == 520); // OR of the other two labels. + assert(dfsan_has_label(l, 8)); + assert(dfsan_has_label(l, 512)); + assert(!dfsan_has_label(l, 1)); }