Skip to content

fix: v5→v6 migration hang on large page_count (fuzz timeout #272) - #272

Merged
adityamukho merged 1 commit into
mainfrom
fix/fuzz-v5-migration-next-free
May 18, 2026
Merged

adityamukho merged 1 commit into
mainfrom
fix/fuzz-v5-migration-next-free

Conversation

@adityamukho

Copy link
Copy Markdown
Collaborator

Root cause

The file_header fuzz target produced this timeout artifact:

[77,71,82,70, 5,0,0,0, 214,214,214,214,0,0,0,0, ..., 61,0,..., 32,...]
 MGRF         version=5  page_count=3,604,123,350          vaet_root=61

In migrate_v5_to_v6 (line 721):

let next_free = header.page_count;  // 3,604,123,350

build_btree wrote a leaf page at offset 3,604,123,350 × 4096 ≈ 14 TB in a sparse file. Then compute_page_checksum looped over 3.6 billion pages — each read_exact returned zeros (sparse regions, no EOF error) — hanging the process and triggering libFuzzer's 60-second per-execution timeout.

Fix

Replace the untrusted header.page_count with the actual end of fact data:

let next_free = 1u64.checked_add(validated_num_fact_pages)?;

save() already uses this pattern correctly (index_start = 1 + new_total_fact_pages); this brings migrate_v5_to_v6 in line.

Changes

  • Fix migrate_v5_to_v6: use 1 + validated_num_fact_pages as B-tree start
  • Add regression test reproducing the exact fuzz artifact
  • Add seed_v5_large_page_count.bin to the file_header corpus

Test plan

  • cargo test test_v5_migration_large_page_count_does_not_hang passes
  • All 962 tests pass
  • Re-run fuzz file_header target manually after merge to confirm no timeout

🤖 Generated with Claude Code

…hang

When migrating a v5 file whose header.page_count is a large fuzz-crafted
value (e.g. 3,604,123,350), migrate_v5_to_v6 passed that value as the
start page for build_btree.  build_btree then wrote a leaf at a ~14 TB
offset in a sparse file, and compute_page_checksum looped over 3.6 billion
zero-filled sparse pages (read_exact returns zeros on sparse regions —
no error), hanging the process and triggering libFuzzer's 60-second
per-execution timeout.

Fix: derive next_free from the actual number of validated fact pages
(1 + validated_num_fact_pages) instead of from the untrusted header field.

Adds a regression test reproducing the exact fuzz artifact bytes, and
adds seed_v5_large_page_count.bin to the file_header corpus so this
class of input is exercised on every future fuzz run.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@codecov

codecov Bot commented May 18, 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 0a3a923 into main May 18, 2026
15 checks passed
@adityamukho
adityamukho deleted the fix/fuzz-v5-migration-next-free branch May 18, 2026 15:23
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