-
Notifications
You must be signed in to change notification settings - Fork 448
fuzz: improve CI iteration strategy, add corpus minimization and summary reporting #4497
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -30,20 +30,76 @@ sed -i 's/lto = true//' Cargo.toml | |||||||||||||||||||||||||||||||||||||||||||||
| export HFUZZ_BUILD_ARGS="--features honggfuzz_fuzz" | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| cargo --color always hfuzz build -j8 | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| SUMMARY="" | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| for TARGET in src/bin/*.rs; do | ||||||||||||||||||||||||||||||||||||||||||||||
| FILENAME=$(basename $TARGET) | ||||||||||||||||||||||||||||||||||||||||||||||
| FILE="${FILENAME%.*}" | ||||||||||||||||||||||||||||||||||||||||||||||
| HFUZZ_RUN_ARGS="--exit_upon_crash -v -n8 --run_time 30" | ||||||||||||||||||||||||||||||||||||||||||||||
| CORPUS_DIR="hfuzz_workspace/$FILE/input" | ||||||||||||||||||||||||||||||||||||||||||||||
| CORPUS_COUNT=$(find "$CORPUS_DIR" -type f 2>/dev/null | wc -l) | ||||||||||||||||||||||||||||||||||||||||||||||
| # Run 8x the corpus size plus a baseline, ensuring full corpus replay | ||||||||||||||||||||||||||||||||||||||||||||||
| # with room for new mutations. The 10-minute hard cap (--run_time 600) | ||||||||||||||||||||||||||||||||||||||||||||||
| # prevents slow-per-iteration targets from running too long. | ||||||||||||||||||||||||||||||||||||||||||||||
| ITERATIONS=$((CORPUS_COUNT * 8 + 1000)) | ||||||||||||||||||||||||||||||||||||||||||||||
| HFUZZ_RUN_ARGS="--exit_upon_crash -q -n8 -t 3 -N $ITERATIONS --run_time 600" | ||||||||||||||||||||||||||||||||||||||||||||||
| if [ "$FILE" = "chanmon_consistency_target" -o "$FILE" = "fs_store_target" ]; then | ||||||||||||||||||||||||||||||||||||||||||||||
| HFUZZ_RUN_ARGS="$HFUZZ_RUN_ARGS -F 64" | ||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||
| export HFUZZ_RUN_ARGS | ||||||||||||||||||||||||||||||||||||||||||||||
| FUZZ_START=$(date +%s) | ||||||||||||||||||||||||||||||||||||||||||||||
| cargo --color always hfuzz run $FILE | ||||||||||||||||||||||||||||||||||||||||||||||
| FUZZ_END=$(date +%s) | ||||||||||||||||||||||||||||||||||||||||||||||
| FUZZ_TIME=$((FUZZ_END - FUZZ_START)) | ||||||||||||||||||||||||||||||||||||||||||||||
| FUZZ_CORPUS_COUNT=$(find "$CORPUS_DIR" -type f 2>/dev/null | wc -l) | ||||||||||||||||||||||||||||||||||||||||||||||
| 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 | ||||||||||||||||||||||||||||||||||||||||||||||
| if [ "$GITHUB_REF" = "refs/heads/main" ] || [ "$FUZZ_MINIMIZE" = "true" ]; then | ||||||||||||||||||||||||||||||||||||||||||||||
| HFUZZ_RUN_ARGS="-M -q -n8 -t 3" | ||||||||||||||||||||||||||||||||||||||||||||||
| export HFUZZ_RUN_ARGS | ||||||||||||||||||||||||||||||||||||||||||||||
| MIN_START=$(date +%s) | ||||||||||||||||||||||||||||||||||||||||||||||
| cargo --color always hfuzz run $FILE | ||||||||||||||||||||||||||||||||||||||||||||||
| MIN_END=$(date +%s) | ||||||||||||||||||||||||||||||||||||||||||||||
| MIN_TIME=$((MIN_END - MIN_START)) | ||||||||||||||||||||||||||||||||||||||||||||||
| MIN_CORPUS_COUNT=$(find "$CORPUS_DIR" -type f 2>/dev/null | wc -l) | ||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+62
to
+69
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The crash check (lines 55-61) runs only after the fuzz step, but not after the minimization step here. Minimization still executes every corpus input through the target binary. If a crash occurs during minimization (e.g., a newly-mutated input from the fuzz step that was added to the corpus but didn't crash during fuzzing due to timing, or a non-deterministic crash), the Consider adding a crash check after the minimization run as well:
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||
| SUMMARY="${SUMMARY}${FILE}|${ITERATIONS}|${CORPUS_COUNT}|${FUZZ_CORPUS_COUNT}|${FUZZ_TIME}|${MIN_CORPUS_COUNT}|${MIN_TIME}\n" | ||||||||||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||||||||||
| SUMMARY="${SUMMARY}${FILE}|${ITERATIONS}|${CORPUS_COUNT}|${FUZZ_CORPUS_COUNT}|${FUZZ_TIME}|-|-\n" | ||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||
| done | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| fmt_time() { | ||||||||||||||||||||||||||||||||||||||||||||||
| local secs=$1 | ||||||||||||||||||||||||||||||||||||||||||||||
| local m=$((secs / 60)) | ||||||||||||||||||||||||||||||||||||||||||||||
| local s=$((secs % 60)) | ||||||||||||||||||||||||||||||||||||||||||||||
| if [ "$m" -gt 0 ]; then | ||||||||||||||||||||||||||||||||||||||||||||||
| printf "%dm %ds" "$m" "$s" | ||||||||||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||||||||||
| printf "%ds" "$s" | ||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| # Print summary table | ||||||||||||||||||||||||||||||||||||||||||||||
| set +x | ||||||||||||||||||||||||||||||||||||||||||||||
| echo "" | ||||||||||||||||||||||||||||||||||||||||||||||
| echo "==== Fuzz Summary ====" | ||||||||||||||||||||||||||||||||||||||||||||||
| HDR="%-40s %7s %7s %-15s %9s %-15s %9s\n" | ||||||||||||||||||||||||||||||||||||||||||||||
| FMT="%-40s %7s %7s %6s %-9s %9s %6s %-9s %9s\n" | ||||||||||||||||||||||||||||||||||||||||||||||
| printf "$HDR" "Target" "Iters" "Corpus" " Fuzzed" "Fuzz time" " Minimized" "Min. time" | ||||||||||||||||||||||||||||||||||||||||||||||
| printf "$HDR" "------" "-----" "------" "---------------" "---------" "---------------" "---------" | ||||||||||||||||||||||||||||||||||||||||||||||
| echo -e "$SUMMARY" | while IFS='|' read -r name iters orig fuzzed ftime minimized mtime; do | ||||||||||||||||||||||||||||||||||||||||||||||
| [ -z "$name" ] && continue | ||||||||||||||||||||||||||||||||||||||||||||||
| fuzz_delta=$((fuzzed - orig)) | ||||||||||||||||||||||||||||||||||||||||||||||
| if [ "$minimized" = "-" ]; then | ||||||||||||||||||||||||||||||||||||||||||||||
| printf "$FMT" "$name" "$iters" "$orig" "$fuzzed" "(+$fuzz_delta)" "$(fmt_time "$ftime")" "-" "" "-" | ||||||||||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||||||||||
| min_delta=$((minimized - fuzzed)) | ||||||||||||||||||||||||||||||||||||||||||||||
| printf "$FMT" "$name" "$iters" "$orig" "$fuzzed" "(+$fuzz_delta)" "$(fmt_time "$ftime")" "$minimized" "($min_delta)" "$(fmt_time "$mtime")" | ||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||
| done | ||||||||||||||||||||||||||||||||||||||||||||||
| echo "======================" | ||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why bother if we do this on
mainevery time anyway?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added it just for testing. Or maybe if a fuzz-affecting refactor PR is open for a long time and has accumulated a large corpus.
Can also remove the label trigger. Do you prefer that?