8000 fuzz: v8 page targets that reach their decoders; keep the corpus between runs (#387, #375) by adityamukho · Pull Request #498 · project-minigraf/minigraf · GitHub
[go: up one dir, main page]

Skip to content

fuzz: v8 page targets that reach their decoders; keep the corpus between runs (#387, #375) - #498

Merged
adityamukho merged 1 commit into
v3from
fuzz/387-corpus-and-page-targets
Oct 9, 2026
Merged

adityamukho merged 1 commit into
v3from
fuzz/387-corpus-and-page-targets

Conversation

@adityamukho
Copy link
Copy Markdown
Collaborator

Refs #387, Refs #375 (tracker #383). PR A of two for #387; PR B adds the ops_sequence and corrupt_file targets. A workflow-only PR to main follows, because scheduled runs use main's copy of fuzz.yml.

Why

  • On v3, btree_page and fact_page still wrote the pre-release single-header layout and stopped at STG-032 on every input. file_header rarely got past the meta CRC. So v8 node, meta and v7-migration decoding got no fuzz coverage.
  • Nightly fuzzing only ever checked out main. v3 code has not been fuzzed at night.
  • The corpus was thrown away after every run.

What

Page targets (fuzz/fuzz_targets/common/mod.rs): a v8 template built through the public API (90 entities, a long value, a fact-level window, a retraction), rewritten with LogWriter at fixed tx times. Its bytes and the seeds cut from it are therefore the same in every process. One batch means every tree page is reachable and nothing is freed. A target overwrites one page and recomputes that page's CRC (crc32fast, per spec §4), so the input reaches the decoder:

Target Fuzzes
btree_page any leaf or internal node of the five trees, optionally with its type flipped; read-only or read-write (#375)
file_header either meta slot, with or without a matching CRC, with or without the other slot, whole page or fields only
fact_page fact page 1 of tests/golden/v7_basic.graph, through migration or the read-only load

Each run executes one input-chosen probe: a query over EAVT, AEVT, AVET, VAET, the DICT, :valid-at or :as-of, or verify(). With all of them on every input, the targets managed only ~8 exec/s under ASan.

Workflows (identical on main and v3):

  • fuzz.yml: two crons, main at 04:00 and v3 at 16:00, like bench.yml/crash-kill.yml. A targets job reads the branch's [[bin]] list, each target fuzzes in its own parallel job (wall time ~1 h instead of ~5.5 h), and the corpus is restored from and saved to actions/cache per branch and target. -timeout=60 catches a hang quickly instead of after libFuzzer's default 1200 s. Failures go to "Nightly fuzz failure ()".
  • fuzz-corpus.yml: weekly cargo fuzz cmin per target. It keeps every committed seed_* file, saves the result to the cache, and force-pushes bot/fuzz-corpus-<branch>, then opens or updates a PR. The repository setting "Allow GitHub Actions to create and approve pull requests" is off. Until it is turned on, the job pushes the branch and puts a compare link in the job summary.

Spec: docs/superpowers/specs/2026-10-09-fuzz-corpus-and-ops-target-design.md. Plan: docs/superpowers/plans/2026-10-09-fuzz-corpus-and-page-targets.md.

Verification

Findings (filed, not fixed here)

No library code changes. The fuzz crate is not part of the published package.

🤖 Generated with Claude Code

https://claude.ai/code/session_012wXxZguv7PgKQjMMH4yJ5h

…een runs (#387, #375)

On v3, btree_page and fact_page still wrote the pre-release single-header
layout and stopped at STG-032 on every input; file_header rarely got past the
meta CRC. The page targets now start from a v8 file built through the public
API and rewritten with LogWriter at fixed tx times, so its bytes and the seeds
cut from it are the same in every process. A target overwrites one page with
the input and recomputes that page's checksum, so the input reaches the
decoder:

- btree_page: any leaf or internal node of the five trees (#375)
- file_header: either meta slot, with or without a matching CRC
- fact_page: the fact page of a v7 golden file, migrated or loaded read-only

Each run executes one input-chosen probe query or verify(), which keeps
executions fast under ASan.

The nightly workflow runs every target in its own parallel job, on main and v3
on alternating crons (scheduled runs use main's copy of the file), and keeps
each target's corpus in the Actions cache. fuzz-corpus.yml minimizes the
cached corpus weekly, keeps committed seed_* files, and proposes it as a pull
request.

The new targets found #496 (a v7 fact page with a damaged type byte is
dropped by migration) and #497 (open trusts the meta page_count).

Refs #387
Refs #375

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012wXxZguv7PgKQjMMH4yJ5h
@codecov
codecov Bot commented Oct 9, 2026
Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@adityamukho
adityamukho merged commit abada1a into v3 Oct 9, 2026
30 of 32 checks passed
@adityamukho
adityamukho deleted the fuzz/387-corpus-and-page-targets branch October 9, 2026 12:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

0