blob: cebcebbd6f7874e59bb95ff067a0b3aad6d1d08e (
plain)
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
|
#!/bin/bash -eu
# Copyright 2016 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
################################################################################
# Fuzzer runner. Appends .options arguments and seed corpus to users args.
# Usage: $0 <fuzzer_name> <fuzzer_args>
export PATH=$OUT:$PATH
cd $OUT
FUZZER=$1
shift
CORPUS_DIR="/tmp/${FUZZER}_corpus"
if [[ "$RUN_FUZZER_MODE" = interactive ]]; then
FUZZER_OUT="$OUT/${FUZZER}_${FUZZING_ENGINE}_${SANITIZER}_out"
else
FUZZER_OUT="/tmp/${FUZZER}_${FUZZING_ENGINE}_${SANITIZER}_out"
fi
function get_dictionary() {
local options_file="$FUZZER.options"
local dict_file="$FUZZER.dict"
local dict=""
if [[ -f "$options_file" ]]; then
dict=$(sed -n 's/^\s*dict\s*=\s*\(.*\)/\1/p' "$options_file" | tail -1)
fi
if [[ -z "$dict" && -f "$dict_file" ]]; then
dict="$dict_file"
fi
[[ -z "$dict" ]] && return
if [[ "$FUZZING_ENGINE" = "libfuzzer" ]]; then
printf -- "-dict=%s" "$dict"
elif [[ "$FUZZING_ENGINE" = "afl" ]]; then
printf -- "-x %s" "$dict"
elif [[ "$FUZZING_ENGINE" = "honggfuzz" ]]; then
printf -- "--dict %s" "$dict"
else
printf "Unexpected FUZZING_ENGINE: $FUZZING_ENGINE, ignoring\n" >&2
fi
}
rm -rf $CORPUS_DIR && mkdir $CORPUS_DIR
rm -rf $FUZZER_OUT && mkdir $FUZZER_OUT
SEED_CORPUS="${FUZZER}_seed_corpus.zip"
if [ -f $SEED_CORPUS ] && [ -z ${SKIP_SEED_CORPUS:-} ]; then
echo "Using seed corpus: $SEED_CORPUS"
unzip -d ${CORPUS_DIR}/ $SEED_CORPUS > /dev/null
fi
OPTIONS_FILE="${FUZZER}.options"
CUSTOM_LIBFUZZER_OPTIONS=""
if [ -f $OPTIONS_FILE ]; then
custom_asan_options=$(parse_options.py $OPTIONS_FILE asan)
if [ ! -z $custom_asan_options ]; then
export ASAN_OPTIONS="$ASAN_OPTIONS:$custom_asan_options"
fi
custom_msan_options=$(parse_options.py $OPTIONS_FILE msan)
if [ ! -z $custom_msan_options ]; then
export MSAN_OPTIONS="$MSAN_OPTIONS:$custom_msan_options"
fi
custom_ubsan_options=$(parse_options.py $OPTIONS_FILE ubsan)
if [ ! -z $custom_ubsan_options ]; then
export UBSAN_OPTIONS="$UBSAN_OPTIONS:$custom_ubsan_options"
fi
CUSTOM_LIBFUZZER_OPTIONS=$(parse_options.py $OPTIONS_FILE libfuzzer)
fi
if [[ "$FUZZING_ENGINE" = afl ]]; then
# https://chromium.googlesource.com/chromium/src/+/master/third_party/afl/src/docs/env_variables.txt
export ASAN_OPTIONS="$ASAN_OPTIONS:abort_on_error=1:symbolize=0"
export MSAN_OPTIONS="$MSAN_OPTIONS:exit_code=86:symbolize=0"
export UBSAN_OPTIONS="$UBSAN_OPTIONS:symbolize=0"
export AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1
export AFL_SKIP_CPUFREQ=1
export AFL_NO_AFFINITY=1
# AFL expects at least 1 file in the input dir.
echo input > ${CORPUS_DIR}/input
CMD_LINE="$OUT/afl-fuzz $AFL_FUZZER_ARGS -i $CORPUS_DIR -o $FUZZER_OUT $(get_dictionary) $* $OUT/$FUZZER"
elif [[ "$FUZZING_ENGINE" = honggfuzz ]]; then
# Honggfuzz expects at least 1 file in the input dir.
echo input > $CORPUS_DIR/input
# --exit_upon_crash: exit whith a first crash seen
# -R (report): save report file to this location
# -W (working dir): where the crashes go
# -v (verbose): don't use VTE UI, just stderr
# -z: use software-instrumentation of clang (trace-pc-guard....)
# -P: use persistent mode of fuzzing (i.e. LLVMFuzzerTestOneInput)
# -f: location of the initial (and destination) file corpus
# -n: number of fuzzing threads (and processes)
CMD_LINE="$OUT/honggfuzz -n 1 --exit_upon_crash -R /tmp/${FUZZER}_honggfuzz.report -W $FUZZER_OUT -v -z -P -f \"$CORPUS_DIR\" $(get_dictionary) $* -- \"$OUT/$FUZZER\""
else
CMD_LINE="$OUT/$FUZZER $FUZZER_ARGS $* $CORPUS_DIR"
if [ ! -z $CUSTOM_LIBFUZZER_OPTIONS ]; then
CMD_LINE="$CMD_LINE $CUSTOM_LIBFUZZER_OPTIONS"
fi
if [[ ! "$CMD_LINE" =~ "-dict=" ]]; then
if [ -f "$FUZZER.dict" ]; then
CMD_LINE="$CMD_LINE -dict=$FUZZER.dict"
fi
fi
CMD_LINE="$CMD_LINE < /dev/null"
fi
echo $CMD_LINE
# Unset OUT so the fuzz target can't rely on it.
unset OUT
bash -c "$CMD_LINE"
|