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 132 133 134 135 136 137
|
# Tests the data flow tracer.
REQUIRES: linux, x86_64
# Disable, like other dataflow tests.
RUN: false
XFAIL: *
# Build the tracer and the test.
RUN: %no_fuzzer_cpp_compiler -c -fno-sanitize=all -fsanitize=dataflow %S/../../lib/fuzzer/dataflow/DataFlow.cpp -o %t-DataFlow.o
RUN: %no_fuzzer_cpp_compiler -c -fno-sanitize=all -fPIC %S/../../lib/fuzzer/dataflow/DataFlowCallbacks.cpp -o %t-DataFlowCallbacks.o
RUN: %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
RUN: %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
RUN: %cpp_compiler %S/ThreeFunctionsTest.cpp -o %t-ThreeFunctionsTest
# Dump the function list.
RUN: %t-ThreeFunctionsTestDF 2>&1 | FileCheck %s --check-prefix=FUNC_LIST
FUNC_LIST-DAG: LLVMFuzzerTestOneInput
FUNC_LIST-DAG: Func1
FUNC_LIST-DAG: Func2
# Prepare the inputs.
RUN: rm -rf %t/IN %t/IN20
RUN: mkdir -p %t/IN %t/IN20
RUN: echo -n ABC > %t/IN/ABC
RUN: echo -n FUABC > %t/IN/FUABC
RUN: echo -n FUZZR > %t/IN/FUZZR
RUN: echo -n FUZZM > %t/IN/FUZZM
RUN: echo -n FUZZMU > %t/IN/FUZZMU
RUN: echo -n 1234567890123456 > %t/IN/1234567890123456
RUN: echo -n FUZZxxxxxxxxxxxxxxxx > %t/IN20/FUZZxxxxxxxxxxxxxxxx
RUN: echo -n FUZZxxxxxxxxxxxxMxxx > %t/IN20/FUZZxxxxxxxxxxxxMxxx
RUN: echo -n FUZxxxxxxxxxxxxxxxxx > %t/IN20/FUZxxxxxxxxxxxxxxxxx
RUN: echo -n FUxxxxxxxxxxxxxxxxxx > %t/IN20/FUxxxxxxxxxxxxxxxxxx
RUN: export DFSAN_OPTIONS=warn_unimplemented=0
# This test assumes that the functions in ThreeFunctionsTestDF are instrumented
# in a specific order:
# LLVMFuzzerTestOneInput: F0
# Func1: F1
# Func2: F2
# ABC: No data is used
RUN:%t-ThreeFunctionsTestDF %t/IN/ABC | FileCheck %s --check-prefix=IN_ABC
IN_ABC-NOT: F0
IN_ABC: C0
IN_ABC-NOT: C
# FUABC: First 3 bytes are checked, Func1/Func2 are not called.
RUN:%t-ThreeFunctionsTestDF %t/IN/FUABC | FileCheck %s --check-prefix=IN_FUABC
IN_FUABC: F0 11100{{$}}
IN_FUABC-NOT: F
IN_FUABC-NEXT: C0
IN_FUABC-NOT: C
# FUZZR: 5 bytes are used (4 in one function, 5-th in the other), Func2 is not called.
RUN:%t-ThreeFunctionsTestDF %t/IN/FUZZR | FileCheck %s --check-prefix=IN_FUZZR
IN_FUZZR: F0 11110
IN_FUZZR: F1 00001
IN_FUZZR-NOT: F
IN_FUZZR: C0
IN_FUZZR: C1
IN_FUZZR-NOT: C
# FUZZM: 5 bytes are used, both Func1 and Func2 are called, Func2 depends only on size.
RUN:%t-ThreeFunctionsTestDF %t/IN/FUZZM | FileCheck %s --check-prefix=IN_FUZZM
IN_FUZZM: F0 11110
IN_FUZZM: F1 00001
IN_FUZZM-NOT: F2
IN_FUZZM: C0
IN_FUZZM: C1
IN_FUZZM: C2
# FUZZMU: 6 bytes are used, both Func1 and Func2 are called, Func2 depends on byte 6 and size.
RUN:%t-ThreeFunctionsTestDF %t/IN/FUZZMU | FileCheck %s --check-prefix=IN_FUZZMU
# Test Labels20TestDF
RUN:%t-Labels20TestDF %t/IN20/FUxxxxxxxxxxxxxxxxxx | FileCheck %s --check-prefix=L20_FU
L20_FU: F0 11100000000000000000{{$}}
L20_FU-NOT: F
RUN:%t-Labels20TestDF %t/IN20/FUZxxxxxxxxxxxxxxxxx | FileCheck %s --check-prefix=L20_FUZ
L20_FUZ: F0 11110000000000000000{{$}}
L20_FUZ-NOT: F
RUN:%t-Labels20TestDF %t/IN20/FUZZxxxxxxxxxxxxxxxx | FileCheck %s --check-prefix=L20_FUZZ
L20_FUZZ: F0 11110000000000000000{{$}}
L20_FUZZ-NEXT: F1 00000000000000001000{{$}}
L20_FUZZ-NOT: F
RUN:%t-Labels20TestDF %t/IN20/FUZZxxxxxxxxxxxxMxxx | FileCheck %s --check-prefix=L20_FUZZM
L20_FUZZM: F0 11110000000000000000{{$}}
L20_FUZZM-NEXT: F1 00000000000000001000{{$}}
L20_FUZZM-NEXT: F2 00000000000000000001{{$}}
L20_FUZZM-NOT: F
# Don't crash with missing data_flow args.
RUN: rm -rf %t-DFT
RUN: %t-ThreeFunctionsTest -collect_data_flow=%t-ThreeFunctionsTestDF
RUN: %t-ThreeFunctionsTest -data_flow_trace=%t-DFT %t/IN/FUZZMU
# Test libFuzzer's built in DFT collection.
RUN: rm -rf %t-DFT
RUN: %t-ThreeFunctionsTest -collect_data_flow=%t-ThreeFunctionsTestDF -data_flow_trace=%t-DFT %t/IN/FUZZMU
RUN: cat %t-DFT/* | sort | FileCheck %s --check-prefix=IN_FUZZMU
IN_FUZZMU: F0 111100
IN_FUZZMU: F1 000010
IN_FUZZMU: F2 000001
# Test that we can run collect_data_flow on the entire corpus dir
RUN: rm -rf %t/OUT
RUN: %t-ThreeFunctionsTest -collect_data_flow=%t-ThreeFunctionsTestDF -data_flow_trace=%t/OUT %t/IN
RUN: %t-ThreeFunctionsTest -data_flow_trace=%t/OUT -runs=0 -focus_function=Func2 %t/IN 2>&1 | FileCheck %s --check-prefix=USE_DATA_FLOW_TRACE
USE_DATA_FLOW_TRACE: INFO: DataFlowTrace: reading from {{.*}}/OUT
USE_DATA_FLOW_TRACE: d28cb407e8e1a702c72d25473f0553d3ec172262 => |000001|
USE_DATA_FLOW_TRACE: INFO: DataFlowTrace: 6 trace files, 3 functions, 1 traces with focus function
USE_DATA_FLOW_TRACE: INFO: Focus function is set to 'Func2'
USE_DATA_FLOW_TRACE: INITED
USE_DATA_FLOW_TRACE: INFO: 2/6 inputs touch the focus function
USE_DATA_FLOW_TRACE: INFO: 1/2 inputs have the Data Flow Trace
# Test that we can run collect_data_flow on a long input (>2**16 bytes)
RUN: printf "%0.sA" {1..150001} > %t/IN/very_long_input
RUN: rm -rf %t/OUT
RUN: %t-ThreeFunctionsTest -collect_data_flow=%t-ThreeFunctionsTestDF -data_flow_trace=%t/OUT %t/IN/very_long_input
RUN: rm %t/IN/very_long_input
# Test that it fails explicitly when an empty corpus is provided.
RUN: rm -rf %t/IN && mkdir %t/IN
RUN: not %t-ThreeFunctionsTest -collect_data_flow=%t-ThreeFunctionsTestDF -data_flow_trace=%t/OUT %t/IN 2>&1 | FileCheck %s --check-prefix=EMPTY_CORPUS
EMPTY_CORPUS: ERROR: can't collect data flow without corpus provided
|