event_callbacks.c
2.92 KB
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 = dfsan_create_label("I", 0);
dfsan_set_label(LabelI, &I, sizeof(I));
LabelJ = dfsan_create_label("J", 0);
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 = dfsan_create_label("Argv", 0);
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