1# Tests the data flow tracer.
2REQUIRES: linux
3UNSUPPORTED: aarch64
4
5# Build the tracer and the test.
6RUN: %no_fuzzer_cpp_compiler -c -fno-sanitize=all -fsanitize=dataflow  %S/../../lib/fuzzer/dataflow/DataFlow.cpp -o  %t-DataFlow.o
7RUN: %no_fuzzer_cpp_compiler    -fno-sanitize=all -fsanitize=dataflow -fsanitize-coverage=trace-pc-guard,pc-table,func,trace-cmp   %S/ThreeFunctionsTest.cpp     %t-DataFlow.o -o %t-ThreeFunctionsTestDF
8RUN: %no_fuzzer_cpp_compiler    -fno-sanitize=all -fsanitize=dataflow -fsanitize-coverage=trace-pc-guard,pc-table,func,trace-cmp   %S/ExplodeDFSanLabelsTest.cpp %t-DataFlow.o -o %t-ExplodeDFSanLabelsTestDF
9RUN: %cpp_compiler %S/ThreeFunctionsTest.cpp -o %t-ThreeFunctionsTest
10
11# Dump the function list.
12RUN:  %t-ThreeFunctionsTestDF 2>&1 | FileCheck %s --check-prefix=FUNC_LIST
13FUNC_LIST-DAG: LLVMFuzzerTestOneInput
14FUNC_LIST-DAG: Func1
15FUNC_LIST-DAG: Func2
16
17# Prepare the inputs.
18RUN: rm -rf %t/IN
19RUN: mkdir -p %t/IN
20RUN: echo -n ABC    > %t/IN/ABC
21RUN: echo -n FUABC  > %t/IN/FUABC
22RUN: echo -n FUZZR  > %t/IN/FUZZR
23RUN: echo -n FUZZM  > %t/IN/FUZZM
24RUN: echo -n FUZZMU > %t/IN/FUZZMU
25RUN: echo -n 1234567890123456 > %t/IN/1234567890123456
26
27# ABC: No data is used, the only used label is 4 (corresponds to the size)
28RUN:%t-ThreeFunctionsTestDF 0 3 %t/IN/ABC    | FileCheck %s --check-prefix=IN_ABC
29IN_ABC: F{{[012]}} 0001
30IN_ABC-NOT: F
31
32# FUABC: First 3 bytes are checked, Func1/Func2 are not called.
33RUN:%t-ThreeFunctionsTestDF 0 5 %t/IN/FUABC  | FileCheck %s --check-prefix=IN_FUABC
34IN_FUABC: F{{[012]}} 111001
35IN_FUABC-NOT: F
36
37# FUZZR: 5 bytes are used (4 in one function, 5-th in the other), Func2 is not called.
38RUN:%t-ThreeFunctionsTestDF 0 5 %t/IN/FUZZR  | FileCheck %s --check-prefix=IN_FUZZR
39IN_FUZZR-DAG: F{{[012]}} 111101
40IN_FUZZR-DAG: F{{[012]}} 000010
41IN_FUZZR-NOT: F
42
43# FUZZM: 5 bytes are used, both Func1 and Func2 are called, Func2 depends only on size (label 6).
44RUN:%t-ThreeFunctionsTestDF 0 5 %t/IN/FUZZM  | FileCheck %s --check-prefix=IN_FUZZM
45IN_FUZZM-DAG: F{{[012]}} 000010
46IN_FUZZM-DAG: F{{[012]}} 111101
47IN_FUZZM-DAG: F{{[012]}} 000001
48
49# FUZZMU: 6 bytes are used, both Func1 and Func2 are called, Func2 depends on byte 6 and size (label 7)
50RUN:%t-ThreeFunctionsTestDF 0 6 %t/IN/FUZZMU  | FileCheck %s --check-prefix=IN_FUZZMU
51
52# Test merge_data_flow
53RUN:rm -f %t-merge-*
54RUN:%t-ThreeFunctionsTestDF 0 2 %t/IN/FUZZMU > %t-merge-1
55RUN:%t-ThreeFunctionsTestDF 2 4 %t/IN/FUZZMU > %t-merge-2
56RUN:%t-ThreeFunctionsTestDF 4 6 %t/IN/FUZZMU > %t-merge-3
57RUN:%libfuzzer_src/scripts/merge_data_flow.py  %t-merge-* | FileCheck %s --check-prefix=IN_FUZZMU
58
59# Test collect_data_flow
60RUN: %libfuzzer_src/scripts/collect_data_flow.py %t-ThreeFunctionsTestDF %t/IN/FUZZMU | FileCheck %s --check-prefix=IN_FUZZMU
61
62IN_FUZZMU-DAG: F{{[012]}} 0000100
63IN_FUZZMU-DAG: F{{[012]}} 1111001
64IN_FUZZMU-DAG: F{{[012]}} 0000011
65
66# A very simple test will cause DFSan to die with "out of labels"
67RUN: not %t-ExplodeDFSanLabelsTestDF 0 16 %t/IN/1234567890123456 2>&1 | FileCheck %s --check-prefix=OUT_OF_LABELS
68OUT_OF_LABELS: ==FATAL: DataFlowSanitizer: out of labels
69# However we can run the same test piece by piece.
70RUN: %t-ExplodeDFSanLabelsTestDF 0 2  %t/IN/1234567890123456
71RUN: %t-ExplodeDFSanLabelsTestDF 2 4  %t/IN/1234567890123456
72RUN: %t-ExplodeDFSanLabelsTestDF 4 6  %t/IN/1234567890123456
73# Or we can use collect_data_flow
74RUN: %libfuzzer_src/scripts/collect_data_flow.py %t-ExplodeDFSanLabelsTestDF %t/IN/1234567890123456
75
76# Test that we can run collect_data_flow on the entire corpus dir
77RUN: rm -rf %t/OUT
78RUN: %libfuzzer_src/scripts/collect_data_flow.py %t-ThreeFunctionsTestDF %t/IN %t/OUT
79RUN: %t-ThreeFunctionsTest -data_flow_trace=%t/OUT -runs=0 -focus_function=Func2 2>&1 | FileCheck %s --check-prefix=USE_DATA_FLOW_TRACE
80USE_DATA_FLOW_TRACE: INFO: Focus function is set to 'Func2'
81USE_DATA_FLOW_TRACE: INFO: DataFlowTrace: reading from {{.*}}/OUT
82USE_DATA_FLOW_TRACE-DAG: a8eefe2fd5d6b32028f355fafa3e739a6bf5edc => |000001|
83USE_DATA_FLOW_TRACE-DGA: d28cb407e8e1a702c72d25473f0553d3ec172262 => |0000011|
84USE_DATA_FLOW_TRACE: INFO: DataFlowTrace: 6 trace files, 3 functions, 2 traces with focus function
85