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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
|
#!/usr/bin/env bash
usage ()
{
test_ids=$(echo "${llvm_all_ids[*]}" | sed 's/ /, /g')
cat << EOF
usage: $0 options
options:
-h Help
-l, --llvm <n> Use llvm fuzz tests and run n times 0=just build, -1=skip (default $use_llvm).
-a, --afl <n> Use AFL fuzz tests and run n times 0=just build, -1=skip (default $use_afl).
-t, --time <n> Run each group of max time <n>[s,h,m,d] - n seconds, hours, minutes or days.
-e <exec|rand|all> Run a specific llvm test or [$test_ids, rand, all].
-f <file> Use this file as initial raw input. Can be repeated.
-d <0,1> Use dump of internal inflate test corpus (default $use_internal_corp).
-i <dir> Fuzz input dir (default $fuzzin_dir).
-o <dir> Fuzz output dir (default $fuzzout_dir).
EOF
exit 0
}
# Defaults
use_afl=-1
use_llvm=1
samp_files=
use_internal_corp=0
fuzzin_dir=fuzzin
fuzzout_dir=fuzzout
llvm_opts=" -print_final_stats=1"
afl_timeout_cmd=""
run_secs=0
llvm_tests=("igzip_simple_inflate_fuzz_test")
llvm_all_ids=("simple" "checked" "round_trip")
llvm_all_tests=("igzip_simple_inflate_fuzz_test" "igzip_checked_inflate_fuzz_test" "igzip_simple_round_trip_fuzz_test")
# Options
while [ "$1" != "${1##-}" ]; do
case $1 in
-h | --help)
usage
;;
-t | --time)
run_secs=$(echo $2 | sed -e 's/d$/*24h/' -e 's/h$/*60m/' -e 's/m$/*60/' -e 's/s$//'| bc)
llvm_opts+=" -max_total_time=$run_secs"
afl_timeout_cmd="timeout --preserve-status $run_secs"
echo Run each for $run_secs seconds
shift 2
;;
-a | --afl)
use_afl=$2
shift 2
;;
-l | --llvm)
use_llvm=$2
shift 2
;;
-f)
samp_files+="$2 "
use_internal_corp=0
shift 2
;;
-d)
use_internal_corp=$2
shift 2
;;
-e)
case $2 in
all)
llvm_tests=${llvm_all_tests[@]}
;;
rand)
llvm_tests=${llvm_all_tests[$RANDOM % ${#llvm_all_tests[@]} ]}
;;
*)
flag=0
for id_index in "${!llvm_all_ids[@]}"; do
if [[ "${llvm_all_ids[$id_index]}" = "$2" ]]; then
flag=1
llvm_tests[0]="${llvm_all_tests[$id_index]}"
break;
fi
done
if [ $flag -eq 0 ]; then
test_ids=$(echo "${llvm_all_ids[*]}" | sed 's/ /, /g')
echo "Invalid test, valid options: $test_ids, rand, or all"
exit 0
fi
;;
esac
shift 2
;;
-i)
fuzzin_dir=$2
shift 2
;;
-o)
fuzzout_dir=$2
shift 2
;;
esac
done
set -xe #exit on fail
# Optionally build afl fuzz tests
if [ $use_afl -ge 0 ]; then
echo Build afl fuzz tests
if ! command -V afl-gcc > /dev/null; then
echo $0 option --afl requires package afl installed
exit 0
fi
make -f Makefile.unx clean
make -f Makefile.unx units=igzip CC=afl-gcc other
fi
# Optionally build llvm fuzz tests
if [ $use_llvm -ge 0 ]; then
echo Build llvm fuzz tests
if ( command -V clang++ > /dev/null ); then
if (echo int LLVMFuzzerTestOneInput\(\)\{return 0\;\} | clang++ -x c - -fsanitize=fuzzer,address -lpthread -o /dev/null >& /dev/null); then
echo have modern clang
llvm_link_args='FUZZLINK=-fsanitize=fuzzer,address'
elif (echo int LLVMFuzzerTestOneInput\(\)\{return 0\;\} | clang++ -x c - -lFuzzer -lpthread -o /dev/null >& /dev/null); then
echo have libFuzzer
llvm_link_args='FUZZLINK=-lFuzzer'
else
echo $0 option --llvm requires clang++ and libFuzzer
exit 0
fi
fi
rm -rf bin
make -f Makefile.unx units=igzip llvm_fuzz_tests igzip_dump_inflate_corpus CC=clang CXX=clang++ ${llvm_link_args}
fi
#Create fuzz input/output directories
mkdir -p $fuzzin_dir
if [ $use_afl -ge 0 ]; then
mkdir -p $fuzzout_dir
fi
# Optionally fill fuzz input with internal tests corpus
[ $use_internal_corp -gt 0 ] && ./igzip_dump_inflate_corpus $fuzzin_dir
# Optionally compress input samples as input into fuzz dir
for f in $samp_files; do
echo Using sample file $f
f_base=`basename $f`
./igzip_file_perf $f -o $fuzzin_dir/samp_${f_base}_cmp
done
# Optionally run tests alternately one after the other
while [ $use_llvm -gt 0 -o $use_afl -gt 0 ]; do
if [ $use_afl -gt 0 ]; then
echo afl run $use_afl
let use_afl--
$afl_timeout_cmd afl-fuzz -T "Run inflate $run_secs s" -i $fuzzin_dir -o $fuzzout_dir -M fuzzer1 -- ./igzip_fuzz_inflate @@
afl-whatsup $fuzzout_dir
fi
if [ $use_llvm -gt 0 ]; then
echo llvm run $use_llvm
let use_llvm--
for test in $llvm_tests; do
echo "Run llvm test $test"
./$test $fuzzin_dir $llvm_opts
done
fi
done
make -f Makefile.unx clean
|