diff --git a/.gitignore b/.gitignore index 2ccfc05f..6055dd86 100644 --- a/.gitignore +++ b/.gitignore @@ -16,7 +16,5 @@ hashes/target bitcoin/dep_test # Fuzz artifacts -bitcoin/fuzz/hfuzz_target -bitcoin/fuzz/hfuzz_workspace -hashes/fuzz/hfuzz_target -hashes/fuzz/hfuzz_workspace +hfuzz_target +hfuzz_workspace diff --git a/fuzz/cycle.sh b/fuzz/cycle.sh index 80bdddf6..d33857c3 100755 --- a/fuzz/cycle.sh +++ b/fuzz/cycle.sh @@ -1,23 +1,26 @@ -#!/bin/bash +#!/usr/bin/env bash # Continuosly cycle over fuzz targets running each for 1 hour. # It uses chrt SCHED_IDLE so that other process takes priority. # # For hfuzz options see https://github.com/google/honggfuzz/blob/master/docs/USAGE.md -export HFUZZ_BUILD_ARGS='--features honggfuzz_fuzz' +set -e +REPO_DIR=$(git rev-parse --show-toplevel) +# shellcheck source=./fuzz-util.sh +source "$REPO_DIR/fuzz/fuzz-util.sh" +export HFUZZ_BUILD_ARGS='--features honggfuzz_fuzz' while : do - for FILE in fuzz_targets/*; - do - TARGET=$(echo $FILE | cut -c 14- | cut -f 1 -d '.') + for targetFile in $(listTargetFiles); do + targetName=$(targetFileToName "$targetFile") + echo "Fuzzing target $targetName ($targetFile)" # fuzz for one hour - HFUZZ_RUN_ARGS='--run_time 3600' chrt -i 0 cargo hfuzz run $TARGET - + HFUZZ_RUN_ARGS='--run_time 3600' chrt -i 0 cargo hfuzz run "$targetName" # minimize the corpus - HFUZZ_RUN_ARGS="-i hfuzz_workspace/$TARGET/input/ -P -M" chrt -i 0 cargo hfuzz run $TARGET + HFUZZ_RUN_ARGS="-i hfuzz_workspace/$targetName/input/ -P -M" chrt -i 0 cargo hfuzz run "$targetName" done done diff --git a/fuzz/fuzz-util.sh b/fuzz/fuzz-util.sh index 284706fc..3402dd15 100755 --- a/fuzz/fuzz-util.sh +++ b/fuzz/fuzz-util.sh @@ -17,10 +17,36 @@ targetFileToName() { | sed 's/\//_/g' } +targetFileToHFuzzInputArg() { + baseName=$(basename "$1") + dirName="${baseName%.*}" + if [ -d "hfuzz_input/$dirName" ]; then + echo "HFUZZ_INPUT_ARGS=\"-f hfuzz_input/$FILE/input\"" + fi +} + listTargetNames() { for target in $(listTargetFiles); do targetFileToName "$target" done } +# Utility function to avoid CI failures on Windows +checkWindowsFiles() { + incorrectFilenames=$(find . -type f -name "*,*" -o -name "*:*" -o -name "*<*" -o -name "*>*" -o -name "*|*" -o -name "*\?*" -o -name "*\**" -o -name "*\"*" | wc -l) + if [ "$incorrectFilenames" -gt 0 ]; then + exit 2 + fi +} +# Checks whether a fuzz case output some report, and dumps it in hex +checkReport() { + reportFile="hfuzz_workspace/$1/HONGGFUZZ.REPORT.TXT" + if [ -f "$reportFile" ]; then + cat "$reportFile" + for CASE in "hfuzz_workspace/$1/SIG"*; do + xxd -p -c10000 < "$CASE" + done + exit 1 + fi +} diff --git a/fuzz/fuzz.sh b/fuzz/fuzz.sh index 1f75c9c0..3b9e2b22 100755 --- a/fuzz/fuzz.sh +++ b/fuzz/fuzz.sh @@ -1,17 +1,18 @@ -#!/bin/bash +#!/usr/bin/env bash set -e -# Check that input files are correct Windows file names -incorrectFilenames=$(find . -type f -name "*,*" -o -name "*:*" -o -name "*<*" -o -name "*>*" -o -name "*|*" -o -name "*\?*" -o -name "*\**" -o -name "*\"*" | wc -l) +REPO_DIR=$(git rev-parse --show-toplevel) -if [ ${incorrectFilenames} -gt 0 ]; then - exit 2 -fi +# shellcheck source=./fuzz-util.sh +source "$REPO_DIR/fuzz/fuzz-util.sh" + +# Check that input files are correct Windows file names +checkWindowsFiles if [ "$1" == "" ]; then - TARGETS=fuzz_targets/* + targetFiles="$(listTargetFiles)" else - TARGETS=fuzz_targets/"$1".rs + targetFiles=fuzz_targets/"$1".rs fi cargo --version @@ -19,20 +20,15 @@ rustc --version # Testing cargo install --force honggfuzz --no-default-features -for TARGET in $TARGETS; do - echo "Fuzzing target $TARGET" - FILENAME=$(basename $TARGET) - FILE="${FILENAME%.*}" - if [ -d hfuzz_input/$FILE ]; then - HFUZZ_INPUT_ARGS="-f hfuzz_input/$FILE/input" - fi - HFUZZ_BUILD_ARGS="--features honggfuzz_fuzz" HFUZZ_RUN_ARGS="--run_time 30 --exit_upon_crash -v $HFUZZ_INPUT_ARGS" cargo hfuzz run $FILE +for targetFile in $targetFiles; do + targetName=$(targetFileToName "$targetFile") + echo "Fuzzing target $targetName ($targetFile)" + if [ -d "hfuzz_input/$targetName" ]; then + HFUZZ_INPUT_ARGS="-f hfuzz_input/$targetName/input\"" + else + HFUZZ_INPUT_ARGS="" + fi + HFUZZ_BUILD_ARGS="--features honggfuzz_fuzz" HFUZZ_RUN_ARGS="--run_time 30 --exit_upon_crash -v $HFUZZ_INPUT_ARGS" cargo hfuzz run "$targetName" - if [ -f hfuzz_workspace/$FILE/HONGGFUZZ.REPORT.TXT ]; then - cat hfuzz_workspace/$FILE/HONGGFUZZ.REPORT.TXT - for CASE in hfuzz_workspace/$FILE/SIG*; do - cat $CASE | xxd -p - done - exit 1 - fi + checkReport "$targetName" done