]> wimlib.net Git - wimlib/blob - tools/libFuzzer/fuzz.sh
fuzz.sh: add --max-len option
[wimlib] / tools / libFuzzer / fuzz.sh
1 #!/bin/bash
2
3 set -e -u -o pipefail
4
5 cd "$(dirname "$0")"
6 TOPDIR=../..
7 SCRIPTDIR=$PWD
8
9 read -r -a AVAILABLE_TARGETS < <(echo */fuzz.c | sed 's@/fuzz.c@@g')
10
11 usage()
12 {
13         cat << EOF
14 Usage: $0 [OPTION]... FUZZ_TARGET
15
16 Fuzz wimlib with LLVM's libFuzzer.
17
18 Options:
19    --asan          Enable AddressSanitizer
20    --input=INPUT   Test a single input file only
21    --max-len=LEN   Maximum length of generated inputs (default: $MAX_LEN)
22    --msan          Enable MemorySanitizer
23    --time=SECONDS  Stop after the given time has passed
24    --ubsan         Enable UndefinedBehaviorSanitizer
25
26 Available fuzz targets: ${AVAILABLE_TARGETS[*]}
27 EOF
28 }
29
30 die()
31 {
32         echo "$*" 1>&2
33         exit 1
34 }
35
36 run_cmd()
37 {
38         echo "$*"
39         "$@"
40 }
41
42 EXTRA_SANITIZERS=
43 EXTRA_FUZZER_ARGS=()
44 INPUT=
45 MAX_LEN=32768
46
47 longopts_array=(
48 asan
49 help
50 input:
51 max-len:
52 msan
53 time:
54 ubsan
55 )
56 longopts=$(echo "${longopts_array[@]}" | tr ' ' ',')
57
58 if ! options=$(getopt -o "" -l "$longopts" -- "$@"); then
59         usage 1>&2
60         exit 1
61 fi
62 eval set -- "$options"
63 while true; do
64         case "$1" in
65         --asan)
66                 EXTRA_SANITIZERS+=",address"
67                 ;;
68         --help)
69                 usage
70                 exit 0
71                 ;;
72         --input)
73                 INPUT=$2
74                 shift
75                 ;;
76         --max-len)
77                 MAX_LEN=$2
78                 shift
79                 ;;
80         --msan)
81                 EXTRA_SANITIZERS+=",memory"
82                 ;;
83         --time)
84                 EXTRA_FUZZER_ARGS+=("-max_total_time=$2")
85                 shift
86                 ;;
87         --ubsan)
88                 EXTRA_SANITIZERS+=",undefined"
89                 ;;
90         --)
91                 shift
92                 break
93                 ;;
94         *)
95                 echo 1>&2 "Invalid option '$1'"
96                 usage 1>&2
97                 exit 1
98         esac
99         shift
100 done
101 EXTRA_FUZZER_ARGS+=("-max_len=$MAX_LEN")
102
103 if (( $# != 1 )); then
104         echo 1>&2 "No fuzz target specified!"
105         usage 1>&2
106         exit 1
107 fi
108 TARGET=$1
109 if [ ! -e "$TARGET/fuzz.c" ]; then
110         echo 1>&2 "'$TARGET' is not a valid fuzz target!"
111         usage 1>&2
112         exit 1
113 fi
114 cd "$TOPDIR"
115 cflags="-g -O1 -Wall -Werror"
116 cflags+=" -fsanitize=fuzzer-no-link$EXTRA_SANITIZERS"
117 if [ -n "$EXTRA_SANITIZERS" ]; then
118         cflags+=" -fno-sanitize-recover=${EXTRA_SANITIZERS#,}"
119 fi
120 if ! [ -e config.log ] || ! grep -q -- "'CFLAGS=$cflags'" config.log; then
121         run_cmd ./configure --enable-test-support --without-fuse --without-ntfs-3g \
122                 CC=clang CFLAGS="$cflags"
123 fi
124 run_cmd make "-j$(getconf _NPROCESSORS_ONLN)"
125 cd "$SCRIPTDIR"
126 if [ -n "$INPUT" ]; then
127         run_cmd clang -g -O1 -fsanitize=fuzzer-no-link$EXTRA_SANITIZERS -Wall -Werror \
128                 -I "$TOPDIR/include" "$TARGET/fuzz.c" test-one-input.c fault-injection.c \
129                 "$TOPDIR/.libs/libwim.a" -o test-one-input
130         run_cmd ./test-one-input "$INPUT"
131 else
132         run_cmd clang -g -O1 -fsanitize=fuzzer$EXTRA_SANITIZERS -Wall -Werror \
133                 -I "$TOPDIR/include" "$TARGET/fuzz.c" fault-injection.c \
134                 "$TOPDIR/.libs/libwim.a" -o "$TARGET/fuzz"
135         run_cmd "$TARGET/fuzz" "${EXTRA_FUZZER_ARGS[@]}" "$TARGET/corpus"
136 fi