1# Tests the data flow tracer. 2REQUIRES: linux, x86_64 3 4# Disable, like other dataflow tests. 5RUN: false 6XFAIL: * 7 8# Build the tracer and the test. 9RUN: %no_fuzzer_cpp_compiler -c -fno-sanitize=all -fsanitize=dataflow %S/../../lib/fuzzer/dataflow/DataFlow.cpp -o %t-DataFlow.o 10RUN: %no_fuzzer_cpp_compiler -c -fno-sanitize=all -fPIC %S/../../lib/fuzzer/dataflow/DataFlowCallbacks.cpp -o %t-DataFlowCallbacks.o 11RUN: %no_fuzzer_cpp_compiler -fno-sanitize=all -fsanitize=dataflow -fsanitize-coverage=trace-pc-guard,pc-table,bb,trace-cmp %S/ThreeFunctionsTest.cpp %t-DataFlow*.o -o %t-ThreeFunctionsTestDF 12RUN: %no_fuzzer_cpp_compiler -fno-sanitize=all -fsanitize=dataflow -fsanitize-coverage=trace-pc-guard,pc-table,bb,trace-cmp %S/Labels20Test.cpp %t-DataFlow*.o -o %t-Labels20TestDF 13RUN: %cpp_compiler %S/ThreeFunctionsTest.cpp -o %t-ThreeFunctionsTest 14 15# Dump the function list. 16RUN: %t-ThreeFunctionsTestDF 2>&1 | FileCheck %s --check-prefix=FUNC_LIST 17FUNC_LIST-DAG: LLVMFuzzerTestOneInput 18FUNC_LIST-DAG: Func1 19FUNC_LIST-DAG: Func2 20 21# Prepare the inputs. 22RUN: rm -rf %t/IN %t/IN20 23RUN: mkdir -p %t/IN %t/IN20 24RUN: echo -n ABC > %t/IN/ABC 25RUN: echo -n FUABC > %t/IN/FUABC 26RUN: echo -n FUZZR > %t/IN/FUZZR 27RUN: echo -n FUZZM > %t/IN/FUZZM 28RUN: echo -n FUZZMU > %t/IN/FUZZMU 29RUN: echo -n 1234567890123456 > %t/IN/1234567890123456 30 31RUN: echo -n FUZZxxxxxxxxxxxxxxxx > %t/IN20/FUZZxxxxxxxxxxxxxxxx 32RUN: echo -n FUZZxxxxxxxxxxxxMxxx > %t/IN20/FUZZxxxxxxxxxxxxMxxx 33RUN: echo -n FUZxxxxxxxxxxxxxxxxx > %t/IN20/FUZxxxxxxxxxxxxxxxxx 34RUN: echo -n FUxxxxxxxxxxxxxxxxxx > %t/IN20/FUxxxxxxxxxxxxxxxxxx 35 36 37RUN: export DFSAN_OPTIONS=warn_unimplemented=0 38 39# This test assumes that the functions in ThreeFunctionsTestDF are instrumented 40# in a specific order: 41# LLVMFuzzerTestOneInput: F0 42# Func1: F1 43# Func2: F2 44 45# ABC: No data is used 46RUN:%t-ThreeFunctionsTestDF %t/IN/ABC | FileCheck %s --check-prefix=IN_ABC 47IN_ABC-NOT: F0 48IN_ABC: C0 49IN_ABC-NOT: C 50 51# FUABC: First 3 bytes are checked, Func1/Func2 are not called. 52RUN:%t-ThreeFunctionsTestDF %t/IN/FUABC | FileCheck %s --check-prefix=IN_FUABC 53IN_FUABC: F0 11100{{$}} 54IN_FUABC-NOT: F 55IN_FUABC-NEXT: C0 56IN_FUABC-NOT: C 57 58# FUZZR: 5 bytes are used (4 in one function, 5-th in the other), Func2 is not called. 59RUN:%t-ThreeFunctionsTestDF %t/IN/FUZZR | FileCheck %s --check-prefix=IN_FUZZR 60IN_FUZZR: F0 11110 61IN_FUZZR: F1 00001 62IN_FUZZR-NOT: F 63IN_FUZZR: C0 64IN_FUZZR: C1 65IN_FUZZR-NOT: C 66 67# FUZZM: 5 bytes are used, both Func1 and Func2 are called, Func2 depends only on size. 68RUN:%t-ThreeFunctionsTestDF %t/IN/FUZZM | FileCheck %s --check-prefix=IN_FUZZM 69IN_FUZZM: F0 11110 70IN_FUZZM: F1 00001 71IN_FUZZM-NOT: F2 72IN_FUZZM: C0 73IN_FUZZM: C1 74IN_FUZZM: C2 75 76# FUZZMU: 6 bytes are used, both Func1 and Func2 are called, Func2 depends on byte 6 and size. 77RUN:%t-ThreeFunctionsTestDF %t/IN/FUZZMU | FileCheck %s --check-prefix=IN_FUZZMU 78 79 80# Test Labels20TestDF 81RUN:%t-Labels20TestDF %t/IN20/FUxxxxxxxxxxxxxxxxxx | FileCheck %s --check-prefix=L20_FU 82L20_FU: F0 11100000000000000000{{$}} 83L20_FU-NOT: F 84 85RUN:%t-Labels20TestDF %t/IN20/FUZxxxxxxxxxxxxxxxxx | FileCheck %s --check-prefix=L20_FUZ 86L20_FUZ: F0 11110000000000000000{{$}} 87L20_FUZ-NOT: F 88 89RUN:%t-Labels20TestDF %t/IN20/FUZZxxxxxxxxxxxxxxxx | FileCheck %s --check-prefix=L20_FUZZ 90L20_FUZZ: F0 11110000000000000000{{$}} 91L20_FUZZ-NEXT: F1 00000000000000001000{{$}} 92L20_FUZZ-NOT: F 93 94RUN:%t-Labels20TestDF %t/IN20/FUZZxxxxxxxxxxxxMxxx | FileCheck %s --check-prefix=L20_FUZZM 95L20_FUZZM: F0 11110000000000000000{{$}} 96L20_FUZZM-NEXT: F1 00000000000000001000{{$}} 97L20_FUZZM-NEXT: F2 00000000000000000001{{$}} 98L20_FUZZM-NOT: F 99 100# Don't crash with missing data_flow args. 101RUN: rm -rf %t-DFT 102RUN: %t-ThreeFunctionsTest -collect_data_flow=%t-ThreeFunctionsTestDF 103RUN: %t-ThreeFunctionsTest -data_flow_trace=%t-DFT %t/IN/FUZZMU 104 105# Test libFuzzer's built in DFT collection. 106RUN: rm -rf %t-DFT 107RUN: %t-ThreeFunctionsTest -collect_data_flow=%t-ThreeFunctionsTestDF -data_flow_trace=%t-DFT %t/IN/FUZZMU 108RUN: cat %t-DFT/* | sort | FileCheck %s --check-prefix=IN_FUZZMU 109 110IN_FUZZMU: F0 111100 111IN_FUZZMU: F1 000010 112IN_FUZZMU: F2 000001 113 114# Test that we can run collect_data_flow on the entire corpus dir 115RUN: rm -rf %t/OUT 116RUN: %t-ThreeFunctionsTest -collect_data_flow=%t-ThreeFunctionsTestDF -data_flow_trace=%t/OUT %t/IN 117RUN: %t-ThreeFunctionsTest -data_flow_trace=%t/OUT -runs=0 -focus_function=Func2 %t/IN 2>&1 | FileCheck %s --check-prefix=USE_DATA_FLOW_TRACE 118 119USE_DATA_FLOW_TRACE: INFO: DataFlowTrace: reading from {{.*}}/OUT 120USE_DATA_FLOW_TRACE: d28cb407e8e1a702c72d25473f0553d3ec172262 => |000001| 121USE_DATA_FLOW_TRACE: INFO: DataFlowTrace: 6 trace files, 3 functions, 1 traces with focus function 122USE_DATA_FLOW_TRACE: INFO: Focus function is set to 'Func2' 123USE_DATA_FLOW_TRACE: INITED 124USE_DATA_FLOW_TRACE: INFO: 2/6 inputs touch the focus function 125USE_DATA_FLOW_TRACE: INFO: 1/2 inputs have the Data Flow Trace 126 127# Test that we can run collect_data_flow on a long input (>2**16 bytes) 128RUN: printf "%0.sA" {1..150001} > %t/IN/very_long_input 129RUN: rm -rf %t/OUT 130RUN: %t-ThreeFunctionsTest -collect_data_flow=%t-ThreeFunctionsTestDF -data_flow_trace=%t/OUT %t/IN/very_long_input 131RUN: rm %t/IN/very_long_input 132 133# Test that it fails explicitly when an empty corpus is provided. 134RUN: rm -rf %t/IN && mkdir %t/IN 135RUN: not %t-ThreeFunctionsTest -collect_data_flow=%t-ThreeFunctionsTestDF -data_flow_trace=%t/OUT %t/IN 2>&1 | FileCheck %s --check-prefix=EMPTY_CORPUS 136 137EMPTY_CORPUS: ERROR: can't collect data flow without corpus provided 138