Count symlinked fuzz corpus files
What changed, and why it matters
This commit fixes a bug in the project's automated fuzzing (stress-testing) script. Previously, the script counted test input files using a command that ignored symbolic links (shortcuts to other directories), so it could undercount the real corpus and run too few fuzzing iterations. The change makes the script follow symbolic links when counting files and aborts loudly if a linked corpus directory appears empty. This is a reliability/quality fix for internal testing infrastructure, not a vulnerability in the Lightning protocol code itself.
No urgent action required. Treat as a normal CI/test-harness improvement. Reviewers can verify that `find -L` behaves correctly on their CI symlink layout and that the new zero-file check does not break legitimate empty corpora that are not symlinks.
Security signals we found
Fixes fuzzing coverage/iteration miscounting caused by find not following symlinks
Adds explicit failure when a linked corpus resolves to zero files, preventing silent under-testing
Only affects CI fuzzing shell script; no changes to Rust protocol or cryptography code
Evidence from the diff
The patch modifies fuzz/ci-fuzz.sh. It replaces three plain find "$CORPUS_DIR" -type f calls with a new corpus_count() helper that uses find -L to follow symlinks. It also adds check_linked_corpus(), which exits with an error if the corpus directory is a symlink and resolves to zero files. This ensures the iteration budget (ITERATIONS=$((8 * CORPUS_COUNT + 4096))) reflects the actual number of seed inputs when CI links cloned corpus directories into hfuzz_workspace.
Changed components
fuzz/ci-fuzz.shInspect captured patch +21 / −3
diff --git a/fuzz/ci-fuzz.sh b/fuzz/ci-fuzz.sh
index 3fc206b..a9cb9b2 100755
--- a/fuzz/ci-fuzz.sh
+++ b/fuzz/ci-fuzz.sh
@@ -41,6 +41,23 @@ check_crash() {
fi
}
+corpus_count() {
+ local CORPUS_DIR=$1
+ # CI links cloned corpus directories into hfuzz_workspace.
+ find -L "$CORPUS_DIR" -type f 2>/dev/null | wc -l
+}
+
+check_linked_corpus() {
+ local CORPUS_DIR=$1
+ local FILE=$2
+ local CORPUS_COUNT=$3
+
+ if [ -L "$CORPUS_DIR" ] && [ "$CORPUS_COUNT" -eq 0 ]; then
+ echo "Linked corpus for $FILE has no visible input files: $CORPUS_DIR"
+ exit 1
+ fi
+}
+
run_targets() {
local CRATE_DIR=$1
local TARGET_RUSTFLAGS=$2
@@ -55,7 +72,8 @@ run_targets() {
FILENAME=$(basename "$TARGET")
FILE="${FILENAME%.*}"
CORPUS_DIR="$HFUZZ_WORKSPACE/$FILE/input"
- CORPUS_COUNT=$(find "$CORPUS_DIR" -type f 2>/dev/null | wc -l)
+ CORPUS_COUNT=$(corpus_count "$CORPUS_DIR")
+ check_linked_corpus "$CORPUS_DIR" "$FILE" "$CORPUS_COUNT"
# 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.
@@ -69,7 +87,7 @@ run_targets() {
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)
+ FUZZ_CORPUS_COUNT=$(corpus_count "$CORPUS_DIR")
check_crash "$HFUZZ_WORKSPACE" "$FILE"
if [ "$GITHUB_REF" = "refs/heads/main" ] || [ "$FUZZ_MINIMIZE" = "true" ]; then
HFUZZ_RUN_ARGS="-M -q -n8 -t 3"
@@ -78,7 +96,7 @@ run_targets() {
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)
+ MIN_CORPUS_COUNT=$(corpus_count "$CORPUS_DIR")
check_crash "$HFUZZ_WORKSPACE" "$FILE"
SUMMARY="${SUMMARY}${FILE}|${ITERATIONS}|${CORPUS_COUNT}|${FUZZ_CORPUS_COUNT}|${FUZZ_TIME}|${MIN_CORPUS_COUNT}|${MIN_TIME}\n"
else
Why this scored 18/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.