Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 18 additions & 6 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,21 @@ jobs:
- name: Simulate docs.rs build
run: ci/check-docsrs.sh

fuzz_sanity:
runs-on: self-hosted
env:
TOOLCHAIN: 1.75
steps:
- name: Checkout source code
uses: actions/checkout@v4
- name: Install Rust ${{ env.TOOLCHAIN }} toolchain
run: |
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile=minimal --default-toolchain ${{ env.TOOLCHAIN }}
- name: Sanity check fuzz targets on Rust ${{ env.TOOLCHAIN }}
run: |
cd fuzz
RUSTFLAGS="--cfg=fuzzing --cfg=secp256k1_fuzz --cfg=hashes_fuzz" cargo test --quiet --color always --lib --bins -j8
fuzz:
runs-on: self-hosted
env:
Expand Down Expand Up @@ -238,13 +253,10 @@ jobs:
key: fuzz-corpus-refs/heads/main-${{ github.sha }}
restore-keys: |
fuzz-corpus-refs/heads/main-
- name: Sanity check fuzz targets on Rust ${{ env.TOOLCHAIN }}
run: |
cd fuzz
RUSTFLAGS="--cfg=fuzzing --cfg=secp256k1_fuzz --cfg=hashes_fuzz" cargo test --verbose --color always --lib --bins -j8
cargo clean
- name: Run fuzzers
run: cd fuzz && ./ci-fuzz.sh && cd ..
env:
FUZZ_MINIMIZE: ${{ contains(github.event.pull_request.labels.*.name, 'fuzz-minimize') }}
- name: Upload honggfuzz corpus
uses: actions/upload-artifact@v4
with:
Expand Down Expand Up @@ -308,7 +320,7 @@ jobs:
TOR_PROXY="127.0.0.1:9050" RUSTFLAGS="--cfg=tor" cargo test --verbose --color always -p lightning-net-tokio
notify-failure:
needs: [build-workspace, build-features, build-bindings, build-nostd, build-cfg-flags, build-sync, fuzz, linting, rustfmt, check_release, check_docs, benchmark, ext-test, tor-connect, coverage]
needs: [build-workspace, build-features, build-bindings, build-nostd, build-cfg-flags, build-sync, fuzz_sanity, fuzz, linting, rustfmt, check_release, check_docs, benchmark, ext-test, tor-connect, coverage]
if: failure() && github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
permissions:
Expand Down
52 changes: 51 additions & 1 deletion fuzz/ci-fuzz.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,70 @@ 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)
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
printf "%dm%ds" $((secs / 60)) $((secs % 60))
}

# 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 "======================"
Loading