diff options
author | Kostya Serebryany <kcc@google.com> | 2018-05-24 01:43:48 +0000 |
---|---|---|
committer | Kostya Serebryany <kcc@google.com> | 2018-05-24 01:43:48 +0000 |
commit | 4d53b744ca0e8f7efa43da5b43ed42120a3b32d9 (patch) | |
tree | 62e5c01f9634c7f301b784227c87ed2a1e434ba8 /compiler-rt | |
parent | 49d7c2f597dea4a6398c43217660a2106496f5dc (diff) | |
download | bcm5719-llvm-4d53b744ca0e8f7efa43da5b43ed42120a3b32d9.tar.gz bcm5719-llvm-4d53b744ca0e8f7efa43da5b43ed42120a3b32d9.zip |
[libFuzzer] DataFlow tracer now tags a subset of the input. A separate script merges traces from the subsets
llvm-svn: 333149
Diffstat (limited to 'compiler-rt')
-rw-r--r-- | compiler-rt/lib/fuzzer/dataflow/DataFlow.cpp | 17 | ||||
-rwxr-xr-x | compiler-rt/lib/fuzzer/scripts/merge_data_flow.py | 36 | ||||
-rw-r--r-- | compiler-rt/test/fuzzer/dataflow.test | 26 |
3 files changed, 66 insertions, 13 deletions
diff --git a/compiler-rt/lib/fuzzer/dataflow/DataFlow.cpp b/compiler-rt/lib/fuzzer/dataflow/DataFlow.cpp index c55c68ea9da..99863074d72 100644 --- a/compiler-rt/lib/fuzzer/dataflow/DataFlow.cpp +++ b/compiler-rt/lib/fuzzer/dataflow/DataFlow.cpp @@ -118,9 +118,12 @@ int main(int argc, char **argv) { LLVMFuzzerInitialize(&argc, &argv); if (argc == 1) return PrintFunctions(); - assert(argc == 2 || argc == 3); + assert(argc == 4 || argc == 5); + size_t Beg = atoi(argv[1]); + size_t End = atoi(argv[2]); + assert(Beg < End); - const char *Input = argv[1]; + const char *Input = argv[3]; fprintf(stderr, "INFO: reading '%s'\n", Input); FILE *In = fopen(Input, "r"); assert(In); @@ -137,7 +140,9 @@ int main(int argc, char **argv) { for (size_t I = 1; I <= InputLen; I++) { dfsan_label L = dfsan_create_label("", nullptr); assert(L == I); - dfsan_set_label(L, Buf + I - 1, 1); + size_t Idx = I - 1; + if (Idx >= Beg && Idx < End) + dfsan_set_label(L, Buf + Idx, 1); } dfsan_label SizeL = dfsan_create_label("", nullptr); assert(SizeL == InputLen + 1); @@ -146,10 +151,10 @@ int main(int argc, char **argv) { LLVMFuzzerTestOneInput(Buf, InputLen); free(Buf); - bool OutIsStdout = argc == 2; + bool OutIsStdout = argc == 4; fprintf(stderr, "INFO: writing dataflow to %s\n", - OutIsStdout ? "<stdout>" : argv[2]); - FILE *Out = OutIsStdout ? stdout : fopen(argv[2], "w"); + OutIsStdout ? "<stdout>" : argv[4]); + FILE *Out = OutIsStdout ? stdout : fopen(argv[4], "w"); PrintDataFlow(Out); if (!OutIsStdout) fclose(Out); } diff --git a/compiler-rt/lib/fuzzer/scripts/merge_data_flow.py b/compiler-rt/lib/fuzzer/scripts/merge_data_flow.py new file mode 100755 index 00000000000..26c0c3bf790 --- /dev/null +++ b/compiler-rt/lib/fuzzer/scripts/merge_data_flow.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python +#===- lib/fuzzer/scripts/merge_data_flow.py ------------------------------===# +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +#===------------------------------------------------------------------------===# +# Merge several data flow traces into one. +# Usage: +# merge_data_flow.py trace1 trace2 ... > result +#===------------------------------------------------------------------------===# +import sys +import fileinput +from array import array + +def Merge(a, b): + res = array('b') + for i in range(0, len(a)): + res.append(ord('1' if a[i] == '1' or b[i] == '1' else '0')) + return res.tostring() + +def main(argv): + D = {} + for line in fileinput.input(): + [F,BV] = line.strip().split(' ') + if F in D: + D[F] = Merge(D[F], BV) + else: + D[F] = BV; + for F in D.keys(): + print F, D[F] + +if __name__ == '__main__': + main(sys.argv) diff --git a/compiler-rt/test/fuzzer/dataflow.test b/compiler-rt/test/fuzzer/dataflow.test index edb655f7a7f..46e5c5d3d1c 100644 --- a/compiler-rt/test/fuzzer/dataflow.test +++ b/compiler-rt/test/fuzzer/dataflow.test @@ -23,33 +23,45 @@ RUN: echo -n FUZZMU > %t/IN/FUZZMU RUN: echo -n 1234567890123456 > %t/IN/1234567890123456 # ABC: No data is used, the only used label is 4 (corresponds to the size) -RUN:%t-ThreeFunctionsTestDF %t/IN/ABC | FileCheck %s --check-prefix=IN_ABC +RUN:%t-ThreeFunctionsTestDF 0 3 %t/IN/ABC | FileCheck %s --check-prefix=IN_ABC IN_ABC: F{{[012]}} 0001 IN_ABC-NOT: F # FUABC: First 3 bytes are checked, Func1/Func2 are not called. -RUN:%t-ThreeFunctionsTestDF %t/IN/FUABC | FileCheck %s --check-prefix=IN_FUABC +RUN:%t-ThreeFunctionsTestDF 0 5 %t/IN/FUABC | FileCheck %s --check-prefix=IN_FUABC IN_FUABC: F{{[012]}} 111001 IN_FUABC-NOT: F # 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 +RUN:%t-ThreeFunctionsTestDF 0 5 %t/IN/FUZZR | FileCheck %s --check-prefix=IN_FUZZR IN_FUZZR-DAG: F{{[012]}} 111101 IN_FUZZR-DAG: F{{[012]}} 000010 IN_FUZZR-NOT: F # FUZZM: 5 bytes are used, both Func1 and Func2 are called, Func2 depends only on size (label 6). -RUN:%t-ThreeFunctionsTestDF %t/IN/FUZZM | FileCheck %s --check-prefix=IN_FUZZM +RUN:%t-ThreeFunctionsTestDF 0 5 %t/IN/FUZZM | FileCheck %s --check-prefix=IN_FUZZM IN_FUZZM-DAG: F{{[012]}} 000010 IN_FUZZM-DAG: F{{[012]}} 111101 IN_FUZZM-DAG: F{{[012]}} 000001 # FUZZMU: 6 bytes are used, both Func1 and Func2 are called, Func2 depends on byte 6 and size (label 7) -RUN:%t-ThreeFunctionsTestDF %t/IN/FUZZMU | FileCheck %s --check-prefix=IN_FUZZMU +RUN:%t-ThreeFunctionsTestDF 0 6 %t/IN/FUZZMU | FileCheck %s --check-prefix=IN_FUZZMU + +# Test merge_data_flow +RUN:rm -f %t-merge-* +RUN:%t-ThreeFunctionsTestDF 0 2 %t/IN/FUZZMU > %t-merge-1 +RUN:%t-ThreeFunctionsTestDF 2 4 %t/IN/FUZZMU > %t-merge-2 +RUN:%t-ThreeFunctionsTestDF 4 6 %t/IN/FUZZMU > %t-merge-3 +RUN:%libfuzzer_src/scripts/merge_data_flow.py %t-merge-* | FileCheck %s --check-prefix=IN_FUZZMU + IN_FUZZMU-DAG: F{{[012]}} 0000100 IN_FUZZMU-DAG: F{{[012]}} 1111001 IN_FUZZMU-DAG: F{{[012]}} 0000011 -# Today a very simple test will cause DFSan to die with "out of labels" -RUN: not %t-ExplodeDFSanLabelsTestDF %t/IN/1234567890123456 2>&1 | FileCheck %s --check-prefix=OUT_OF_LABELS +# A very simple test will cause DFSan to die with "out of labels" +RUN: not %t-ExplodeDFSanLabelsTestDF 0 16 %t/IN/1234567890123456 2>&1 | FileCheck %s --check-prefix=OUT_OF_LABELS OUT_OF_LABELS: ==FATAL: DataFlowSanitizer: out of labels +# However we can run the same test piece by piece. +RUN: %t-ExplodeDFSanLabelsTestDF 0 2 %t/IN/1234567890123456 +RUN: %t-ExplodeDFSanLabelsTestDF 2 4 %t/IN/1234567890123456 +RUN: %t-ExplodeDFSanLabelsTestDF 4 6 %t/IN/1234567890123456 |