1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
// RUN: %clang_dfsan -fno-sanitize=dataflow -O2 -fPIE -DCALLBACKS -c %s -o %t-callbacks.o
// RUN: %clang_dfsan -O2 -mllvm -dfsan-event-callbacks %s %t-callbacks.o -o %t
// RUN: %run %t FooBarBaz 2>&1 | FileCheck %s
// Tests that callbacks are inserted for store events when
// -dfsan-event-callbacks is specified.
#include <assert.h>
#include <sanitizer/dfsan_interface.h>
#include <stdio.h>
#include <string.h>
#ifdef CALLBACKS
// Compile this code without DFSan to avoid recursive instrumentation.
extern dfsan_label LabelI;
extern dfsan_label LabelJ;
extern dfsan_label LabelIJ;
extern dfsan_label LabelArgv;
extern size_t LenArgv;
void __dfsan_store_callback(dfsan_label Label) {
if (!Label)
return;
static int Count = 0;
switch (Count++) {
case 0:
assert(Label == LabelI);
break;
case 1:
assert(Label == LabelJ);
break;
case 2:
assert(Label == LabelIJ);
break;
default:
assert(0);
}
fprintf(stderr, "Label %u stored to memory\n", Label);
}
void __dfsan_load_callback(dfsan_label Label) {
if (!Label)
return;
fprintf(stderr, "Label %u loaded from memory\n", Label);
}
void __dfsan_mem_transfer_callback(dfsan_label *Start, size_t Len) {
assert(Len == LenArgv);
for (int I = 0; I < Len; ++I) {
assert(Start[I] == LabelArgv);
}
fprintf(stderr, "Label %u copied to memory\n", Start[0]);
}
void __dfsan_cmp_callback(dfsan_label CombinedLabel) {
if (!CombinedLabel)
return;
fprintf(stderr, "Label %u used for branching\n", CombinedLabel);
}
#else
// Compile this code with DFSan and -dfsan-event-callbacks to insert the
// callbacks.
dfsan_label LabelI;
dfsan_label LabelJ;
dfsan_label LabelIJ;
dfsan_label LabelArgv;
size_t LenArgv;
int main(int Argc, char *Argv[]) {
assert(Argc == 2);
int I = 1, J = 2;
LabelI = 1;
dfsan_set_label(LabelI, &I, sizeof(I));
LabelJ = 2;
dfsan_set_label(LabelJ, &J, sizeof(J));
LabelIJ = dfsan_union(LabelI, LabelJ);
// CHECK: Label 1 stored to memory
volatile int Sink = I;
// CHECK: Label 1 loaded from memory
// CHECK: Label 1 used for branching
assert(Sink == 1);
// CHECK: Label 2 stored to memory
Sink = J;
// CHECK: Label 2 loaded from memory
// CHECK: Label 2 used for branching
assert(Sink == 2);
// CHECK: Label 2 loaded from memory
// CHECK: Label 3 stored to memory
Sink += I;
// CHECK: Label 3 loaded from memory
// CHECK: Label 3 used for branching
assert(Sink == 3);
// CHECK: Label 3 used for branching
assert(I != J);
LenArgv = strlen(Argv[1]);
LabelArgv = 4;
dfsan_set_label(LabelArgv, Argv[1], LenArgv);
char Buf[64];
assert(LenArgv < sizeof(Buf) - 1);
// CHECK: Label 4 copied to memory
void *volatile SinkPtr = Buf;
memcpy(SinkPtr, Argv[1], LenArgv);
// CHECK: Label 4 copied to memory
SinkPtr = &Buf[1];
memmove(SinkPtr, Buf, LenArgv);
return 0;
}
#endif // #ifdef CALLBACKS
|