]> wimlib.net Git - wimlib/blob - tools/afl-fuzz/fuzz.sh
tools: add afl-fuzz files
[wimlib] / tools / afl-fuzz / fuzz.sh
1 #!/bin/bash
2
3 set -e -u -o pipefail
4
5 cd "$(dirname "$0")"
6
7 read -r -a AVAILABLE_TARGETS < <(echo */fuzz.c | sed 's@/fuzz.c@@g')
8
9 usage()
10 {
11         cat << EOF
12 Usage: $0 [OPTION]... [TARGET]...
13
14 Fuzz wimlib with afl-fuzz.
15
16 Options:
17    --asan          Enable AddressSanitizer
18    --no-resume     Don't resume existing afl-fuzz session; start a new one
19    --ubsan         Enable UndefinedBehaviorSanitizer
20
21 Available targets: ${AVAILABLE_TARGETS[*]}
22 EOF
23 }
24
25 die()
26 {
27         echo "$*" 1>&2
28         exit 1
29 }
30
31 asan=false
32 ubsan=false
33 may_resume=true
34
35 longopts_array=(
36 asan
37 help
38 no-resume
39 ubsan
40 )
41 longopts=$(echo "${longopts_array[@]}" | tr ' ' ',')
42
43 if ! options=$(getopt -o "" -l "$longopts" -- "$@"); then
44         usage 1>&2
45         exit 1
46 fi
47 eval set -- "$options"
48 while (( $# >= 0 )); do
49         case "$1" in
50         --asan)
51                 asan=true
52                 ;;
53         --help)
54                 usage
55                 exit 0
56                 ;;
57         --no-resume)
58                 may_resume=false
59                 ;;
60         --ubsan)
61                 ubsan=true
62                 ;;
63         --)
64                 shift
65                 break
66                 ;;
67         *)
68                 echo 1>&2 "Invalid option: \"$1\""
69                 usage 1>&2
70                 exit 1
71         esac
72         shift
73 done
74
75 if $asan && $ubsan; then
76         die "--asan and --ubsan are mutually exclusive"
77 fi
78
79 if ! type -P afl-fuzz > /dev/null; then
80         die "afl-fuzz is not installed"
81 fi
82
83 if (( $# == 0 )); then
84         targets=("${AVAILABLE_TARGETS[@]}")
85 else
86         for target; do
87                 found=false
88                 for t in "${AVAILABLE_TARGETS[@]}"; do
89                         if [ "$target" = "$t" ]; then
90                                 found=true
91                         fi
92                 done
93                 if ! $found; then
94                         echo 1>&2 "Unknown target '$target'"
95                         echo 1>&2 "Available targets: ${AVAILABLE_TARGETS[*]}"
96                         exit 1
97                 fi
98         done
99         targets=("$@")
100 fi
101 if (( ${#targets[@]} > 1 )) && ! type -P urxvt > /dev/null; then
102         die "urxvt is not installed"
103 fi
104
105 afl_opts=""
106 if $asan; then
107         export AFL_USE_ASAN=1
108         export CFLAGS="-O2 -m32"
109         export CC=afl-clang
110         afl_opts+=" -m 800"
111 elif $ubsan; then
112         export CFLAGS="-fsanitize=undefined -fno-sanitize-recover=undefined"
113         export CC=afl-gcc
114 else
115         export AFL_HARDEN=1
116         export CFLAGS="-O2"
117         export CC=afl-gcc
118 fi
119
120 sudo sh -c "echo core > /proc/sys/kernel/core_pattern"
121 sudo sh -c "echo performance | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor"
122
123 NPROC=$(getconf _NPROCESSORS_ONLN)
124
125 (
126 cd ../../
127 ./configure CC="$CC" CFLAGS="$CFLAGS"
128 make "-j$NPROC"
129 )
130 make "-j$NPROC" -B
131 export LD_LIBRARY_PATH=$PWD/../../.libs
132
133 for dir in "${targets[@]}"; do
134         workdir=/tmp/wimlib_$dir
135         cp -vaT "$dir" "$workdir"
136         indir=$workdir/inputs
137         outdir=$workdir/outputs
138         if [ -e "$outdir" ]; then
139                 if $may_resume; then
140                         indir="-"
141                 else
142                         rm -rf "${outdir:?}"/*
143                 fi
144         else
145                 mkdir "$outdir"
146         fi
147         cmd="afl-fuzz -i $indir -o $outdir -T wimlib_$dir $afl_opts -- $workdir/fuzz @@"
148         if (( ${#targets[@]} > 1 )); then
149                 urxvt -e bash -c "$cmd" &
150         else
151                 $cmd
152         fi
153 done
154 wait