llvm-project
111 строк · 2.9 Кб
1// RUN: %clang_dfsan -fno-sanitize=dataflow -O2 -fPIE -DCALLBACKS -c %s -o %t-callbacks.o
2// RUN: %clang_dfsan -fsanitize-ignorelist=%S/Inputs/flags_abilist.txt -O2 -mllvm -dfsan-conditional-callbacks %s %t-callbacks.o -o %t
3// RUN: %run %t FooBarBaz 2>&1 | FileCheck %s
4//
5// RUN: %clang_dfsan -fno-sanitize=dataflow -O2 -fPIE -DCALLBACKS -DORIGINS -c %s -o %t-callbacks-orig.o
6// RUN: %clang_dfsan -fsanitize-ignorelist=%S/Inputs/flags_abilist.txt -O2 -mllvm -dfsan-conditional-callbacks -mllvm -dfsan-track-origins=1 -DORIGINS %s %t-callbacks-orig.o -o %t-orig
7// RUN: %run %t-orig FooBarBaz 2>&1 | FileCheck %s
8
9// Tests that callbacks are inserted for conditionals when
10// -dfsan-conditional-callbacks is specified.
11
12#include <assert.h>
13#include <sanitizer/dfsan_interface.h>
14#include <stdio.h>
15#include <string.h>
16
17#ifdef CALLBACKS
18// Compile this code without DFSan to avoid recursive instrumentation.
19
20extern dfsan_label LabelI;
21extern dfsan_label LabelJ;
22extern dfsan_label LabelIJ;
23
24void my_dfsan_conditional_callback(dfsan_label Label, dfsan_origin Origin) {
25assert(Label != 0);
26#ifdef ORIGINS
27assert(Origin != 0);
28#else
29assert(Origin == 0);
30#endif
31
32static int Count = 0;
33switch (Count++) {
34case 0:
35assert(Label == LabelI);
36break;
37case 1:
38assert(Label == LabelJ);
39break;
40case 2:
41assert(Label == LabelIJ);
42break;
43default:
44break;
45}
46
47fprintf(stderr, "Label %u used as condition\n", Label);
48}
49
50#else
51// Compile this code with DFSan and -dfsan-conditional-callbacks to insert the
52// callbacks.
53
54dfsan_label LabelI;
55dfsan_label LabelJ;
56dfsan_label LabelIJ;
57
58extern void my_dfsan_conditional_callback(dfsan_label Label,
59dfsan_origin Origin);
60
61int main(int Argc, char *Argv[]) {
62assert(Argc == 2);
63
64dfsan_set_conditional_callback(my_dfsan_conditional_callback);
65
66int result = 0;
67// Make these not look like constants, otherwise the branch we're expecting
68// may be optimized out.
69int DataI = (Argv[0][0] != 0) ? 1 : 0;
70int DataJ = (Argv[1][0] != 0) ? 2 : 0;
71LabelI = 1;
72dfsan_set_label(LabelI, &DataI, sizeof(DataI));
73LabelJ = 2;
74dfsan_set_label(LabelJ, &DataJ, sizeof(DataJ));
75LabelIJ = dfsan_union(LabelI, LabelJ);
76
77assert(dfsan_get_label(DataI) == LabelI);
78
79// CHECK: Label 1 used as condition
80if (DataI) {
81result = 42;
82}
83
84fprintf(stderr, "Result is %d\n", result);
85assert(dfsan_get_label(DataJ) == LabelJ);
86
87// CHECK: Label 2 used as condition
88switch (DataJ) {
89case 1:
90result += 10000;
91break;
92case 2:
93result += 4200;
94break;
95default:
96break;
97}
98
99int tainted_cond = ((DataI * DataJ) != 1);
100fprintf(stderr, "Result is %d\n", result);
101assert(dfsan_get_label(tainted_cond) == LabelIJ);
102
103// CHECK: Label 3 used as condition
104result = tainted_cond ? result + 420000 : 9;
105
106fprintf(stderr, "Result is %d\n", result);
107assert(result == 424242);
108return 0;
109}
110
111#endif // #ifdef CALLBACKS
112