Skip to content

Commit d8ff11f

Browse files
committed
fuzz: improve iteration scaling, add minimization and summary table
Replace the fixed 30s run_time with iteration counts scaled to 8x corpus size (plus a 1000 baseline) with a 10-minute hard cap per target. This ensures the full corpus is replayed with room for mutations, while small targets finish quickly. On main (and on PRs with the fuzz-minimize label), run honggfuzz corpus minimization after each target to prune inputs that don't contribute unique coverage, keeping the cache size manageable. Print a summary table at the end with per-target stats: iterations, corpus sizes before/after fuzzing and minimization, and run times. Other changes: - Use -q (quiet) to suppress per-iteration status output - Set 3s per-input timeout (-t 3) for all targets - Pass FUZZ_MINIMIZE env var from PR label in workflow - Check for crashes after minimization, not just after fuzzing AI tools were used in preparing this commit.
1 parent d86297e commit d8ff11f

2 files changed

Lines changed: 71 additions & 7 deletions

File tree

.github/workflows/build.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,8 @@ jobs:
255255
fuzz-corpus-refs/heads/main-
256256
- name: Run fuzzers
257257
run: cd fuzz && ./ci-fuzz.sh && cd ..
258+
env:
259+
FUZZ_MINIMIZE: ${{ contains(github.event.pull_request.labels.*.name, 'fuzz-minimize') }}
258260
- name: Upload honggfuzz corpus
259261
uses: actions/upload-artifact@v4
260262
with:

fuzz/ci-fuzz.sh

Lines changed: 69 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,20 +30,82 @@ sed -i 's/lto = true//' Cargo.toml
3030
export HFUZZ_BUILD_ARGS="--features honggfuzz_fuzz"
3131

3232
cargo --color always hfuzz build -j8
33+
34+
SUMMARY=""
35+
36+
check_crash() {
37+
local FILE=$1
38+
if [ -f "hfuzz_workspace/$FILE/HONGGFUZZ.REPORT.TXT" ]; then
39+
cat "hfuzz_workspace/$FILE/HONGGFUZZ.REPORT.TXT"
40+
for CASE in "hfuzz_workspace/$FILE"/SIG*; do
41+
cat "$CASE" | xxd -p
42+
done
43+
exit 1
44+
fi
45+
}
46+
3347
for TARGET in src/bin/*.rs; do
3448
FILENAME=$(basename $TARGET)
3549
FILE="${FILENAME%.*}"
36-
HFUZZ_RUN_ARGS="--exit_upon_crash -v -n8 --run_time 30"
50+
CORPUS_DIR="hfuzz_workspace/$FILE/input"
51+
CORPUS_COUNT=$(find "$CORPUS_DIR" -type f 2>/dev/null | wc -l)
52+
# Run 8x the corpus size plus a baseline, ensuring full corpus replay
53+
# with room for new mutations. The 10-minute hard cap (--run_time 600)
54+
# prevents slow-per-iteration targets from running too long.
55+
ITERATIONS=$((CORPUS_COUNT * 8 + 1000))
56+
HFUZZ_RUN_ARGS="--exit_upon_crash -q -n8 -t 3 -N $ITERATIONS --run_time 600"
3757
if [ "$FILE" = "chanmon_consistency_target" -o "$FILE" = "fs_store_target" ]; then
3858
HFUZZ_RUN_ARGS="$HFUZZ_RUN_ARGS -F 64"
3959
fi
4060
export HFUZZ_RUN_ARGS
61+
FUZZ_START=$(date +%s)
4162
cargo --color always hfuzz run $FILE
42-
if [ -f hfuzz_workspace/$FILE/HONGGFUZZ.REPORT.TXT ]; then
43-
cat hfuzz_workspace/$FILE/HONGGFUZZ.REPORT.TXT
44-
for CASE in hfuzz_workspace/$FILE/SIG*; do
45-
cat $CASE | xxd -p
46-
done
47-
exit 1
63+
FUZZ_END=$(date +%s)
64+
FUZZ_TIME=$((FUZZ_END - FUZZ_START))
65+
FUZZ_CORPUS_COUNT=$(find "$CORPUS_DIR" -type f 2>/dev/null | wc -l)
66+
check_crash "$FILE"
67+
if [ "$GITHUB_REF" = "refs/heads/main" ] || [ "$FUZZ_MINIMIZE" = "true" ]; then
68+
HFUZZ_RUN_ARGS="-M -q -n8 -t 3"
69+
export HFUZZ_RUN_ARGS
70+
MIN_START=$(date +%s)
71+
cargo --color always hfuzz run $FILE
72+
MIN_END=$(date +%s)
73+
MIN_TIME=$((MIN_END - MIN_START))
74+
MIN_CORPUS_COUNT=$(find "$CORPUS_DIR" -type f 2>/dev/null | wc -l)
75+
check_crash "$FILE"
76+
SUMMARY="${SUMMARY}${FILE}|${ITERATIONS}|${CORPUS_COUNT}|${FUZZ_CORPUS_COUNT}|${FUZZ_TIME}|${MIN_CORPUS_COUNT}|${MIN_TIME}\n"
77+
else
78+
SUMMARY="${SUMMARY}${FILE}|${ITERATIONS}|${CORPUS_COUNT}|${FUZZ_CORPUS_COUNT}|${FUZZ_TIME}|-|-\n"
79+
fi
80+
done
81+
82+
fmt_time() {
83+
local secs=$1
84+
local m=$((secs / 60))
85+
local s=$((secs % 60))
86+
if [ "$m" -gt 0 ]; then
87+
printf "%dm %ds" "$m" "$s"
88+
else
89+
printf "%ds" "$s"
90+
fi
91+
}
92+
93+
# Print summary table
94+
set +x
95+
echo ""
96+
echo "==== Fuzz Summary ===="
97+
HDR="%-40s %7s %7s %-15s %9s %-15s %9s\n"
98+
FMT="%-40s %7s %7s %6s %-9s %9s %6s %-9s %9s\n"
99+
printf "$HDR" "Target" "Iters" "Corpus" " Fuzzed" "Fuzz time" " Minimized" "Min. time"
100+
printf "$HDR" "------" "-----" "------" "---------------" "---------" "---------------" "---------"
101+
echo -e "$SUMMARY" | while IFS='|' read -r name iters orig fuzzed ftime minimized mtime; do
102+
[ -z "$name" ] && continue
103+
fuzz_delta=$((fuzzed - orig))
104+
if [ "$minimized" = "-" ]; then
105+
printf "$FMT" "$name" "$iters" "$orig" "$fuzzed" "(+$fuzz_delta)" "$(fmt_time "$ftime")" "-" "" "-"
106+
else
107+
min_delta=$((minimized - fuzzed))
108+
printf "$FMT" "$name" "$iters" "$orig" "$fuzzed" "(+$fuzz_delta)" "$(fmt_time "$ftime")" "$minimized" "($min_delta)" "$(fmt_time "$mtime")"
48109
fi
49110
done
111+
echo "======================"

0 commit comments

Comments
 (0)