Skip to content

deep-fuzz corpus restore keys off whole-run success — one target's crash starves all targets' corpus next night #100

Description

@joeldsouzax

Context

Surfaced during the #80 review (PR #99). Pre-existing behavior from #45 — affects both the deep-fuzz (libFuzzer) and deep-fuzz-afl (AFL++/CMPLOG) jobs in .github/workflows/fuzz.yml.

Problem

Each job's corpus-restore step resolves the previous corpus from the last successful whole workflow run:

run_id="$(gh run list --workflow fuzz.yml --branch main --status success --limit 1 --json databaseId --jq '.[0].databaseId // empty' ...)"

--status success reflects the aggregate conclusion of the entire matrixed run (both jobs × all targets). So if any single target in either job crashes (or the CMPLOG-confirm step fails, or a flake), the whole run is marked non-success — and the next night every target of every job fails to find a prior corpus artifact and reseeds from scratch (committed seeds + 1-byte fallback only).

Net effect: a single crash anywhere throws away the accumulated corpus for all targets on the following night. Corpus accumulation — the entire point of persisting artifacts night over night — is fragile to one unrelated failure.

Why it matters

Comparison-coverage fuzzing (value-profile + CMPLOG) depends on compounding corpus growth to reach deep parse states. A whole-fleet reseed erases that progress and wastes the runner budget re-discovering known-shallow inputs.

Possible fixes (not yet decided)

  • Resolve the run id per artifact existence rather than per-run success — e.g. find the most recent run (any conclusion) that actually uploaded corpus-<engine>-<target>, or query the artifacts API directly for the latest artifact of that name on main.
  • Or upload corpus on if: always() (like the AFL crash step) so a crashing target still persists its grown corpus for the next night, decoupling persistence from run success.
  • Consider retention-days interplay so a transient gap doesn't lose the artifact entirely.

Acceptance

  • A single target's crash/failure no longer starves the other targets' corpus restore on the following night.
  • Corpus continues to compound per-target across nights independent of unrelated failures.

Pointers

Metadata

Metadata

Assignees

No one assigned

    Labels

    testingTest harnesses, fuzzing, differential testing

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions