Zebra Coverage-Guided Fuzzing Infrastructure

M1 Month 1 — Coverage detail + disclosure follow-up

Two finer-grained pieces of evidence from the closed Month 1 window (2026-03-30 → 2026-04-30): a per-target coverage breakdown for the five fuzz harnesses, and a short coordinated-disclosure follow-up. M1 Month 2 (May) is the harden + ship window and is in progress; the M1 final delivery report will be posted ahead of the 2026-05-30 sign-off.


1. Coverage snapshot — 5 fuzz targets

Per-target line coverage at the close of Month 1, measured with cargo fuzz coverage against each target’s corpus and aggregated via llvm-cov report.

(Same data in text form for screen readers.)

Target Corpus files Key file Line coverage
block_deserialize 1,494 zebra-chain/src/block/serialize.rs 64.38%
block_deep_fuzz 353 zebra-chain/src/block/serialize.rs 64.38%
p2p_message_parse 283 zebra-network/src/protocol/external/codec.rs 32.85%
p2p_deep_fuzz 344 zebra-network/src/protocol/external/codec.rs 35.48%
addr_message_fuzz 16 zebra-network/src/protocol/external/addr/v1.rs corpus expansion in flight

Block deserialization — coverage on key zebra-chain files:

File Lines Line coverage
zebra-chain/src/transaction/serialize.rs 828 83.45%
zebra-chain/src/sapling/output.rs 123 83.74%
zebra-chain/src/orchard/action.rs 62 87.10%
zebra-chain/src/sapling/spend.rs 147 74.83%
zebra-chain/src/orchard/note/nullifiers.rs 22 77.27%
zebra-chain/src/serialization/compact_size.rs 116 81.03%
zebra-chain/src/serialization/zcash_deserialize.rs 106 57.55%
zebra-chain/src/serialization/zcash_serialize.rs 96 53.12%
zebra-chain/src/serialization/read_zcash.rs 36 50.00%
zebra-chain/src/block/serialize.rs 160 64.38%

A note on block/serialize.rs: the residual ~36% un-covered region is composed mostly of the CountedHeader serialize/deserialize impls (used by P2P “headers”-only messages, not on the block_deserialize fuzz path) and the SerializedBlock conversion impls (the serialize direction; this target only exercises deserialize). These regions are unreachable from Block::zcash_deserialize regardless of corpus or fuzz duration — they need a separate ser-direction target, which is a Month 2 hardening candidate.

The block target reaches deep into transaction-internal deserialization paths because mainnet blocks embed real V5 / V4 transactions. That’s why transaction/serialize.rs, sapling/output.rs, and orchard/action.rs all sit at 80%+ line coverage from the block target alone.


2. Coordinated disclosure update

While preparing M1 Month 2 work, we identified a panic in Zebra’s V6 transaction hash path that was reachable through a recently exercised code path. We submitted the report through the standard GitHub Security Advisory workflow on the Zebra repository. The Zebra Foundation security team triaged the report promptly, then converted it to a public tracking issue with High severity and the appropriate C-bug / S-needs-triage labels. We would like to thank @conradoplg and the Zebra Foundation security team for the rapid and constructive triage — initial submission to public tracking inside one working day.


3. Where this leaves M1 going into the final stretch

Month 2 is the consolidation window:

  • Hardening of the existing targets and corpus seeding for the queued candidates
  • Initial CI smoke scaffold (M2 deliverable preparation)
  • Upstream re-baselining
  • M1 final delivery report ahead of the 2026-05-30 sign-off

All scope and quality remain anchored to the proposal verbatim deliverables and acceptance criteria. Thanks again to ZCG, the Zebra Foundation, and the broader Zcash community for the support and the responsive coordination on disclosure.

2 Likes