1#!/usr/bin/env bash 2 3usage () 4{ 5test_ids=$(echo "${llvm_all_ids[*]}" | sed 's/ /, /g') 6cat << EOF 7usage: $0 options 8options: 9 -h Help 10 -l, --llvm <n> Use llvm fuzz tests and run n times 0=just build, -1=skip (default $use_llvm). 11 -a, --afl <n> Use AFL fuzz tests and run n times 0=just build, -1=skip (default $use_afl). 12 -t, --time <n> Run each group of max time <n>[s,h,m,d] - n seconds, hours, minutes or days. 13 -e <exec|rand|all> Run a specific llvm test or [$test_ids, rand, all]. 14 -f <file> Use this file as initial raw input. Can be repeated. 15 -d <0,1> Use dump of internal inflate test corpus (default $use_internal_corp). 16 -i <dir> Fuzz input dir (default $fuzzin_dir). 17 -o <dir> Fuzz output dir (default $fuzzout_dir). 18EOF 19exit 0 20} 21 22# Defaults 23use_afl=-1 24use_llvm=1 25samp_files= 26use_internal_corp=0 27fuzzin_dir=fuzzin 28fuzzout_dir=fuzzout 29llvm_opts=" -print_final_stats=1" 30afl_timeout_cmd="" 31run_secs=0 32llvm_tests=("igzip_simple_inflate_fuzz_test") 33llvm_all_ids=("simple" "checked" "round_trip") 34llvm_all_tests=("igzip_simple_inflate_fuzz_test" "igzip_checked_inflate_fuzz_test" "igzip_simple_round_trip_fuzz_test") 35 36# Options 37while [ "$1" != "${1##-}" ]; do 38 case $1 in 39 -h | --help) 40 usage 41 ;; 42 -t | --time) 43 run_secs=$(echo $2 | sed -e 's/d$/*24h/' -e 's/h$/*60m/' -e 's/m$/*60/' -e 's/s$//'| bc) 44 llvm_opts+=" -max_total_time=$run_secs" 45 afl_timeout_cmd="timeout --preserve-status $run_secs" 46 echo Run each for $run_secs seconds 47 shift 2 48 ;; 49 -a | --afl) 50 use_afl=$2 51 shift 2 52 ;; 53 -l | --llvm) 54 use_llvm=$2 55 shift 2 56 ;; 57 -f) 58 samp_files+="$2 " 59 use_internal_corp=0 60 shift 2 61 ;; 62 -d) 63 use_internal_corp=$2 64 shift 2 65 ;; 66 -e) 67 case $2 in 68 all) 69 llvm_tests=${llvm_all_tests[@]} 70 ;; 71 rand) 72 llvm_tests=${llvm_all_tests[$RANDOM % ${#llvm_all_tests[@]} ]} 73 ;; 74 *) 75 flag=0 76 for id_index in "${!llvm_all_ids[@]}"; do 77 if [[ "${llvm_all_ids[$id_index]}" = "$2" ]]; then 78 flag=1 79 llvm_tests[0]="${llvm_all_tests[$id_index]}" 80 break; 81 fi 82 done 83 84 if [ $flag -eq 0 ]; then 85 test_ids=$(echo "${llvm_all_ids[*]}" | sed 's/ /, /g') 86 echo "Invalid test, valid options: $test_ids, rand, or all" 87 exit 0 88 fi 89 ;; 90 esac 91 shift 2 92 ;; 93 -i) 94 fuzzin_dir=$2 95 shift 2 96 ;; 97 -o) 98 fuzzout_dir=$2 99 shift 2 100 ;; 101 esac 102done 103 104set -xe #exit on fail 105 106# Optionally build afl fuzz tests 107if [ $use_afl -ge 0 ]; then 108 echo Build afl fuzz tests 109 if ! command -V afl-gcc > /dev/null; then 110 echo $0 option --afl requires package afl installed 111 exit 0 112 fi 113 make -f Makefile.unx clean 114 make -f Makefile.unx units=igzip CC=afl-gcc other 115fi 116 117# Optionally build llvm fuzz tests 118if [ $use_llvm -ge 0 ]; then 119 echo Build llvm fuzz tests 120 if ( command -V clang++ > /dev/null ); then 121 if (echo int LLVMFuzzerTestOneInput\(\)\{return 0\;\} | clang++ -x c - -fsanitize=fuzzer,address -lpthread -o /dev/null >& /dev/null); then 122 echo have modern clang 123 llvm_link_args='FUZZLINK=-fsanitize=fuzzer,address' 124 elif (echo int LLVMFuzzerTestOneInput\(\)\{return 0\;\} | clang++ -x c - -lFuzzer -lpthread -o /dev/null >& /dev/null); then 125 echo have libFuzzer 126 llvm_link_args='FUZZLINK=-lFuzzer' 127 else 128 echo $0 option --llvm requires clang++ and libFuzzer 129 exit 0 130 fi 131 fi 132 rm -rf bin 133 make -f Makefile.unx units=igzip llvm_fuzz_tests igzip_dump_inflate_corpus CC=clang CXX=clang++ ${llvm_link_args} 134fi 135 136#Create fuzz input/output directories 137mkdir -p $fuzzin_dir 138if [ $use_afl -ge 0 ]; then 139 mkdir -p $fuzzout_dir 140fi 141 142# Optionally fill fuzz input with internal tests corpus 143[ $use_internal_corp -gt 0 ] && ./igzip_dump_inflate_corpus $fuzzin_dir 144 145# Optionally compress input samples as input into fuzz dir 146for f in $samp_files; do 147 echo Using sample file $f 148 f_base=`basename $f` 149 ./igzip_file_perf $f -o $fuzzin_dir/samp_${f_base}_cmp 150done 151 152# Optionally run tests alternately one after the other 153while [ $use_llvm -gt 0 -o $use_afl -gt 0 ]; do 154 if [ $use_afl -gt 0 ]; then 155 echo afl run $use_afl 156 let use_afl-- 157 $afl_timeout_cmd afl-fuzz -T "Run inflate $run_secs s" -i $fuzzin_dir -o $fuzzout_dir -M fuzzer1 -- ./igzip_fuzz_inflate @@ 158 afl-whatsup $fuzzout_dir 159 fi 160 161 if [ $use_llvm -gt 0 ]; then 162 echo llvm run $use_llvm 163 let use_llvm-- 164 for test in $llvm_tests; do 165 echo "Run llvm test $test" 166 ./$test $fuzzin_dir $llvm_opts 167 done 168 fi 169done 170 171make -f Makefile.unx clean 172