scripts: improve afl-fuzz support

Add a proper script which builds the fuzzed programs and runs the
fuzzer.  Also make all compression levels get fuzzed.
This commit is contained in:
Eric Biggers 2021-12-31 12:14:01 -06:00
parent eafe829b4d
commit 804c6c74f6
5 changed files with 158 additions and 17 deletions

1
scripts/afl-fuzz/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
*/fuzz

View File

@ -1,7 +1,6 @@
SRC := $(wildcard */*.c)
EXE := $(SRC:.c=)
CFLAGS := -O2 -s
LDLIBS := -ldeflate
LDFLAGS := -L../..
CPPFLAGS := -I../..

View File

@ -12,15 +12,22 @@ int main(int argc, char **argv)
int ret;
int fd = open(argv[1], O_RDONLY);
struct stat stbuf;
unsigned char level;
assert(fd >= 0);
ret = fstat(fd, &stbuf);
assert(!ret);
char in[stbuf.st_size];
if (stbuf.st_size == 0)
return 0;
ret = read(fd, &level, 1);
assert(ret == 1);
level %= 13;
char in[stbuf.st_size - 1];
ret = read(fd, in, sizeof in);
assert(ret == sizeof in);
c = libdeflate_alloc_compressor(6);
c = libdeflate_alloc_compressor(level);
d = libdeflate_alloc_decompressor();
char out[sizeof(in)];

148
scripts/afl-fuzz/fuzz.sh Executable file
View File

@ -0,0 +1,148 @@
#!/bin/bash
set -e -u -o pipefail
cd "$(dirname "$0")"
read -r -a AVAILABLE_TARGETS < <(echo */fuzz.c | sed 's@/fuzz.c@@g')
usage()
{
cat << EOF
Usage: $0 [OPTION]... [TARGET]...
Fuzz libdeflate with afl-fuzz.
Options:
--asan Enable AddressSanitizer
--no-resume Don't resume existing afl-fuzz session; start a new one
--ubsan Enable UndefinedBehaviorSanitizer
Available targets: ${AVAILABLE_TARGETS[*]}
EOF
}
die()
{
echo "$*" 1>&2
exit 1
}
asan=false
ubsan=false
may_resume=true
longopts_array=(
asan
help
no-resume
ubsan
)
longopts=$(echo "${longopts_array[@]}" | tr ' ' ',')
if ! options=$(getopt -o "" -l "$longopts" -- "$@"); then
usage 1>&2
exit 1
fi
eval set -- "$options"
while (( $# >= 0 )); do
case "$1" in
--asan)
asan=true
;;
--help)
usage
exit 0
;;
--no-resume)
may_resume=false
;;
--ubsan)
ubsan=true
;;
--)
shift
break
;;
*)
echo 1>&2 "Invalid option: \"$1\""
usage 1>&2
exit 1
esac
shift
done
if $asan && $ubsan; then
die "--asan and --ubsan are mutually exclusive"
fi
if ! type -P afl-fuzz > /dev/null; then
die "afl-fuzz is not installed"
fi
if (( $# == 0 )); then
targets=("${AVAILABLE_TARGETS[@]}")
else
for target; do
found=false
for t in "${AVAILABLE_TARGETS[@]}"; do
if [ "$target" = "$t" ]; then
found=true
fi
done
if ! $found; then
echo 1>&2 "Unknown target '$target'"
echo 1>&2 "Available targets: ${AVAILABLE_TARGETS[*]}"
exit 1
fi
done
targets=("$@")
fi
if (( ${#targets[@]} > 1 )) && ! type -P urxvt > /dev/null; then
die "urxvt is not installed"
fi
afl_opts=""
if $asan; then
export AFL_USE_ASAN=1
export CFLAGS="-O2 -m32"
export CC=afl-clang
afl_opts+=" -m 800"
elif $ubsan; then
export CFLAGS="-fsanitize=undefined -fno-sanitize-recover=undefined"
export CC=afl-gcc
else
export AFL_HARDEN=1
export CFLAGS="-O2"
export CC=afl-clang-fast
fi
sudo sh -c "echo core > /proc/sys/kernel/core_pattern"
sudo sh -c "echo performance | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor"
NPROC=$(getconf _NPROCESSORS_ONLN)
make "-j$NPROC" -C ../../ libdeflate.a
make "-j$NPROC" -B
for dir in "${targets[@]}"; do
cp -vaT "$dir" "/tmp/$dir"
indir=/tmp/$dir/inputs
outdir=/tmp/$dir/outputs
if [ -e "$outdir" ]; then
if $may_resume; then
indir="-"
else
rm -rf "${outdir:?}"/*
fi
else
mkdir "$outdir"
fi
cmd="afl-fuzz -i $indir -o $outdir -T $dir $afl_opts -- /tmp/$dir/fuzz @@"
if (( ${#targets[@]} > 1 )); then
urxvt -e bash -c "$cmd" &
else
$cmd
fi
done
wait

View File

@ -1,14 +0,0 @@
#!/bin/sh
set -e
make -C ../../ clean
make clean
AFL_HARDEN=1 make CC=afl-gcc -C ../../
AFL_HARDEN=1 make CC=afl-gcc
for dir in $(find . -mindepth 1 -maxdepth 1 -type d); do
rm -rf /tmp/$dir
cp -va $dir /tmp/$dir
mkdir -p /tmp/$dir/outputs
done