From 759e8cbd7e94c055c252ed62cc4331a54550cdc9 Mon Sep 17 00:00:00 2001 From: Ray Walker Date: Fri, 14 Aug 2026 20:56:12 +1000 Subject: [PATCH 1/4] fix(fuzz): commit per-target corpus seeds cargo-fuzz actually loads (LAB-1149) The fuzz corpus was buried by three stacked defects: the gitignore pattern corpus/*/ excluded every seed the generator produced; the committed CORPUS_INFO.md documented 1,758 seeds (6.9MB, 2025-11) that were not in the repo; and the generator wrote a category tree (byte_storage/, encryption/) that no [[bin]] target name matches, so cargo-fuzz could never have loaded those seeds even if committed. Every run cold-started from random bytes. - generate_corpus.sh: rewritten to write deterministic seeds into corpus// for all 14 targets, shaped per target input format. StorageEnvelope seeds are byte-exact against cachekit-core 0.4.0's wire format (raw LZ4 block, xxHash3-64 big-endian checksum, rmp-serde array form), verified against the crate's pinned empty-input checksum vector. - .gitignore: corpus is no longer ignored; comment states the actual policy. - CORPUS_INFO.md: describes the real tree; no volatile counts (live numbers come from validate_corpus.sh). - validate_corpus.sh: derives targets from Cargo.toml [[bin]] stanzas and FAILS when any target has no seeds or the corpus exceeds the 10MB budget. - minimize_corpus.sh: target list derived from Cargo.toml instead of a hand-maintained copy; a failed cmin now fails the script. - README.md: corpus sections match the per-target layout; stale Blake3 and FUZZ_TARGETS-list references corrected. - .pre-commit-config.yaml: corpus excluded from trailing-whitespace and end-of-file-fixer - appending a newline to a seed silently changes it. No CI change needed: cargo fuzz run defaults its corpus to fuzz/corpus/ , so fuzz-smoke.yml and security-deep.yml pick the seeds up as-is. Measured (60s, nightly-2026-04-27, -print_final_stats=1): - encryption_large_payload cold: cov 185, ft 194, max input len 53 bytes after 5,376 execs. Seeded (5 files found): ft 300, 256KB inputs from exec #6 - the target finally tests large payloads. - byte_storage_decompress cold: cov 2156, ft 3492. Seeded (14 files found): cov 2420, ft 4110 - valid-checksum envelopes unlock the post-decompression verify branches. --- .pre-commit-config.yaml | 5 + rust/fuzz/.gitignore | 9 +- rust/fuzz/README.md | 53 +- rust/fuzz/corpus/CORPUS_INFO.md | 113 ++-- .../compressible.bin | 1 + .../byte_storage_checksum_collision/large.bin | Bin 0 -> 1024 bytes .../medium.bin | Bin 0 -> 256 bytes .../byte_storage_checksum_collision/small.bin | 1 + .../byte_storage_compress/compressible.bin | 1 + .../empty.bin} | 0 .../corpus/byte_storage_compress/gradient.bin | Bin 0 -> 1024 bytes .../byte_storage_compress/random_1k.bin | Bin 0 -> 1024 bytes .../byte_storage_compress/single_byte.bin | 1 + .../corpus/byte_storage_compress/text.bin | 1 + .../corpus/byte_storage_compress/unicode.bin | 1 + .../corrupted_payload.bin | Bin 0 -> 43 bytes .../decompression_bomb.bin | Bin 0 -> 29 bytes .../empty_compressed.bin | Bin 0 -> 21 bytes .../invalid_msgpack.bin | 1 + .../map_form.bin | 1 + .../missing_fields.bin | 1 + .../size_mismatch.bin | 1 + .../truncated.bin | 1 + .../valid_compressible.bin | Bin 0 -> 43 bytes .../valid_gradient.bin | Bin 0 -> 297 bytes .../valid_random.bin | Bin 0 -> 1058 bytes .../valid_text.bin | 1 + .../valid_unicode_format.bin | 1 + .../wrong_checksum.bin | Bin 0 -> 76 bytes .../corrupted_payload.bin | Bin 0 -> 43 bytes .../decompression_bomb.bin | Bin 0 -> 29 bytes .../empty_compressed.bin | Bin 0 -> 21 bytes .../invalid_msgpack.bin | 1 + .../byte_storage_decompress/map_form.bin | 1 + .../missing_fields.bin | 1 + .../byte_storage_decompress/size_mismatch.bin | 1 + .../byte_storage_decompress/truncated.bin | 1 + .../valid_compressible.bin | Bin 0 -> 43 bytes .../valid_gradient.bin | Bin 0 -> 297 bytes .../byte_storage_decompress/valid_random.bin | Bin 0 -> 1058 bytes .../byte_storage_decompress/valid_text.bin | 1 + .../valid_unicode_format.bin | 1 + .../wrong_checksum.bin | Bin 0 -> 76 bytes .../byte_storage_empty_data/data_no_size.bin | Bin 0 -> 13 bytes .../corpus/byte_storage_empty_data/random.bin | 1 + .../byte_storage_empty_data/size_no_data.bin | Bin 0 -> 13 bytes .../corpus/byte_storage_empty_data/zeros.bin | Bin 0 -> 13 bytes .../byte_storage_format_injection/bom.bin | 1 + .../control_chars.bin | 2 + .../long_10k.bin | 1 + .../byte_storage_format_injection/normal.bin | 1 + .../null_byte.bin | Bin 0 -> 8 bytes .../path_traversal.bin | 1 + .../rtl_override.bin | 1 + .../boundary_512mb.bin | Bin 0 -> 14 bytes .../random_a.bin | 1 + .../random_b.bin | 1 + .../byte_storage_integer_overflow/u32_max.bin | 1 + .../byte_storage_integer_overflow/zeros.bin | Bin 0 -> 14 bytes .../encryption_aad_injection/key_128.bin | 1 + .../encryption_aad_injection/key_nulls.bin | Bin 0 -> 151 bytes .../encryption_aad_injection/key_random.bin | Bin 0 -> 1032 bytes .../corpus/encryption_key_derivation/bom.bin | 1 + .../empty_tenant.bin | 1 + .../encryption_key_derivation/long_tenant.bin | 1 + .../normal_tenant.bin | 1 + .../encryption_key_derivation/null_byte.bin | Bin 0 -> 27 bytes .../path_traversal.bin | 1 + .../encryption_key_derivation/unicode.bin | 1 + .../key_100k_random.bin | Bin 0 -> 102432 bytes .../key_16k_compressible.bin | 1 + .../encryption_large_payload/key_1k.bin | Bin 0 -> 1056 bytes .../key_256k_compressible.bin | 1 + .../encryption_large_payload/key_64k.bin | Bin 0 -> 65568 bytes .../corpus/encryption_nonce_reuse/key_64.bin | 1 + .../encryption_nonce_reuse/key_small.bin | 1 + .../encryption_roundtrip/key_compressible.bin | 1 + .../corpus/encryption_roundtrip/key_only.bin | 1 + .../encryption_roundtrip/key_random.bin | Bin 0 -> 288 bytes .../corpus/encryption_roundtrip/key_text.bin | 1 + .../key_200.bin | 1 + .../key_512.bin | Bin 0 -> 544 bytes .../key_min.bin | 1 + .../key_compressible.bin | 1 + .../key_random.bin | 1 + .../integration_layered_security/key_text.bin | 1 + rust/fuzz/scripts/generate_corpus.sh | 533 +++++++----------- rust/fuzz/scripts/minimize_corpus.sh | 46 +- rust/fuzz/scripts/validate_corpus.sh | 184 +++--- 89 files changed, 428 insertions(+), 565 deletions(-) create mode 100644 rust/fuzz/corpus/byte_storage_checksum_collision/compressible.bin create mode 100644 rust/fuzz/corpus/byte_storage_checksum_collision/large.bin create mode 100644 rust/fuzz/corpus/byte_storage_checksum_collision/medium.bin create mode 100644 rust/fuzz/corpus/byte_storage_checksum_collision/small.bin create mode 100644 rust/fuzz/corpus/byte_storage_compress/compressible.bin rename rust/fuzz/corpus/{.gitkeep => byte_storage_compress/empty.bin} (100%) create mode 100644 rust/fuzz/corpus/byte_storage_compress/gradient.bin create mode 100644 rust/fuzz/corpus/byte_storage_compress/random_1k.bin create mode 100644 rust/fuzz/corpus/byte_storage_compress/single_byte.bin create mode 100644 rust/fuzz/corpus/byte_storage_compress/text.bin create mode 100644 rust/fuzz/corpus/byte_storage_compress/unicode.bin create mode 100644 rust/fuzz/corpus/byte_storage_corrupted_envelope/corrupted_payload.bin create mode 100644 rust/fuzz/corpus/byte_storage_corrupted_envelope/decompression_bomb.bin create mode 100644 rust/fuzz/corpus/byte_storage_corrupted_envelope/empty_compressed.bin create mode 100644 rust/fuzz/corpus/byte_storage_corrupted_envelope/invalid_msgpack.bin create mode 100644 rust/fuzz/corpus/byte_storage_corrupted_envelope/map_form.bin create mode 100644 rust/fuzz/corpus/byte_storage_corrupted_envelope/missing_fields.bin create mode 100644 rust/fuzz/corpus/byte_storage_corrupted_envelope/size_mismatch.bin create mode 100644 rust/fuzz/corpus/byte_storage_corrupted_envelope/truncated.bin create mode 100644 rust/fuzz/corpus/byte_storage_corrupted_envelope/valid_compressible.bin create mode 100644 rust/fuzz/corpus/byte_storage_corrupted_envelope/valid_gradient.bin create mode 100644 rust/fuzz/corpus/byte_storage_corrupted_envelope/valid_random.bin create mode 100644 rust/fuzz/corpus/byte_storage_corrupted_envelope/valid_text.bin create mode 100644 rust/fuzz/corpus/byte_storage_corrupted_envelope/valid_unicode_format.bin create mode 100644 rust/fuzz/corpus/byte_storage_corrupted_envelope/wrong_checksum.bin create mode 100644 rust/fuzz/corpus/byte_storage_decompress/corrupted_payload.bin create mode 100644 rust/fuzz/corpus/byte_storage_decompress/decompression_bomb.bin create mode 100644 rust/fuzz/corpus/byte_storage_decompress/empty_compressed.bin create mode 100644 rust/fuzz/corpus/byte_storage_decompress/invalid_msgpack.bin create mode 100644 rust/fuzz/corpus/byte_storage_decompress/map_form.bin create mode 100644 rust/fuzz/corpus/byte_storage_decompress/missing_fields.bin create mode 100644 rust/fuzz/corpus/byte_storage_decompress/size_mismatch.bin create mode 100644 rust/fuzz/corpus/byte_storage_decompress/truncated.bin create mode 100644 rust/fuzz/corpus/byte_storage_decompress/valid_compressible.bin create mode 100644 rust/fuzz/corpus/byte_storage_decompress/valid_gradient.bin create mode 100644 rust/fuzz/corpus/byte_storage_decompress/valid_random.bin create mode 100644 rust/fuzz/corpus/byte_storage_decompress/valid_text.bin create mode 100644 rust/fuzz/corpus/byte_storage_decompress/valid_unicode_format.bin create mode 100644 rust/fuzz/corpus/byte_storage_decompress/wrong_checksum.bin create mode 100644 rust/fuzz/corpus/byte_storage_empty_data/data_no_size.bin create mode 100644 rust/fuzz/corpus/byte_storage_empty_data/random.bin create mode 100644 rust/fuzz/corpus/byte_storage_empty_data/size_no_data.bin create mode 100644 rust/fuzz/corpus/byte_storage_empty_data/zeros.bin create mode 100644 rust/fuzz/corpus/byte_storage_format_injection/bom.bin create mode 100644 rust/fuzz/corpus/byte_storage_format_injection/control_chars.bin create mode 100644 rust/fuzz/corpus/byte_storage_format_injection/long_10k.bin create mode 100644 rust/fuzz/corpus/byte_storage_format_injection/normal.bin create mode 100644 rust/fuzz/corpus/byte_storage_format_injection/null_byte.bin create mode 100644 rust/fuzz/corpus/byte_storage_format_injection/path_traversal.bin create mode 100644 rust/fuzz/corpus/byte_storage_format_injection/rtl_override.bin create mode 100644 rust/fuzz/corpus/byte_storage_integer_overflow/boundary_512mb.bin create mode 100644 rust/fuzz/corpus/byte_storage_integer_overflow/random_a.bin create mode 100644 rust/fuzz/corpus/byte_storage_integer_overflow/random_b.bin create mode 100644 rust/fuzz/corpus/byte_storage_integer_overflow/u32_max.bin create mode 100644 rust/fuzz/corpus/byte_storage_integer_overflow/zeros.bin create mode 100644 rust/fuzz/corpus/encryption_aad_injection/key_128.bin create mode 100644 rust/fuzz/corpus/encryption_aad_injection/key_nulls.bin create mode 100644 rust/fuzz/corpus/encryption_aad_injection/key_random.bin create mode 100644 rust/fuzz/corpus/encryption_key_derivation/bom.bin create mode 100644 rust/fuzz/corpus/encryption_key_derivation/empty_tenant.bin create mode 100644 rust/fuzz/corpus/encryption_key_derivation/long_tenant.bin create mode 100644 rust/fuzz/corpus/encryption_key_derivation/normal_tenant.bin create mode 100644 rust/fuzz/corpus/encryption_key_derivation/null_byte.bin create mode 100644 rust/fuzz/corpus/encryption_key_derivation/path_traversal.bin create mode 100644 rust/fuzz/corpus/encryption_key_derivation/unicode.bin create mode 100644 rust/fuzz/corpus/encryption_large_payload/key_100k_random.bin create mode 100644 rust/fuzz/corpus/encryption_large_payload/key_16k_compressible.bin create mode 100644 rust/fuzz/corpus/encryption_large_payload/key_1k.bin create mode 100644 rust/fuzz/corpus/encryption_large_payload/key_256k_compressible.bin create mode 100644 rust/fuzz/corpus/encryption_large_payload/key_64k.bin create mode 100644 rust/fuzz/corpus/encryption_nonce_reuse/key_64.bin create mode 100644 rust/fuzz/corpus/encryption_nonce_reuse/key_small.bin create mode 100644 rust/fuzz/corpus/encryption_roundtrip/key_compressible.bin create mode 100644 rust/fuzz/corpus/encryption_roundtrip/key_only.bin create mode 100644 rust/fuzz/corpus/encryption_roundtrip/key_random.bin create mode 100644 rust/fuzz/corpus/encryption_roundtrip/key_text.bin create mode 100644 rust/fuzz/corpus/encryption_truncated_ciphertext/key_200.bin create mode 100644 rust/fuzz/corpus/encryption_truncated_ciphertext/key_512.bin create mode 100644 rust/fuzz/corpus/encryption_truncated_ciphertext/key_min.bin create mode 100644 rust/fuzz/corpus/integration_layered_security/key_compressible.bin create mode 100644 rust/fuzz/corpus/integration_layered_security/key_random.bin create mode 100644 rust/fuzz/corpus/integration_layered_security/key_text.bin diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0c70a63..d636fb6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -77,8 +77,13 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: 3e8a8703264a2f4a69428a0aa4dcb512790b2c8c # v6.0.0 # pragma: allowlist secret hooks: + # Fuzz corpus seeds are opaque byte strings, not text — "fixing" their + # whitespace or final newline silently changes the seed (and breaks + # byte-exact StorageEnvelope seeds whose checksum must verify). - id: trailing-whitespace + exclude: ^rust/fuzz/corpus/ - id: end-of-file-fixer + exclude: ^rust/fuzz/corpus/ - id: check-yaml - id: check-added-large-files args: [--maxkb=1000] diff --git a/rust/fuzz/.gitignore b/rust/fuzz/.gitignore index 6cbee8c..6e8c5c5 100644 --- a/rust/fuzz/.gitignore +++ b/rust/fuzz/.gitignore @@ -1,7 +1,8 @@ -# Fuzz corpus and artifacts -# Corpus growth: allow initial seeds, ignore generated -corpus/*/ -!corpus/*/.gitkeep +# corpus/ is deliberately NOT ignored: seeds are committed per target +# (corpus//, the layout cargo-fuzz loads by default). Local fuzz runs +# grow these directories with hash-named discoveries — triage them, then +# commit keepers (after minimize_corpus.sh) or discard with git clean. +# The old `corpus/*/` pattern here silently excluded every seed: LAB-1149. # Artifacts: crashes, hangs, slow inputs artifacts/ diff --git a/rust/fuzz/README.md b/rust/fuzz/README.md index 56d2047..58e72a0 100644 --- a/rust/fuzz/README.md +++ b/rust/fuzz/README.md @@ -52,7 +52,7 @@ cd rust && make fuzz-coverage - Tests: u32::MAX, MAX_UNCOMPRESSED_SIZE ± 1, suspicious compression ratios **byte_storage_checksum_collision.rs** -- Attack: Data corruption with manipulated Blake3 checksums +- Attack: Data corruption with manipulated xxHash3-64 checksums - Validates: Integrity verification detects mismatches - Tests: Bit flips, truncation, zero checksums, partial corruption @@ -103,41 +103,52 @@ cd rust && make fuzz-coverage ## Corpus Management ### Directory Structure + +One committed seed directory per fuzz target, named exactly after the +`[[bin]]` stanza in `Cargo.toml`: + ``` rust/fuzz/corpus/ -├── byte_storage/ -│ ├── valid_envelopes/ # Valid MessagePack envelopes -│ ├── corrupted_envelopes/ # Known corruption patterns -│ ├── size_edge_cases/ # MIN, MAX, boundary sizes -│ └── format_strings/ # Valid + malicious format identifiers -├── encryption/ -│ ├── key_material/ # Valid 32-byte keys, edge cases -│ ├── tenant_ids/ # Realistic + malicious tenant IDs -│ ├── aad_patterns/ # Normal + injected AAD -│ └── ciphertext_samples/ # Valid + truncated ciphertext -└── integration/ - └── layered_data/ # Compressed-then-encrypted samples +├── CORPUS_INFO.md # Layout contract and maintenance guide +├── byte_storage_compress/ # Raw plaintext seeds +├── byte_storage_decompress/ # Valid + corrupted StorageEnvelope bytes +├── … # One directory per [[bin]] target +└── integration_layered_security/ ``` +This is the layout `cargo fuzz run ` loads by default — locally and +in CI, with no corpus argument. Seeds are shaped per target's input format +(e.g. `32-byte key ++ plaintext` for encryption targets); the envelope seeds +are byte-exact against cachekit-core's wire format so their xxHash3-64 +checksums verify, reaching branches random inputs essentially never hit. +See `corpus/CORPUS_INFO.md` for the full contract. + ### Corpus Scripts ```bash -# Generate initial corpus from test fixtures +# (Re)generate the deterministic per-target seed set +# Needs python3 with msgpack, lz4, xxhash — or via uv: +# uv run --no-project --with msgpack --with lz4 --with xxhash bash scripts/generate_corpus.sh cd rust/fuzz && ./scripts/generate_corpus.sh -# Minimize corpus (deduplicate, reduce size) +# Minimize corpus after growth runs (cargo fuzz cmin per target) cd rust/fuzz && ./scripts/minimize_corpus.sh -# Validate corpus integrity (< 10MB total) +# Validate: every Cargo.toml target has seeds, total < 10MB cd rust/fuzz && ./scripts/validate_corpus.sh ``` **Corpus Size Limit**: Total corpus should remain under 10MB for fast CI smoke tests. +**Regression seeds**: when a crash is found and fixed, commit the minimized +reproducer into `corpus//` so it is re-tested on every future run. + ## CI Integration ### Smoke Tests (PR Validation) `.github/workflows/fuzz-smoke.yml` runs on every pull request: - 60 seconds per target (~14 minutes total) +- Starts from the committed seeds in `corpus//` (cargo-fuzz's default + corpus path) instead of cold-starting from random bytes - Catches fuzzing regressions before merge - Uploads crash artifacts on failure @@ -261,11 +272,13 @@ All fuzz targets enforce fail-closed behavior: When adding new fuzz targets: 1. Follow naming convention: `_.rs` -2. Add target to `Cargo.toml` [[bin]] section -3. Create corpus subdirectory with `.gitkeep` +2. Add target to `Cargo.toml` [[bin]] section — the Makefile, CI, and corpus + scripts all derive the target list from these stanzas; there is no separate + list to update +3. Add seeds for the target to `scripts/generate_corpus.sh` and run it — + `validate_corpus.sh` fails until `corpus//` has seeds 4. Document attack vector in this README -5. Add target to `FUZZ_TARGETS` list in `rust/Makefile` -6. Verify with `make fuzz-target TARGET=your_new_target` +5. Verify with `make fuzz-target TARGET=your_new_target` ## References diff --git a/rust/fuzz/corpus/CORPUS_INFO.md b/rust/fuzz/corpus/CORPUS_INFO.md index 931d8d4..cb0cf64 100644 --- a/rust/fuzz/corpus/CORPUS_INFO.md +++ b/rust/fuzz/corpus/CORPUS_INFO.md @@ -1,94 +1,55 @@ -# Fuzzing Corpus Information +# Fuzzing Corpus -## Overview +Committed seed inputs for the fuzz targets in this crate. -This directory contains the initial fuzzing corpus for cachekit's Rust security layer. +## Layout: one directory per target -**Generated**: 2025-11-07 -**Total Size**: 6.9MB (under 10MB target) -**Total Files**: 1,758 samples - -## Corpus Organization - -### ByteStorage Corpus (`byte_storage/`) -- **valid_envelopes/** (3 files, 12K): Valid MessagePack envelopes for baseline testing -- **corrupted_envelopes/** (4 files, 16K): Malformed MessagePack structures -- **size_edge_cases/** (8 files, 28K): Size boundary testing (0 bytes, 1 byte, u32::MAX, suspicious ratios) -- **format_strings/** (5 files, 28K): Format identifier injection patterns - -**Edge Cases Added**: -- Empty file (0 bytes) -- Single byte file -- 100 null bytes -- u32::MAX representation - -### Encryption Corpus (`encryption/`) -- **key_material/** (3 files, 12K): Master key samples -- **tenant_ids/** (10 files, 48K): Tenant identifier patterns (normal, malicious, Unicode) -- **aad_patterns/** (5 files, 24K): Additional authenticated data samples -- **ciphertext_samples/** (4 files, 12K): Valid and corrupted ciphertext - -**Edge Cases Added**: -- Unicode mixed (Korean + Japanese) -- Emoji -- RTL override character (U+202E) -- Embedded null bytes - -### Integration Corpus (`integration/`) -- **layered_data/** (2 files, 8K): Combined compression + encryption samples +``` +corpus// +``` -## Corpus Generation +`` is the `[[bin]]` name in `Cargo.toml`, because that is the +directory `cargo fuzz run ` loads (and grows) by default — no corpus +argument needed, locally or in CI. Any other layout is invisible to the +fuzzer: an earlier category tree (`byte_storage/`, `encryption/`, …) sat here +for months without a single target ever reading it (LAB-1149). -Corpus was generated from: -1. **Automated extraction** (`scripts/generate_corpus.sh`): - - Production test fixtures from `tests/critical/` - - Synthetic edge cases (size boundaries, format injection) - - Encryption patterns (tenant IDs, AAD, ciphertext) +No file counts or sizes are recorded here — a written-down count is stale the +day someone adds a seed. For live numbers run: -2. **Manual additions**: - - Empty files - - Unicode edge cases - - Null byte patterns - - Platform-specific edge cases +```bash +./scripts/validate_corpus.sh +``` -## Validation +It fails if any `[[bin]]` target lacks seeds or the corpus exceeds the 10MB +CI budget. -Validated with `scripts/validate_corpus.sh`: -- Total size under 10MB target -- Sufficient sample diversity (1,758 files) -- Proper directory organization -- 3 empty files (intentional edge cases) +## Where seeds come from -## Usage +- **Generated**: `scripts/generate_corpus.sh` writes a deterministic seed set + per target, shaped to each target's input format (e.g. `32-byte key ++ + plaintext` for encryption targets). Valid `StorageEnvelope` seeds are + byte-exact against cachekit-core's wire format — raw LZ4 block, xxHash3-64 + big-endian checksum, rmp-serde array-form MessagePack — so they reach + `extract()`'s post-decompression branches that random inputs essentially + never hit (a matching 64-bit checksum is a 2^-64 event). +- **Grown**: local fuzz runs write hash-named discoveries into these + directories. Commit keepers after `scripts/minimize_corpus.sh`, or discard. +- **Regressions**: when a crash is found and fixed, commit the minimized + reproducer into the crashing target's directory so the input is re-tested + on every future run. -### Quick Fuzzing (60s per target) -```bash -make fuzz-quick -``` +## Maintenance -### Deep Fuzzing (8hr per target) ```bash -make fuzz-deep -``` +# Regenerate the deterministic seed set (safe: same version → same bytes) +./scripts/generate_corpus.sh -### Corpus Maintenance -```bash -# Minimize corpus (remove redundancy) +# Deduplicate / shrink after growth runs ./scripts/minimize_corpus.sh -# Re-validate after changes +# Check layout and size budget ./scripts/validate_corpus.sh ``` -## Maintenance Notes - -- **Corpus growth**: Fuzzing will discover new inputs and add them to corpus automatically -- **Minimization**: Run `minimize_corpus.sh` periodically to deduplicate and reduce size -- **Edge cases**: Add new attack patterns to appropriate subdirectories -- **Size limit**: Keep total corpus under 10MB for CI efficiency - -## References - -- Design document: `.spec-workflow/specs/rust-fuzzing-enhancement/design.md` -- Fuzzing guide: `rust/fuzz/README.md` -- Task specification: `.spec-workflow/specs/rust-fuzzing-enhancement/tasks.md` +Keep the total under 10MB so CI seed loading stays cheap. diff --git a/rust/fuzz/corpus/byte_storage_checksum_collision/compressible.bin b/rust/fuzz/corpus/byte_storage_checksum_collision/compressible.bin new file mode 100644 index 0000000..f67e2de --- /dev/null +++ b/rust/fuzz/corpus/byte_storage_checksum_collision/compressible.bin @@ -0,0 +1 @@ +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaae/ \ No newline at end of file diff --git a/rust/fuzz/corpus/byte_storage_checksum_collision/large.bin b/rust/fuzz/corpus/byte_storage_checksum_collision/large.bin new file mode 100644 index 0000000000000000000000000000000000000000..6367f9ca0d211384a80cc988793c663ad881d6dc GIT binary patch literal 1024 zcmV+b1poVlU9ZH% z?4C(dQ_+w&xVoUF?liD41s;BeFa`QHtR6D%l#uxz6D9o zs-N4GeXa2kAyZ;0v6$y@Vraxo0TwU!o;lUfhm^St)y`E9t z`n+;SIT^x)-R1hHl{IbcWl@oOd|Kc0NxC6L8dP@Yao2n*G4H~;(F^e(A;*^?!oLcl zlHzj5AE>;^E!lluh%4$UeM#U?{+x|l+PLdJiQmHicSg);C9hCwlOfmZt-n zpB4FjaXWC9V%Z?rvF0h;7L;?{t49r+6xn_?68Pf|oEg=t68G&FDIFv&KA*|9H@iD_`9;q0Yz^w?f20QhT^YnV$2RA z-;f>3z^pkZQC0#UGpV5+xuTFEh=bZp1Z4LRq^U-j`p_48H+G+h57r7MU8ZSeANHt7 z$Gfi*UOPlsyLH6YFc^b07 zv>KhwNp>D$W>t{TgbuaFdD{I&FvveVPF2!)jj*j?0Q841GcCrRMOIUKyzZsyzt!v z`KL%o#W!;PF%!|@8r*~xhZD#}Zc~01CyCqVQsKD%W`x_84^)9HjdC!!o#ZQ%}ZQKt({faIXfF&%}VV7Ctopw~NTOExA62l4X&7f?;^WZU&9*h5EQ GB|k}RH*{wJ literal 0 HcmV?d00001 diff --git a/rust/fuzz/corpus/byte_storage_checksum_collision/small.bin b/rust/fuzz/corpus/byte_storage_checksum_collision/small.bin new file mode 100644 index 0000000..6ccdd1d --- /dev/null +++ b/rust/fuzz/corpus/byte_storage_checksum_collision/small.bin @@ -0,0 +1 @@ +0uS YcaaBHN2s \ No newline at end of file diff --git a/rust/fuzz/corpus/byte_storage_compress/compressible.bin b/rust/fuzz/corpus/byte_storage_compress/compressible.bin new file mode 100644 index 0000000..ebf63e7 --- /dev/null +++ b/rust/fuzz/corpus/byte_storage_compress/compressible.bin @@ -0,0 +1 @@ +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \ No newline at end of file diff --git a/rust/fuzz/corpus/.gitkeep b/rust/fuzz/corpus/byte_storage_compress/empty.bin similarity index 100% rename from rust/fuzz/corpus/.gitkeep rename to rust/fuzz/corpus/byte_storage_compress/empty.bin diff --git a/rust/fuzz/corpus/byte_storage_compress/gradient.bin b/rust/fuzz/corpus/byte_storage_compress/gradient.bin new file mode 100644 index 0000000000000000000000000000000000000000..c8b49c8cd518e58491924bfc364ff26e01a85009 GIT binary patch literal 1024 zcmZQzWMXDvWn<^yMC+6cQE@6%&_`l#-T_m6KOcR8m$^Ra4i{)Y8_`)zddH zG%_|ZH8Z!cw6eCbwX=6{baHlab#wRd^z!!c_45x13RUz zF>}`JIdkXDU$Ah|;w4L$Enl&6)#^2C*R9{Mant54TeofBv2)k%J$v`9 zs)QhMihzNUwhOFaT;@e7o37G03(2YS&r z+%ouyGl&k6_B|glc1^9SRB7G7$pQZsu)S`e5%1}#GU`I<8Y@V=#>|ty?IJ*7yDJ*c zmrYEuvht3bo)nycOwDOK!P8aw+xoYvZZoMBvf92Xu!i>m!Dy}fM3t6u~>gaS{{+i@+ zJ1>u;o~H*FN}|Zlbti#0N|f-|9S5#$xunzlV#2JAu4_QgypF(p`8klY@JM2k6nDFi zW8-VqX%{(;T42*AwX<|Ix;CCcP!CANXla!Er$@lrG`b@;Ltyy^@$m^(*S;oGV3fNn za*TQlczAyny4vzZsq8>`FpB6J0t>>1rprt49RCR~;FA)uo4m4q10-BHbjLfJB6;)1 zam%}XTW^ir%|@3eF5`J}W+g+%Fu73q^A!-%qyblwNfa|H86GTeOvoZMoh`V;yB;BT zHwvsB4h9uQBF{ML4PP=p$Cs-Z(8OI>$~$n#Lkwd}MP)Pr@3%ra{70n&QUX9C(50UU zJU?bn1orhb_LG@_KNz^qW}LnY55p~{Sxcng=sXvXDa-cWtF*DiET4vq`0_l^Z~%`& z+nUFFlD(5b+2+dodhAy>*2-=?$BFhK-Xs>OyL{}Zyrn!N`*7#Y>i~m+0A=hVOE%%~ zFi#TzjPjA~6TRp#1mFd%5^8}@Wz*K#8peA$`Vvx6Mm5w6Vm$)=NbCGCZ zWc}JnUvQ7BZke}JNF617e6%r~<2~bxt&yR;#I75CAy< literal 0 HcmV?d00001 diff --git a/rust/fuzz/corpus/byte_storage_compress/single_byte.bin b/rust/fuzz/corpus/byte_storage_compress/single_byte.bin new file mode 100644 index 0000000..2e65efe --- /dev/null +++ b/rust/fuzz/corpus/byte_storage_compress/single_byte.bin @@ -0,0 +1 @@ +a \ No newline at end of file diff --git a/rust/fuzz/corpus/byte_storage_compress/text.bin b/rust/fuzz/corpus/byte_storage_compress/text.bin new file mode 100644 index 0000000..2124643 --- /dev/null +++ b/rust/fuzz/corpus/byte_storage_compress/text.bin @@ -0,0 +1 @@ +Hello, cachekit! MessagePack envelope roundtrip seed. \ No newline at end of file diff --git a/rust/fuzz/corpus/byte_storage_compress/unicode.bin b/rust/fuzz/corpus/byte_storage_compress/unicode.bin new file mode 100644 index 0000000..fb77344 --- /dev/null +++ b/rust/fuzz/corpus/byte_storage_compress/unicode.bin @@ -0,0 +1 @@ +café ✨ 한국어 テスト \ No newline at end of file diff --git a/rust/fuzz/corpus/byte_storage_corrupted_envelope/corrupted_payload.bin b/rust/fuzz/corpus/byte_storage_corrupted_envelope/corrupted_payload.bin new file mode 100644 index 0000000000000000000000000000000000000000..5d3d1c61dcd45ca3c5e074203751e3ed4cc9541d GIT binary patch literal 43 scmbPoL`Xi7k>NiCybDMKfpk9;r5MgLt-5D+o#kLyo?Dz=keHke0O}|d-T(jq literal 0 HcmV?d00001 diff --git a/rust/fuzz/corpus/byte_storage_corrupted_envelope/decompression_bomb.bin b/rust/fuzz/corpus/byte_storage_corrupted_envelope/decompression_bomb.bin new file mode 100644 index 0000000000000000000000000000000000000000..014efa2116c046858ed08673b31a4f5a589ab95f GIT binary patch literal 29 dcmbPogoS~TiFpPC6rB4H1j}=a(+d)lvjKUd3Q_<7 literal 0 HcmV?d00001 diff --git a/rust/fuzz/corpus/byte_storage_corrupted_envelope/empty_compressed.bin b/rust/fuzz/corpus/byte_storage_corrupted_envelope/empty_compressed.bin new file mode 100644 index 0000000000000000000000000000000000000000..d13a66763b1122b342e36bdf90c21ac68cca6ba7 GIT binary patch literal 21 XcmbPogkc5)6r?QAElw{;OwI-XI=Kbn literal 0 HcmV?d00001 diff --git a/rust/fuzz/corpus/byte_storage_corrupted_envelope/invalid_msgpack.bin b/rust/fuzz/corpus/byte_storage_corrupted_envelope/invalid_msgpack.bin new file mode 100644 index 0000000..8663f7d --- /dev/null +++ b/rust/fuzz/corpus/byte_storage_corrupted_envelope/invalid_msgpack.bin @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/rust/fuzz/corpus/byte_storage_corrupted_envelope/map_form.bin b/rust/fuzz/corpus/byte_storage_corrupted_envelope/map_form.bin new file mode 100644 index 0000000..db8db2b --- /dev/null +++ b/rust/fuzz/corpus/byte_storage_corrupted_envelope/map_form.bin @@ -0,0 +1 @@ +compressed_data7&Hello, cachekit! MessagePack envelope roundtrip seed.checksumr̡̀׭original_size5formatmsgpack \ No newline at end of file diff --git a/rust/fuzz/corpus/byte_storage_corrupted_envelope/missing_fields.bin b/rust/fuzz/corpus/byte_storage_corrupted_envelope/missing_fields.bin new file mode 100644 index 0000000..2e2d562 --- /dev/null +++ b/rust/fuzz/corpus/byte_storage_corrupted_envelope/missing_fields.bin @@ -0,0 +1 @@ +only_one_field \ No newline at end of file diff --git a/rust/fuzz/corpus/byte_storage_corrupted_envelope/size_mismatch.bin b/rust/fuzz/corpus/byte_storage_corrupted_envelope/size_mismatch.bin new file mode 100644 index 0000000..9f11f07 --- /dev/null +++ b/rust/fuzz/corpus/byte_storage_corrupted_envelope/size_mismatch.bin @@ -0,0 +1 @@ +7&Hello, cachekit! MessagePack envelope roundtrip seed.r̡̀6msgpack \ No newline at end of file diff --git a/rust/fuzz/corpus/byte_storage_corrupted_envelope/truncated.bin b/rust/fuzz/corpus/byte_storage_corrupted_envelope/truncated.bin new file mode 100644 index 0000000..c7e2981 --- /dev/null +++ b/rust/fuzz/corpus/byte_storage_corrupted_envelope/truncated.bin @@ -0,0 +1 @@ +7&Hello, cachekit! MessagePack envelop \ No newline at end of file diff --git a/rust/fuzz/corpus/byte_storage_corrupted_envelope/valid_compressible.bin b/rust/fuzz/corpus/byte_storage_corrupted_envelope/valid_compressible.bin new file mode 100644 index 0000000000000000000000000000000000000000..466c6b564d238955e173be233c152fc3e6244e74 GIT binary patch literal 43 scmbPoL`Xi7k>NiCybDMKff;@#N->;gT6NFtI?KVZJhwQ#ATc=`0PbED4*&oF literal 0 HcmV?d00001 diff --git a/rust/fuzz/corpus/byte_storage_corrupted_envelope/valid_gradient.bin b/rust/fuzz/corpus/byte_storage_corrupted_envelope/valid_gradient.bin new file mode 100644 index 0000000000000000000000000000000000000000..a51e38efbfc5dac76d5be6dc0681e45863b3f16a GIT binary patch literal 297 zcmV+^0oMMM#Q_cf@c;n=0|W&I2M7rY3k(eo4-gR&6BHE|7Z@2D8yp=TA0QzjBP1mz zCnzZ@D=aN8FEBAOGc+|eH#j*uJ3Ku;KR`i3LqtVJM@UIZOH55pPf$@(Q&d$}S6EqE zTU=dUUtnQkV`OD!XJ~0^Yiw<9Z*XyPb98lfcX)YvdwhLLo_tE{cAuduPQv$VCgx45~wyS%-=zrex5 z!^FkL$H>Xb%goKr&(P7*)6~`0*Vx(G+uYsW-{9fm+J3B@9^>R^Yr!h v_xSnx`~3a>{{R91|LRct{Qds_n9Qhf%=szIggMNOBFzKgus^0 literal 0 HcmV?d00001 diff --git a/rust/fuzz/corpus/byte_storage_corrupted_envelope/valid_random.bin b/rust/fuzz/corpus/byte_storage_corrupted_envelope/valid_random.bin new file mode 100644 index 0000000000000000000000000000000000000000..059034de5a90c931f61deee9ade109b3791ac3b4 GIT binary patch literal 1058 zcmV+-1l{|T#RLWL|NsB=xf3c&IIYTK!qM5=@!af*O}k+uu0U|i-!DVw$-!V|&)jZx9z`KU08xEus7<2&e-CqFUVUJ-uO$1ZLBc-KiT@A=>6 z=Um7J$_IMUH{3G#i8F`}k@h_wF?LO@s#Iy+z{vss7O=f;pb_ussWR$9=^86YyvEFv zzwIJGVY@3D&zDV1v9j`xznwztd1#$quu&!(3Lx1JkO~Q=Gdn&Flw+mUX zKG9S#N+Mk3ER>J48qKgXA=7|_IBSjsza$U_WcOGRZg0q?g$I{Zha z15yG&BG9Fu2s}S#PXzY$H1?C3fIk?x&Sspx3lGCBrddm*;OIOTk15Oc-mA2+#4MkN zjQH|A&~N~cLfe|hdy>7ALD}ZY`+DqGH`dB-JjaRlA>Jewsk?masJx{-Bl~dY&FcVz zfdFOfB1<;m@Gwsk0OWfEMpOAk?@w>r7F#{PQ#>tt&KUNcNmyp;zsqQVVrX|_I=BOG37A$q{Xy>-l@0!S_A_>iMgFrZ{k&~xu#61 zB>TCv8%#3!I&u3xIGyMs#VRfVMS3sx&#aXsMf#;H(m{t^wTqKLm2!NG7@Dtv(h=_o zNn7B#TgVB=$BZ3{56)?9jIMGdBE=K#Ok~OJ3-$|pqp%pQ4I?Jg&IJ#kzi%}R_!X8m zexu>)P@s86meA=xAoV5(K_jS$?Z}S cm*?fdBvi literal 0 HcmV?d00001 diff --git a/rust/fuzz/corpus/byte_storage_corrupted_envelope/valid_text.bin b/rust/fuzz/corpus/byte_storage_corrupted_envelope/valid_text.bin new file mode 100644 index 0000000..ac29837 --- /dev/null +++ b/rust/fuzz/corpus/byte_storage_corrupted_envelope/valid_text.bin @@ -0,0 +1 @@ +7&Hello, cachekit! MessagePack envelope roundtrip seed.r̡̀5msgpack \ No newline at end of file diff --git a/rust/fuzz/corpus/byte_storage_corrupted_envelope/valid_unicode_format.bin b/rust/fuzz/corpus/byte_storage_corrupted_envelope/valid_unicode_format.bin new file mode 100644 index 0000000..8246d33 --- /dev/null +++ b/rust/fuzz/corpus/byte_storage_corrupted_envelope/valid_unicode_format.bin @@ -0,0 +1 @@ +7&Hello, cachekit! MessagePack envelope roundtrip seed.r̡̀5utf8_✨ \ No newline at end of file diff --git a/rust/fuzz/corpus/byte_storage_corrupted_envelope/wrong_checksum.bin b/rust/fuzz/corpus/byte_storage_corrupted_envelope/wrong_checksum.bin new file mode 100644 index 0000000000000000000000000000000000000000..bceed862c4a0b0dd951972fa0dd7cb35aa4bab43 GIT binary patch literal 76 zcmbPo#QcMrM`}(^zK%k2Vsb`mc4mp9f^TYZabkLEKw@&XLTX-FYEFJZszOnIXNiCybDMKfpk9;r5MgLt-5D+o#kLyo?Dz=keHke0O}|d-T(jq literal 0 HcmV?d00001 diff --git a/rust/fuzz/corpus/byte_storage_decompress/decompression_bomb.bin b/rust/fuzz/corpus/byte_storage_decompress/decompression_bomb.bin new file mode 100644 index 0000000000000000000000000000000000000000..014efa2116c046858ed08673b31a4f5a589ab95f GIT binary patch literal 29 dcmbPogoS~TiFpPC6rB4H1j}=a(+d)lvjKUd3Q_<7 literal 0 HcmV?d00001 diff --git a/rust/fuzz/corpus/byte_storage_decompress/empty_compressed.bin b/rust/fuzz/corpus/byte_storage_decompress/empty_compressed.bin new file mode 100644 index 0000000000000000000000000000000000000000..d13a66763b1122b342e36bdf90c21ac68cca6ba7 GIT binary patch literal 21 XcmbPogkc5)6r?QAElw{;OwI-XI=Kbn literal 0 HcmV?d00001 diff --git a/rust/fuzz/corpus/byte_storage_decompress/invalid_msgpack.bin b/rust/fuzz/corpus/byte_storage_decompress/invalid_msgpack.bin new file mode 100644 index 0000000..8663f7d --- /dev/null +++ b/rust/fuzz/corpus/byte_storage_decompress/invalid_msgpack.bin @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/rust/fuzz/corpus/byte_storage_decompress/map_form.bin b/rust/fuzz/corpus/byte_storage_decompress/map_form.bin new file mode 100644 index 0000000..db8db2b --- /dev/null +++ b/rust/fuzz/corpus/byte_storage_decompress/map_form.bin @@ -0,0 +1 @@ +compressed_data7&Hello, cachekit! MessagePack envelope roundtrip seed.checksumr̡̀׭original_size5formatmsgpack \ No newline at end of file diff --git a/rust/fuzz/corpus/byte_storage_decompress/missing_fields.bin b/rust/fuzz/corpus/byte_storage_decompress/missing_fields.bin new file mode 100644 index 0000000..2e2d562 --- /dev/null +++ b/rust/fuzz/corpus/byte_storage_decompress/missing_fields.bin @@ -0,0 +1 @@ +only_one_field \ No newline at end of file diff --git a/rust/fuzz/corpus/byte_storage_decompress/size_mismatch.bin b/rust/fuzz/corpus/byte_storage_decompress/size_mismatch.bin new file mode 100644 index 0000000..9f11f07 --- /dev/null +++ b/rust/fuzz/corpus/byte_storage_decompress/size_mismatch.bin @@ -0,0 +1 @@ +7&Hello, cachekit! MessagePack envelope roundtrip seed.r̡̀6msgpack \ No newline at end of file diff --git a/rust/fuzz/corpus/byte_storage_decompress/truncated.bin b/rust/fuzz/corpus/byte_storage_decompress/truncated.bin new file mode 100644 index 0000000..c7e2981 --- /dev/null +++ b/rust/fuzz/corpus/byte_storage_decompress/truncated.bin @@ -0,0 +1 @@ +7&Hello, cachekit! MessagePack envelop \ No newline at end of file diff --git a/rust/fuzz/corpus/byte_storage_decompress/valid_compressible.bin b/rust/fuzz/corpus/byte_storage_decompress/valid_compressible.bin new file mode 100644 index 0000000000000000000000000000000000000000..466c6b564d238955e173be233c152fc3e6244e74 GIT binary patch literal 43 scmbPoL`Xi7k>NiCybDMKff;@#N->;gT6NFtI?KVZJhwQ#ATc=`0PbED4*&oF literal 0 HcmV?d00001 diff --git a/rust/fuzz/corpus/byte_storage_decompress/valid_gradient.bin b/rust/fuzz/corpus/byte_storage_decompress/valid_gradient.bin new file mode 100644 index 0000000000000000000000000000000000000000..a51e38efbfc5dac76d5be6dc0681e45863b3f16a GIT binary patch literal 297 zcmV+^0oMMM#Q_cf@c;n=0|W&I2M7rY3k(eo4-gR&6BHE|7Z@2D8yp=TA0QzjBP1mz zCnzZ@D=aN8FEBAOGc+|eH#j*uJ3Ku;KR`i3LqtVJM@UIZOH55pPf$@(Q&d$}S6EqE zTU=dUUtnQkV`OD!XJ~0^Yiw<9Z*XyPb98lfcX)YvdwhLLo_tE{cAuduPQv$VCgx45~wyS%-=zrex5 z!^FkL$H>Xb%goKr&(P7*)6~`0*Vx(G+uYsW-{9fm+J3B@9^>R^Yr!h v_xSnx`~3a>{{R91|LRct{Qds_n9Qhf%=szIggMNOBFzKgus^0 literal 0 HcmV?d00001 diff --git a/rust/fuzz/corpus/byte_storage_decompress/valid_random.bin b/rust/fuzz/corpus/byte_storage_decompress/valid_random.bin new file mode 100644 index 0000000000000000000000000000000000000000..059034de5a90c931f61deee9ade109b3791ac3b4 GIT binary patch literal 1058 zcmV+-1l{|T#RLWL|NsB=xf3c&IIYTK!qM5=@!af*O}k+uu0U|i-!DVw$-!V|&)jZx9z`KU08xEus7<2&e-CqFUVUJ-uO$1ZLBc-KiT@A=>6 z=Um7J$_IMUH{3G#i8F`}k@h_wF?LO@s#Iy+z{vss7O=f;pb_ussWR$9=^86YyvEFv zzwIJGVY@3D&zDV1v9j`xznwztd1#$quu&!(3Lx1JkO~Q=Gdn&Flw+mUX zKG9S#N+Mk3ER>J48qKgXA=7|_IBSjsza$U_WcOGRZg0q?g$I{Zha z15yG&BG9Fu2s}S#PXzY$H1?C3fIk?x&Sspx3lGCBrddm*;OIOTk15Oc-mA2+#4MkN zjQH|A&~N~cLfe|hdy>7ALD}ZY`+DqGH`dB-JjaRlA>Jewsk?masJx{-Bl~dY&FcVz zfdFOfB1<;m@Gwsk0OWfEMpOAk?@w>r7F#{PQ#>tt&KUNcNmyp;zsqQVVrX|_I=BOG37A$q{Xy>-l@0!S_A_>iMgFrZ{k&~xu#61 zB>TCv8%#3!I&u3xIGyMs#VRfVMS3sx&#aXsMf#;H(m{t^wTqKLm2!NG7@Dtv(h=_o zNn7B#TgVB=$BZ3{56)?9jIMGdBE=K#Ok~OJ3-$|pqp%pQ4I?Jg&IJ#kzi%}R_!X8m zexu>)P@s86meA=xAoV5(K_jS$?Z}S cm*?fdBvi literal 0 HcmV?d00001 diff --git a/rust/fuzz/corpus/byte_storage_decompress/valid_text.bin b/rust/fuzz/corpus/byte_storage_decompress/valid_text.bin new file mode 100644 index 0000000..ac29837 --- /dev/null +++ b/rust/fuzz/corpus/byte_storage_decompress/valid_text.bin @@ -0,0 +1 @@ +7&Hello, cachekit! MessagePack envelope roundtrip seed.r̡̀5msgpack \ No newline at end of file diff --git a/rust/fuzz/corpus/byte_storage_decompress/valid_unicode_format.bin b/rust/fuzz/corpus/byte_storage_decompress/valid_unicode_format.bin new file mode 100644 index 0000000..8246d33 --- /dev/null +++ b/rust/fuzz/corpus/byte_storage_decompress/valid_unicode_format.bin @@ -0,0 +1 @@ +7&Hello, cachekit! MessagePack envelope roundtrip seed.r̡̀5utf8_✨ \ No newline at end of file diff --git a/rust/fuzz/corpus/byte_storage_decompress/wrong_checksum.bin b/rust/fuzz/corpus/byte_storage_decompress/wrong_checksum.bin new file mode 100644 index 0000000000000000000000000000000000000000..bceed862c4a0b0dd951972fa0dd7cb35aa4bab43 GIT binary patch literal 76 zcmbPo#QcMrM`}(^zK%k2Vsb`mc4mp9f^TYZabkLEKw@&XLTX-FYEFJZszOnIXi>c literal 0 HcmV?d00001 diff --git a/rust/fuzz/corpus/byte_storage_empty_data/random.bin b/rust/fuzz/corpus/byte_storage_empty_data/random.bin new file mode 100644 index 0000000..f9ab2c6 --- /dev/null +++ b/rust/fuzz/corpus/byte_storage_empty_data/random.bin @@ -0,0 +1 @@ + 'n`96IJpӚ \ No newline at end of file diff --git a/rust/fuzz/corpus/byte_storage_empty_data/size_no_data.bin b/rust/fuzz/corpus/byte_storage_empty_data/size_no_data.bin new file mode 100644 index 0000000000000000000000000000000000000000..9c1107c3b591c1e9c1ee179b713818223bd66ffc GIT binary patch literal 13 LcmaFC%zyv@3;6)- literal 0 HcmV?d00001 diff --git a/rust/fuzz/corpus/byte_storage_empty_data/zeros.bin b/rust/fuzz/corpus/byte_storage_empty_data/zeros.bin new file mode 100644 index 0000000000000000000000000000000000000000..e91e775a1f19649e96f2cd6f37ab731a92214df5 GIT binary patch literal 13 KcmZQzKmq^&4FCZE literal 0 HcmV?d00001 diff --git a/rust/fuzz/corpus/byte_storage_format_injection/bom.bin b/rust/fuzz/corpus/byte_storage_format_injection/bom.bin new file mode 100644 index 0000000..6866187 --- /dev/null +++ b/rust/fuzz/corpus/byte_storage_format_injection/bom.bin @@ -0,0 +1 @@ +bom \ No newline at end of file diff --git a/rust/fuzz/corpus/byte_storage_format_injection/control_chars.bin b/rust/fuzz/corpus/byte_storage_format_injection/control_chars.bin new file mode 100644 index 0000000..47180ca --- /dev/null +++ b/rust/fuzz/corpus/byte_storage_format_injection/control_chars.bin @@ -0,0 +1,2 @@ +fmt +CRLF \ No newline at end of file diff --git a/rust/fuzz/corpus/byte_storage_format_injection/long_10k.bin b/rust/fuzz/corpus/byte_storage_format_injection/long_10k.bin new file mode 100644 index 0000000..f2776bd --- /dev/null +++ b/rust/fuzz/corpus/byte_storage_format_injection/long_10k.bin @@ -0,0 +1 @@ +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ No newline at end of file diff --git a/rust/fuzz/corpus/byte_storage_format_injection/normal.bin b/rust/fuzz/corpus/byte_storage_format_injection/normal.bin new file mode 100644 index 0000000..b3ae8a0 --- /dev/null +++ b/rust/fuzz/corpus/byte_storage_format_injection/normal.bin @@ -0,0 +1 @@ +msgpack \ No newline at end of file diff --git a/rust/fuzz/corpus/byte_storage_format_injection/null_byte.bin b/rust/fuzz/corpus/byte_storage_format_injection/null_byte.bin new file mode 100644 index 0000000000000000000000000000000000000000..ee5839f281f2e1beb449be44f2c1a8d5c4be423f GIT binary patch literal 8 PcmYexEn&zj&B*}(4Mqb4 literal 0 HcmV?d00001 diff --git a/rust/fuzz/corpus/byte_storage_format_injection/path_traversal.bin b/rust/fuzz/corpus/byte_storage_format_injection/path_traversal.bin new file mode 100644 index 0000000..91bf449 --- /dev/null +++ b/rust/fuzz/corpus/byte_storage_format_injection/path_traversal.bin @@ -0,0 +1 @@ +../../../etc/passwd \ No newline at end of file diff --git a/rust/fuzz/corpus/byte_storage_format_injection/rtl_override.bin b/rust/fuzz/corpus/byte_storage_format_injection/rtl_override.bin new file mode 100644 index 0000000..7aac776 --- /dev/null +++ b/rust/fuzz/corpus/byte_storage_format_injection/rtl_override.bin @@ -0,0 +1 @@ +‮rtl \ No newline at end of file diff --git a/rust/fuzz/corpus/byte_storage_integer_overflow/boundary_512mb.bin b/rust/fuzz/corpus/byte_storage_integer_overflow/boundary_512mb.bin new file mode 100644 index 0000000000000000000000000000000000000000..ec584a8d426056db527628350398f51592048a9b GIT binary patch literal 14 PcmZQzU{LrU3I!Yh8VCc> literal 0 HcmV?d00001 diff --git a/rust/fuzz/corpus/byte_storage_integer_overflow/random_a.bin b/rust/fuzz/corpus/byte_storage_integer_overflow/random_a.bin new file mode 100644 index 0000000..fa6c652 --- /dev/null +++ b/rust/fuzz/corpus/byte_storage_integer_overflow/random_a.bin @@ -0,0 +1 @@ +#6g!ƣ]1? \ No newline at end of file diff --git a/rust/fuzz/corpus/byte_storage_integer_overflow/random_b.bin b/rust/fuzz/corpus/byte_storage_integer_overflow/random_b.bin new file mode 100644 index 0000000..6f9d57e --- /dev/null +++ b/rust/fuzz/corpus/byte_storage_integer_overflow/random_b.bin @@ -0,0 +1 @@ +U_7ETH53p>P] \ No newline at end of file diff --git a/rust/fuzz/corpus/byte_storage_integer_overflow/u32_max.bin b/rust/fuzz/corpus/byte_storage_integer_overflow/u32_max.bin new file mode 100644 index 0000000..0f2267d --- /dev/null +++ b/rust/fuzz/corpus/byte_storage_integer_overflow/u32_max.bin @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/rust/fuzz/corpus/byte_storage_integer_overflow/zeros.bin b/rust/fuzz/corpus/byte_storage_integer_overflow/zeros.bin new file mode 100644 index 0000000000000000000000000000000000000000..80023568107ecf6dd6095def597ce5eac83da921 GIT binary patch literal 14 KcmZQzKn4H+4gdiF literal 0 HcmV?d00001 diff --git a/rust/fuzz/corpus/encryption_aad_injection/key_128.bin b/rust/fuzz/corpus/encryption_aad_injection/key_128.bin new file mode 100644 index 0000000..eaeb5f2 --- /dev/null +++ b/rust/fuzz/corpus/encryption_aad_injection/key_128.bin @@ -0,0 +1 @@ +QP!+U=i.d3'r"ppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppaad_normalqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq \ No newline at end of file diff --git a/rust/fuzz/corpus/encryption_aad_injection/key_nulls.bin b/rust/fuzz/corpus/encryption_aad_injection/key_nulls.bin new file mode 100644 index 0000000000000000000000000000000000000000..719fa2ff65c0e9b8a3d00fd13b89d7021883d587 GIT binary patch literal 151 zcmb2*XPw3NJupE0i=uYl+RztGwl_2NQjBNL`>tLj`+lQR0R z;E&HWlpP{9+6d7M^69K<*UOemN&WPz<~QH?y8|BqB76>oCb$vXx{zy2$E4HgqBCwc ze91`3=TQ;ZKCVO&&|YwZjIu<{GJk!8|F$E@g+DlzM{P#MtY~s>*cNrujl!?EIjaFf z9J6J+J*}saLlP&UJlh_rkTyr#T=Kd3$_^=sBP%2IYtK()K``C%JWeM+xQJEkVcdo! z9DTnR=T45cA%6K3KIF&VNVI$_A0J>*#0W|#nb}^F79&?M*wN3;l1{|#LaXlU1y_VEFi(?!+zAc4?>mL|>lZ>e`^%w^W z;m+-_o+NHqJUZ=>DfDrvDgbudmJI!Wi`+uj{Dr#y{V;rPM0~R65hk%oB{on zdF+V)1QrUcJzfSynj8jhd677C2K$BG+05PtP4y1E<8}BrWE&$Zj?)H{S^SJL( zTkPyy1pEeMog-nJ@F$q_6OYGMiiFMFZnKAd18}6Fi*9nOHzl!A6A`Vs^>K+-RtaMV zpDP7oO{3b>&{|(pwBZETbXv0ht|bzq=Gl^1BwKjGrs#TyrZo7DWE6wa{4_<|9wpHlyO?QuiEKp CX8tGu literal 0 HcmV?d00001 diff --git a/rust/fuzz/corpus/encryption_key_derivation/bom.bin b/rust/fuzz/corpus/encryption_key_derivation/bom.bin new file mode 100644 index 0000000..11c4c07 --- /dev/null +++ b/rust/fuzz/corpus/encryption_key_derivation/bom.bin @@ -0,0 +1 @@ +o%)I;yxJh~bom_tenant \ No newline at end of file diff --git a/rust/fuzz/corpus/encryption_key_derivation/empty_tenant.bin b/rust/fuzz/corpus/encryption_key_derivation/empty_tenant.bin new file mode 100644 index 0000000..b1b1f68 --- /dev/null +++ b/rust/fuzz/corpus/encryption_key_derivation/empty_tenant.bin @@ -0,0 +1 @@ +o%)I;yxJh~ \ No newline at end of file diff --git a/rust/fuzz/corpus/encryption_key_derivation/long_tenant.bin b/rust/fuzz/corpus/encryption_key_derivation/long_tenant.bin new file mode 100644 index 0000000..56992bb --- /dev/null +++ b/rust/fuzz/corpus/encryption_key_derivation/long_tenant.bin @@ -0,0 +1 @@ +o%)I;yxJh~xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ No newline at end of file diff --git a/rust/fuzz/corpus/encryption_key_derivation/normal_tenant.bin b/rust/fuzz/corpus/encryption_key_derivation/normal_tenant.bin new file mode 100644 index 0000000..b5de533 --- /dev/null +++ b/rust/fuzz/corpus/encryption_key_derivation/normal_tenant.bin @@ -0,0 +1 @@ +o%)I;yxJh~customer-12345 \ No newline at end of file diff --git a/rust/fuzz/corpus/encryption_key_derivation/null_byte.bin b/rust/fuzz/corpus/encryption_key_derivation/null_byte.bin new file mode 100644 index 0000000000000000000000000000000000000000..d0e546b81657e541a59af079e1b7832731f17684 GIT binary patch literal 27 icmd1bc>jj#2~AJy$`=(ky)x=bQu7k?N*MA=b8-N`3=Ek7 literal 0 HcmV?d00001 diff --git a/rust/fuzz/corpus/encryption_key_derivation/path_traversal.bin b/rust/fuzz/corpus/encryption_key_derivation/path_traversal.bin new file mode 100644 index 0000000..420ef2c --- /dev/null +++ b/rust/fuzz/corpus/encryption_key_derivation/path_traversal.bin @@ -0,0 +1 @@ +o%)I;yxJh~../../../admin \ No newline at end of file diff --git a/rust/fuzz/corpus/encryption_key_derivation/unicode.bin b/rust/fuzz/corpus/encryption_key_derivation/unicode.bin new file mode 100644 index 0000000..d37efdb --- /dev/null +++ b/rust/fuzz/corpus/encryption_key_derivation/unicode.bin @@ -0,0 +1 @@ +o%)I;yxJh~한국어✨ \ No newline at end of file diff --git a/rust/fuzz/corpus/encryption_large_payload/key_100k_random.bin b/rust/fuzz/corpus/encryption_large_payload/key_100k_random.bin new file mode 100644 index 0000000000000000000000000000000000000000..b08bc9f34c3a04f45cb0d972b3d8f71798cc5d3e GIT binary patch literal 102432 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 V^}X41emDnfE4qbKjmOsAE`KA+Qqlkb literal 0 HcmV?d00001 diff --git a/rust/fuzz/corpus/encryption_nonce_reuse/key_64.bin b/rust/fuzz/corpus/encryption_nonce_reuse/key_64.bin new file mode 100644 index 0000000..6906167 --- /dev/null +++ b/rust/fuzz/corpus/encryption_nonce_reuse/key_64.bin @@ -0,0 +1 @@ +QP!+U=i.d3'r" W0ʹ?⢠/ݰ&Wu[Ȅ"MFKÈJM$JBPƪ/` ߴXW \ No newline at end of file diff --git a/rust/fuzz/corpus/encryption_nonce_reuse/key_small.bin b/rust/fuzz/corpus/encryption_nonce_reuse/key_small.bin new file mode 100644 index 0000000..3db1e3f --- /dev/null +++ b/rust/fuzz/corpus/encryption_nonce_reuse/key_small.bin @@ -0,0 +1 @@ +QP!+U=i.d3'r"nonce_reuse_seed \ No newline at end of file diff --git a/rust/fuzz/corpus/encryption_roundtrip/key_compressible.bin b/rust/fuzz/corpus/encryption_roundtrip/key_compressible.bin new file mode 100644 index 0000000..3074b1d --- /dev/null +++ b/rust/fuzz/corpus/encryption_roundtrip/key_compressible.bin @@ -0,0 +1 @@ +QP!+U=i.d3'r"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \ No newline at end of file diff --git a/rust/fuzz/corpus/encryption_roundtrip/key_only.bin b/rust/fuzz/corpus/encryption_roundtrip/key_only.bin new file mode 100644 index 0000000..a928766 --- /dev/null +++ b/rust/fuzz/corpus/encryption_roundtrip/key_only.bin @@ -0,0 +1 @@ +QP!+U=i.d3'r" \ No newline at end of file diff --git a/rust/fuzz/corpus/encryption_roundtrip/key_random.bin b/rust/fuzz/corpus/encryption_roundtrip/key_random.bin new file mode 100644 index 0000000000000000000000000000000000000000..bf8a7a0fe0af9c03e691ccd8151da7345dd02bbd GIT binary patch literal 288 zcmV+*0pI=_4+WYA_fb$6^dT#btySoPJ=tk4WHXtb_a|~4@3A7@@31f*yz)Sfj2y0K zg`9U*IjqO#0f~nu!W1m`BXB3)%W+;ubuKN{$U1v#jvM&iYdd`5vy|GBI;dBqXMQ1` zw+u`Fpe zNnZ&X6_7adY=5W=HuGHQVgp`p8%klosz4zY|4dFJx*KQ(;XvA&+_{1+wC$2NVZm%h m^vWKDTlPf+969_zX9E+Or-3w@-@CDhNNAce!!8b6@~Y7d%Y{t< literal 0 HcmV?d00001 diff --git a/rust/fuzz/corpus/encryption_roundtrip/key_text.bin b/rust/fuzz/corpus/encryption_roundtrip/key_text.bin new file mode 100644 index 0000000..3805637 --- /dev/null +++ b/rust/fuzz/corpus/encryption_roundtrip/key_text.bin @@ -0,0 +1 @@ +QP!+U=i.d3'r"Hello, cachekit! MessagePack envelope roundtrip seed. \ No newline at end of file diff --git a/rust/fuzz/corpus/encryption_truncated_ciphertext/key_200.bin b/rust/fuzz/corpus/encryption_truncated_ciphertext/key_200.bin new file mode 100644 index 0000000..961cdfc --- /dev/null +++ b/rust/fuzz/corpus/encryption_truncated_ciphertext/key_200.bin @@ -0,0 +1 @@ +QP!+U=i.d3'r"s* zzr+zEI36ΕȠ$O!nAeaA`oTI.bOfbp}4Rcs\MȺ0jD}HofKl :6ϡG> -yĉkac%0LLsBm;~~ӤgDXjڰ[?SP,=Vw3% \ No newline at end of file diff --git a/rust/fuzz/corpus/encryption_truncated_ciphertext/key_512.bin b/rust/fuzz/corpus/encryption_truncated_ciphertext/key_512.bin new file mode 100644 index 0000000000000000000000000000000000000000..b8e01229ea362b84fa9a41ef6d4beffc4cfd65fa GIT binary patch literal 544 zcmV+*0^j`_4+WYA_fb$6^dT#btySoPJ=tk4WHXtb_a|~4@3A5lHnmIoCN-Z0DYP9n z%7s{x)GG?jwG%N9OVFzBh>@Gh1+K$E6hTMOQ+J#yFhuj&91Cg^kE0w?7lLK+m;+0B z9cy6!xjz+Lw~St$`-ug}Wsf6q`_MT@Rc2jp!Cu#%LK2uP*Y=Q5cNSlT25;~`d?~ial7{*hLa3)k6k*H1!Qk-QdVb=hW zAZdsxaUfA37@SRFZBQMM1%oMSvnFI(crd{8%4-L&$wte4AE)=5+%qb`08H;vZA14< zn-YN(sc3x8Xhro}pkTKU`qa~NT%)kfI+t-YY*3>5v57cB^0TBY@hS!(Ms}f2Caq$X z;o!b_=l9P)-rLO3UjC4Meg(giI4~c6QgT2nt~48WaAa68#rPb%S9pvulZ ziXb@GNFS^H%7L#+FzAYf`2{4c?Fq}!qyg;G^CzPIMHlIWcEwdzV!suLbE)^Ey_r5J<-4l%>h`WQAOTw)g)CgUc@jAbtqS7DHTmgs`ceeeO&?ADf%w5@ z7s32F4*Ppjia@L>4PP0JQt%%YJ>1s|n=3fqaMB3+_tnT`+bj`wU=9=X%c~Ioii;Cz iu3vEdKqz1K2V@X$u?Tq{$>`I;><-YU9P?hyAla6Y0s*Z6 literal 0 HcmV?d00001 diff --git a/rust/fuzz/corpus/encryption_truncated_ciphertext/key_min.bin b/rust/fuzz/corpus/encryption_truncated_ciphertext/key_min.bin new file mode 100644 index 0000000..98274fe --- /dev/null +++ b/rust/fuzz/corpus/encryption_truncated_ciphertext/key_min.bin @@ -0,0 +1 @@ +QP!+U=i.d3'r"tc \ No newline at end of file diff --git a/rust/fuzz/corpus/integration_layered_security/key_compressible.bin b/rust/fuzz/corpus/integration_layered_security/key_compressible.bin new file mode 100644 index 0000000..8ebe320 --- /dev/null +++ b/rust/fuzz/corpus/integration_layered_security/key_compressible.bin @@ -0,0 +1 @@ +QP!+U=i.d3'r"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \ No newline at end of file diff --git a/rust/fuzz/corpus/integration_layered_security/key_random.bin b/rust/fuzz/corpus/integration_layered_security/key_random.bin new file mode 100644 index 0000000..9cf3e92 --- /dev/null +++ b/rust/fuzz/corpus/integration_layered_security/key_random.bin @@ -0,0 +1 @@ +QP!+U=i.d3'r"CQHs.Ƶ8anEv0hvrc0AbF]Ѷ:6nf?w= 9f3Nm"5h&k${b ABU \ No newline at end of file diff --git a/rust/fuzz/corpus/integration_layered_security/key_text.bin b/rust/fuzz/corpus/integration_layered_security/key_text.bin new file mode 100644 index 0000000..64d41b5 --- /dev/null +++ b/rust/fuzz/corpus/integration_layered_security/key_text.bin @@ -0,0 +1 @@ +QP!+U=i.d3'r"Hello, cachekit! MessagePack envelope roundtrip seed. layered. layered. layered. layered. \ No newline at end of file diff --git a/rust/fuzz/scripts/generate_corpus.sh b/rust/fuzz/scripts/generate_corpus.sh index 59f01e5..4c6a99d 100755 --- a/rust/fuzz/scripts/generate_corpus.sh +++ b/rust/fuzz/scripts/generate_corpus.sh @@ -1,342 +1,231 @@ #!/usr/bin/env bash set -euo pipefail -# Corpus generation script for cachekit fuzzing -# Extracts samples from test fixtures and generates edge cases +# Corpus generation for cachekit fuzzing. +# +# Writes seeds into corpus// — one directory per [[bin]] name in +# Cargo.toml, because that is the layout `cargo fuzz run ` loads by +# default. (A previous version wrote a category tree, corpus/byte_storage/…, +# which no target ever read: LAB-1149.) +# +# Deterministic: same script version → byte-identical seeds, so re-runs +# produce clean git diffs. Valid StorageEnvelope seeds are byte-exact against +# cachekit-core 0.4.0's wire format (raw LZ4 block + xxHash3-64 big-endian +# checksum + rmp-serde array-form msgpack), verified against the crate's +# pinned empty-input checksum test vector. SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" FUZZ_DIR="$(dirname "$SCRIPT_DIR")" CORPUS_DIR="$FUZZ_DIR/corpus" -PROJECT_ROOT="$(cd "$FUZZ_DIR/../.." && pwd)" echo "=== Cachekit Fuzzing Corpus Generator ===" echo "Corpus directory: $CORPUS_DIR" -echo "Project root: $PROJECT_ROOT" -# Cleanup function -cleanup_corpus() { - local category=$1 - local max_size_mb=${2:-10} - - local total_size=$(du -sm "$CORPUS_DIR/$category" 2>/dev/null | cut -f1 || echo "0") - if [ "$total_size" -gt "$max_size_mb" ]; then - echo "WARNING: $category corpus is ${total_size}MB (limit: ${max_size_mb}MB)" - echo "Run minimize_corpus.sh to reduce size" +if ! command -v python3 &>/dev/null; then + echo "ERROR: python3 is required for corpus generation" + exit 1 +fi + +# msgpack for envelope framing; lz4 + xxhash to mint envelopes whose checksum +# actually verifies — those are the seeds that reach extract()'s deepest +# branch (checksum check runs AFTER decompression; random bytes never get +# there). With uv: uv run --no-project --with lz4 --with xxhash --with msgpack … +for mod in msgpack lz4.block xxhash; do + if ! python3 -c "import $mod" 2>/dev/null; then + echo "ERROR: Python module '$mod' is required" + echo "Install with: pip install msgpack lz4 xxhash" + echo "Or run via uv: uv run --no-project --with msgpack --with lz4 --with xxhash bash scripts/generate_corpus.sh" + exit 1 fi -} - -# Generate ByteStorage corpus samples -generate_byte_storage_corpus() { - echo "" - echo "=== Generating ByteStorage Corpus ===" - - local valid_dir="$CORPUS_DIR/byte_storage/valid_envelopes" - local corrupted_dir="$CORPUS_DIR/byte_storage/corrupted_envelopes" - local size_dir="$CORPUS_DIR/byte_storage/size_edge_cases" - local format_dir="$CORPUS_DIR/byte_storage/format_strings" - - # Create valid envelope samples using Python - echo "Creating valid MessagePack envelopes..." - python3 - "$valid_dir" <<'PYTHON' -import sys -import msgpack -from pathlib import Path - -corpus_dir = Path(sys.argv[1]) -corpus_dir.mkdir(parents=True, exist_ok=True) +done -# Sample 1: Minimal valid envelope -envelope = { - "format": "msgpack", - "original_size": 13, - "compressed_data": b"hello, world!", - "checksum": b"\x00" * 32, # Placeholder Blake3 checksum -} -(corpus_dir / "minimal.msgpack").write_bytes(msgpack.packb(envelope)) - -# Sample 2: Larger payload -envelope = { - "format": "json", - "original_size": 1000, - "compressed_data": b"x" * 1000, - "checksum": b"\x00" * 32, -} -(corpus_dir / "large.msgpack").write_bytes(msgpack.packb(envelope)) - -# Sample 3: Unicode format string -envelope = { - "format": "utf8_text_\u2728", - "original_size": 50, - "compressed_data": b"unicode test data" * 3, - "checksum": b"\xff" * 32, -} -(corpus_dir / "unicode.msgpack").write_bytes(msgpack.packb(envelope)) - -print(f"Created 3 valid envelope samples in {corpus_dir}") -PYTHON - - # Generate corrupted envelopes - echo "Creating corrupted envelope samples..." - python3 - "$corrupted_dir" <<'PYTHON' +python3 - "$CORPUS_DIR" <<'PYTHON' +import random import sys -import msgpack from pathlib import Path -corpus_dir = Path(sys.argv[1]) -corpus_dir.mkdir(parents=True, exist_ok=True) - -# Corrupted sample 1: Missing fields -(corpus_dir / "missing_fields.msgpack").write_bytes(msgpack.packb({"format": "msgpack"})) - -# Corrupted sample 2: Wrong types -envelope = { - "format": 12345, # Should be string - "original_size": "invalid", # Should be int - "compressed_data": "not_bytes", # Should be bytes - "checksum": b"\x00" * 32, -} -(corpus_dir / "wrong_types.msgpack").write_bytes(msgpack.packb(envelope)) - -# Corrupted sample 3: Truncated MessagePack -full_envelope = msgpack.packb({ - "format": "msgpack", - "original_size": 100, - "compressed_data": b"x" * 100, - "checksum": b"\x00" * 32, -}) -(corpus_dir / "truncated.msgpack").write_bytes(full_envelope[:len(full_envelope)//2]) - -# Corrupted sample 4: Invalid MessagePack bytes -(corpus_dir / "invalid_msgpack.bin").write_bytes(b"\xff\xff\xff\xff\xff\xff\xff\xff") - -print(f"Created 4 corrupted envelope samples in {corpus_dir}") -PYTHON - - # Generate size edge cases - echo "Creating size edge case samples..." - python3 - "$size_dir" <<'PYTHON' -import sys +import lz4.block import msgpack -from pathlib import Path - -corpus_dir = Path(sys.argv[1]) -corpus_dir.mkdir(parents=True, exist_ok=True) - -# Edge case 1: Zero size -envelope = { - "format": "msgpack", - "original_size": 0, - "compressed_data": b"", - "checksum": b"\x00" * 32, -} -(corpus_dir / "zero_size.msgpack").write_bytes(msgpack.packb(envelope)) - -# Edge case 2: Single byte -envelope = { - "format": "msgpack", - "original_size": 1, - "compressed_data": b"x", - "checksum": b"\x00" * 32, +import xxhash + +corpus = Path(sys.argv[1]) +# Deterministic PRNG: reproducible corpus, clean diffs on regeneration. +rng = random.Random(0xCAC4E) + +written = {} + + +def seed(target: str, name: str, data: bytes) -> None: + d = corpus / target + d.mkdir(parents=True, exist_ok=True) + (d / name).write_bytes(data) + written[target] = written.get(target, 0) + 1 + + +def envelope(data: bytes, fmt: str = "msgpack") -> bytes: + """Byte-exact StorageEnvelope: what ByteStorage::store() emits for `data`. + + rmp-serde array form: [bin(compressed), [8 checksum ints], u32 size, str]. + compressed_data is a raw LZ4 block (lz4_flex::compress — no size prefix); + checksum is xxh3_64(data).to_be_bytes(). + """ + compressed = lz4.block.compress(data, store_size=False) + checksum = list(xxhash.xxh3_64(data).digest()) # digest() is big-endian + return msgpack.packb([compressed, checksum, len(data), fmt], use_bin_type=True) + + +# ── Shared payloads ───────────────────────────────────────────────────────── +text = b"Hello, cachekit! MessagePack envelope roundtrip seed." +compressible = b"a" * 2048 +gradient = bytes(range(256)) * 4 +random_1k = rng.randbytes(1024) +key32 = rng.randbytes(32) + +# ── byte_storage_compress: raw plaintext in, store()/retrieve() roundtrip ── +seed("byte_storage_compress", "empty.bin", b"") +seed("byte_storage_compress", "single_byte.bin", b"a") +seed("byte_storage_compress", "text.bin", text) +seed("byte_storage_compress", "compressible.bin", compressible) +seed("byte_storage_compress", "gradient.bin", gradient) +seed("byte_storage_compress", "random_1k.bin", random_1k) +seed("byte_storage_compress", "unicode.bin", "café ✨ 한국어 テスト".encode()) + +# ── byte_storage_decompress + byte_storage_corrupted_envelope: +# both parse envelope bytes (retrieve() / rmp_serde::from_slice) ───────── +valid_text = envelope(text) +valid_comp = envelope(compressible) + +corrupted_payload = bytearray(valid_comp) +corrupted_payload[len(corrupted_payload) // 2] ^= 0xFF # checksum mismatch + +env_samples = { + "valid_text.bin": valid_text, + "valid_compressible.bin": valid_comp, + "valid_gradient.bin": envelope(gradient), + "valid_random.bin": envelope(random_1k), + "valid_unicode_format.bin": envelope(text, fmt="utf8_✨"), + "corrupted_payload.bin": bytes(corrupted_payload), + "truncated.bin": valid_text[: len(valid_text) // 2], + "wrong_checksum.bin": msgpack.packb( + [lz4.block.compress(text, store_size=False), [0] * 8, len(text), "msgpack"], + use_bin_type=True, + ), + "size_mismatch.bin": msgpack.packb( + [ + lz4.block.compress(text, store_size=False), + list(xxhash.xxh3_64(text).digest()), + len(text) + 1, + "msgpack", + ], + use_bin_type=True, + ), + "decompression_bomb.bin": msgpack.packb( + [b"\x00\x01\x02\x03", [0] * 8, 4_294_967_295, "msgpack"], + use_bin_type=True, + ), + "empty_compressed.bin": msgpack.packb( + [b"", [0] * 8, 100, "msgpack"], use_bin_type=True + ), + "missing_fields.bin": msgpack.packb([b"only_one_field"], use_bin_type=True), + "map_form.bin": msgpack.packb( + { + "compressed_data": lz4.block.compress(text, store_size=False), + "checksum": list(xxhash.xxh3_64(text).digest()), + "original_size": len(text), + "format": "msgpack", + }, + use_bin_type=True, + ), + "invalid_msgpack.bin": b"\xff" * 8, } -(corpus_dir / "single_byte.msgpack").write_bytes(msgpack.packb(envelope)) - -# Edge case 3: u32::MAX original_size (overflow attack) -envelope = { - "format": "msgpack", - "original_size": 4294967295, # u32::MAX - "compressed_data": b"small", - "checksum": b"\x00" * 32, -} -(corpus_dir / "u32_max.msgpack").write_bytes(msgpack.packb(envelope)) - -# Edge case 4: Suspicious compression ratio -envelope = { - "format": "msgpack", - "original_size": 10_000_000, # 10MB claimed - "compressed_data": b"tiny", # 4 bytes actual - "checksum": b"\x00" * 32, -} -(corpus_dir / "suspicious_ratio.msgpack").write_bytes(msgpack.packb(envelope)) - -print(f"Created 4 size edge case samples in {corpus_dir}") -PYTHON - - # Generate format string samples - echo "Creating format string injection samples..." - python3 - "$format_dir" <<'PYTHON' -import sys -import msgpack -from pathlib import Path - -corpus_dir = Path(sys.argv[1]) -corpus_dir.mkdir(parents=True, exist_ok=True) - -malicious_formats = [ - "../../../etc/passwd", # Path traversal - "fmt\x00null", # Null byte - "fmt\nCRLF\r", # Control characters - "\u202ERTL", # Unicode RTL override - "x" * 10000, # Very long string -] - -for i, fmt in enumerate(malicious_formats): - envelope = { - "format": fmt, - "original_size": 100, - "compressed_data": b"x" * 100, - "checksum": b"\x00" * 32, - } - (corpus_dir / f"injection_{i}.msgpack").write_bytes(msgpack.packb(envelope)) - -print(f"Created {len(malicious_formats)} format injection samples in {corpus_dir}") +for name, data in env_samples.items(): + seed("byte_storage_decompress", name, data) + seed("byte_storage_corrupted_envelope", name, data) + +# ── byte_storage_format_injection: raw bytes become the format string ────── +seed("byte_storage_format_injection", "normal.bin", b"msgpack") +seed("byte_storage_format_injection", "path_traversal.bin", b"../../../etc/passwd") +seed("byte_storage_format_injection", "null_byte.bin", b"fmt\x00null") +seed("byte_storage_format_injection", "control_chars.bin", b"fmt\nCRLF\r") +seed("byte_storage_format_injection", "rtl_override.bin", "‮rtl".encode()) +seed("byte_storage_format_injection", "bom.bin", "bom".encode()) +seed("byte_storage_format_injection", "long_10k.bin", b"x" * 10_000) + +# ── Arbitrary-derived targets: seeds are raw bytes consumed by the derive. +# Exact field mapping is an implementation detail of `arbitrary`, so these +# are varied starting points, not precision-crafted structs. ───────────── +# byte_storage_integer_overflow: (u32, u8, [u8;8], u8) ≈ 14 bytes +seed("byte_storage_integer_overflow", "zeros.bin", b"\x00" * 14) +seed("byte_storage_integer_overflow", "u32_max.bin", b"\xff\xff\xff\xff" + b"\x10" + b"\xaa" * 8 + b"\x04") +seed("byte_storage_integer_overflow", "boundary_512mb.bin", b"\x00\x00\x00\x20" + b"\xff" + b"\x55" * 8 + b"\x08") +seed("byte_storage_integer_overflow", "random_a.bin", rng.randbytes(14)) +seed("byte_storage_integer_overflow", "random_b.bin", rng.randbytes(16)) + +# byte_storage_checksum_collision: (Vec, u32, u8) +seed("byte_storage_checksum_collision", "small.bin", rng.randbytes(24)) +seed("byte_storage_checksum_collision", "medium.bin", rng.randbytes(256)) +seed("byte_storage_checksum_collision", "large.bin", rng.randbytes(1024)) +seed("byte_storage_checksum_collision", "compressible.bin", b"a" * 512 + rng.randbytes(8)) + +# byte_storage_empty_data: (u32, u8, [u8;8]) ≈ 13 bytes +seed("byte_storage_empty_data", "zeros.bin", b"\x00" * 13) +seed("byte_storage_empty_data", "size_no_data.bin", b"\xe8\x03\x00\x00" + b"\x00" + b"\x00" * 8) +seed("byte_storage_empty_data", "data_no_size.bin", b"\x00\x00\x00\x00" + b"\x40" + b"\x11" * 8) +seed("byte_storage_empty_data", "random.bin", rng.randbytes(13)) + +# ── Encryption targets: input = 32-byte key ++ plaintext ──────────────────── +seed("encryption_roundtrip", "key_only.bin", key32) +seed("encryption_roundtrip", "key_text.bin", key32 + text) +seed("encryption_roundtrip", "key_compressible.bin", key32 + compressible) +seed("encryption_roundtrip", "key_random.bin", key32 + rng.randbytes(256)) + +# encryption_key_derivation: 16-byte master key ++ tenant salt +mk16 = rng.randbytes(16) +seed("encryption_key_derivation", "normal_tenant.bin", mk16 + b"customer-12345") +seed("encryption_key_derivation", "path_traversal.bin", mk16 + b"../../../admin") +seed("encryption_key_derivation", "null_byte.bin", mk16 + b"tenant\x00null") +seed("encryption_key_derivation", "bom.bin", mk16 + "bom_tenant".encode()) +seed("encryption_key_derivation", "empty_tenant.bin", mk16) +seed("encryption_key_derivation", "unicode.bin", mk16 + "한국어✨".encode()) +seed("encryption_key_derivation", "long_tenant.bin", mk16 + b"x" * 4096) + +# encryption_nonce_reuse: small plaintexts → 100-iteration uniqueness loop +seed("encryption_nonce_reuse", "key_small.bin", key32 + b"nonce_reuse_seed") +seed("encryption_nonce_reuse", "key_64.bin", key32 + rng.randbytes(64)) + +# encryption_truncated_ciphertext: total must be in 32..=1024 +seed("encryption_truncated_ciphertext", "key_min.bin", key32 + b"tc") +seed("encryption_truncated_ciphertext", "key_200.bin", key32 + rng.randbytes(200)) +seed("encryption_truncated_ciphertext", "key_512.bin", key32 + rng.randbytes(512)) + +# encryption_aad_injection: needs 32-byte key + ≥100 bytes (split plaintext/AAD) +seed("encryption_aad_injection", "key_128.bin", key32 + b"p" * 64 + b"aad_normal" + b"q" * 54) +seed("encryption_aad_injection", "key_nulls.bin", key32 + b"p" * 60 + b"aad\x00null\x00" + b"q" * 50) +seed("encryption_aad_injection", "key_random.bin", key32 + rng.randbytes(1000)) + +# encryption_large_payload: sizes libFuzzer is slow to grow into on its own +seed("encryption_large_payload", "key_1k.bin", key32 + rng.randbytes(1024)) +seed("encryption_large_payload", "key_16k_compressible.bin", key32 + b"a" * 16_384) +seed("encryption_large_payload", "key_64k.bin", key32 + rng.randbytes(65_536)) +seed("encryption_large_payload", "key_256k_compressible.bin", key32 + b"ab" * 131_072) +seed("encryption_large_payload", "key_100k_random.bin", key32 + rng.randbytes(102_400)) + +# integration_layered_security: 32-byte key + plaintext (total ≥ 64, ≤ 4096+32) +seed("integration_layered_security", "key_text.bin", key32 + text + b" layered." * 4) +seed("integration_layered_security", "key_compressible.bin", key32 + b"a" * 512) +seed("integration_layered_security", "key_random.bin", key32 + rng.randbytes(128)) + +total = sum(written.values()) +print(f"Wrote {total} seeds across {len(written)} target directories:") +for target in sorted(written): + print(f" corpus/{target}/: {written[target]} seeds") PYTHON - cleanup_corpus "byte_storage" 5 -} - -# Generate Encryption corpus samples -generate_encryption_corpus() { - echo "" - echo "=== Generating Encryption Corpus ===" - - local key_dir="$CORPUS_DIR/encryption/key_material" - local tenant_dir="$CORPUS_DIR/encryption/tenant_ids" - local aad_dir="$CORPUS_DIR/encryption/aad_patterns" - local ciphertext_dir="$CORPUS_DIR/encryption/ciphertext_samples" - - # Generate key material samples - echo "Creating key material samples..." - mkdir -p "$key_dir" - dd if=/dev/urandom of="$key_dir/valid_32byte.key" bs=32 count=1 2>/dev/null - dd if=/dev/urandom of="$key_dir/zeros.key" bs=32 count=1 2>/dev/null /dev/null | tr '\0' '\377' - echo "Created 3 key material samples" - - # Generate tenant ID samples - echo "Creating tenant ID samples..." - mkdir -p "$tenant_dir" - echo -n "customer-12345" > "$tenant_dir/normal.txt" - echo -n "../../../admin" > "$tenant_dir/path_traversal.txt" - printf "tenant\x00null" > "$tenant_dir/null_byte.bin" - echo -n "tenant$(printf '\n')CRLF$(printf '\r')" > "$tenant_dir/control_chars.txt" - python3 -c "print('\uFEFF' + 'BOM_tenant', end='')" > "$tenant_dir/unicode_bom.txt" - python3 -c "print('x' * 10000, end='')" > "$tenant_dir/very_long.txt" - echo "Created 6 tenant ID samples" - - # Generate AAD pattern samples - echo "Creating AAD pattern samples..." - mkdir -p "$aad_dir" - echo -n "cache_key_12345" > "$aad_dir/normal.txt" - printf "aad\x00null" > "$aad_dir/null_byte.bin" - printf "aad\n\r\t" > "$aad_dir/control_chars.bin" - python3 -c "print('a' * 10000, end='')" > "$aad_dir/very_long.txt" - echo -n "" > "$aad_dir/empty.txt" - echo "Created 5 AAD pattern samples" - - # Generate ciphertext samples (using Python) - echo "Creating ciphertext samples..." - python3 - "$ciphertext_dir" <<'PYTHON' -import sys -from pathlib import Path - -corpus_dir = Path(sys.argv[1]) -corpus_dir.mkdir(parents=True, exist_ok=True) - -# Sample 1: Valid-looking ciphertext structure (12-byte nonce + data + 16-byte tag) -nonce = b"\x00" * 12 -ciphertext_body = b"encrypted_data_here" -auth_tag = b"\xff" * 16 -(corpus_dir / "valid_structure.bin").write_bytes(nonce + ciphertext_body + auth_tag) - -# Sample 2: Truncated nonce -(corpus_dir / "truncated_nonce.bin").write_bytes(b"\x00" * 6) - -# Sample 3: Missing auth tag -(corpus_dir / "missing_auth_tag.bin").write_bytes(b"\x00" * 12 + b"data") - -# Sample 4: Empty ciphertext -(corpus_dir / "empty.bin").write_bytes(b"") - -print(f"Created 4 ciphertext samples in {corpus_dir}") -PYTHON - - cleanup_corpus "encryption" 3 -} - -# Generate Integration corpus samples -generate_integration_corpus() { - echo "" - echo "=== Generating Integration Corpus ===" - - local layered_dir="$CORPUS_DIR/integration/layered_data" - mkdir -p "$layered_dir" - - echo "Creating layered (compressed + encrypted) samples..." - python3 - "$layered_dir" <<'PYTHON' -import sys -import msgpack -from pathlib import Path - -corpus_dir = Path(sys.argv[1]) -corpus_dir.mkdir(parents=True, exist_ok=True) - -# Sample 1: Valid envelope that could be encrypted -envelope = { - "format": "msgpack", - "original_size": 100, - "compressed_data": b"x" * 100, - "checksum": b"\x00" * 32, -} -envelope_bytes = msgpack.packb(envelope) - -# Simulate "encrypted" version (nonce + envelope + tag) -nonce = b"\x00" * 12 -auth_tag = b"\xff" * 16 -layered = nonce + envelope_bytes + auth_tag -(corpus_dir / "valid_layered.bin").write_bytes(layered) - -# Sample 2: Corrupted inner envelope -corrupted_envelope = msgpack.packb({"format": "msgpack"}) # Missing fields -layered = b"\x00" * 12 + corrupted_envelope + b"\xff" * 16 -(corpus_dir / "corrupted_inner.bin").write_bytes(layered) - -print(f"Created 2 integration samples in {corpus_dir}") -PYTHON - - cleanup_corpus "integration" 2 -} - -# Main execution -main() { - echo "Starting corpus generation..." - - # Check Python availability - if ! command -v python3 &> /dev/null; then - echo "ERROR: python3 is required for corpus generation" - exit 1 - fi - - # Check msgpack availability - if ! python3 -c "import msgpack" 2>/dev/null; then - echo "ERROR: Python msgpack library is required" - echo "Install with: pip install msgpack" - exit 1 - fi - - generate_byte_storage_corpus - generate_encryption_corpus - generate_integration_corpus - - echo "" - echo "=== Corpus Generation Complete ===" - echo "Total corpus size:" - du -sh "$CORPUS_DIR" - - echo "" - echo "Next steps:" - echo " 1. Review corpus: find $CORPUS_DIR -type f ! -name '.gitkeep'" - echo " 2. Minimize corpus: ./scripts/minimize_corpus.sh" - echo " 3. Validate corpus: ./scripts/validate_corpus.sh" -} - -main "$@" +echo "" +echo "=== Corpus Generation Complete ===" +du -sh "$CORPUS_DIR" +echo "" +echo "Next steps:" +echo " 1. Validate layout matches Cargo.toml targets: ./scripts/validate_corpus.sh" +echo " 2. Sanity-run every seed once: cargo +nightly fuzz run -- -runs=0" +echo " 3. After growth runs, minimize: ./scripts/minimize_corpus.sh" diff --git a/rust/fuzz/scripts/minimize_corpus.sh b/rust/fuzz/scripts/minimize_corpus.sh index 0263484..4b4db49 100755 --- a/rust/fuzz/scripts/minimize_corpus.sh +++ b/rust/fuzz/scripts/minimize_corpus.sh @@ -17,23 +17,15 @@ if ! command -v cargo-fuzz &> /dev/null; then exit 1 fi -# All fuzz targets (must match Cargo.toml) -FUZZ_TARGETS=( - "byte_storage_compress" - "byte_storage_decompress" - "encryption_roundtrip" - "byte_storage_corrupted_envelope" - "byte_storage_integer_overflow" - "byte_storage_checksum_collision" - "byte_storage_empty_data" - "byte_storage_format_injection" - "encryption_key_derivation" - "encryption_nonce_reuse" - "encryption_truncated_ciphertext" - "encryption_aad_injection" - "encryption_large_payload" - "integration_layered_security" -) +# Targets derived from the [[bin]] stanzas in Cargo.toml — the same source +# `cargo fuzz list`, the Makefile, and validate_corpus.sh read. A +# hand-maintained copy here is the drift hazard that buried the original +# corpus (LAB-1149). +mapfile -t FUZZ_TARGETS < <(grep -A1 '^\[\[bin\]\]' "$FUZZ_DIR/Cargo.toml" | sed -n 's/^name = "\(.*\)"/\1/p') +if [ "${#FUZZ_TARGETS[@]}" -eq 0 ]; then + echo "ERROR: no [[bin]] targets found in $FUZZ_DIR/Cargo.toml" + exit 1 +fi # Function to minimize corpus for a single target minimize_target() { @@ -58,18 +50,18 @@ minimize_target() { echo "" echo "Minimizing $target corpus (${before_count} files, ${before_size})..." - # Run corpus minimization + # Run corpus minimization — a failed cmin fails the script (targets are + # derived from Cargo.toml, so "target may not exist" is a real error). cd "$FUZZ_DIR" - if cargo fuzz cmin "$target" 2>&1 | grep -E "(Minimizing|files|testcases)"; then - # Count files after minimization - local after_count=$(find "$corpus_path" -type f ! -name '.gitkeep' | wc -l | tr -d ' ') - local after_size=$(du -sh "$corpus_path" 2>/dev/null | cut -f1 || echo "0B") - - local removed=$((before_count - after_count)) - echo "✅ Minimized $target: ${before_count} → ${after_count} files (-${removed}), ${before_size} → ${after_size}" - else - echo "⚠️ Minimization failed for $target (target may not exist yet)" + if ! cargo fuzz cmin "$target"; then + echo "❌ Minimization failed for $target" + exit 1 fi + + local after_count=$(find "$corpus_path" -type f ! -name '.gitkeep' | wc -l | tr -d ' ') + local after_size=$(du -sh "$corpus_path" 2>/dev/null | cut -f1 || echo "0B") + local removed=$((before_count - after_count)) + echo "✅ Minimized $target: ${before_count} → ${after_count} files (-${removed}), ${before_size} → ${after_size}" } # Main execution diff --git a/rust/fuzz/scripts/validate_corpus.sh b/rust/fuzz/scripts/validate_corpus.sh index e4d5287..c15a13b 100755 --- a/rust/fuzz/scripts/validate_corpus.sh +++ b/rust/fuzz/scripts/validate_corpus.sh @@ -1,8 +1,24 @@ #!/usr/bin/env bash set -euo pipefail -# Corpus validation script for cachekit fuzzing -# Reports corpus health metrics and validates integrity +# Corpus validation for cachekit fuzzing. +# +# The corpus contract: one seed directory per [[bin]] target in Cargo.toml, +# at corpus// — the layout `cargo fuzz run ` loads by default. +# This script fails if any target has no seeds (the drift that buried the +# original corpus: LAB-1149) or if the total exceeds the 10MB CI budget. + +if [ "${1:-}" = "--help" ] || [ "${1:-}" = "-h" ]; then + echo "Usage: $0" + echo "" + echo "Validate the per-target fuzzing corpus." + echo "" + echo "Checks:" + echo " - Every [[bin]] target in Cargo.toml has a non-empty corpus//" + echo " - Total corpus size within the 10MB CI budget" + echo " - Flags individual seeds over 1MB" + exit 0 +fi SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" FUZZ_DIR="$(dirname "$SCRIPT_DIR")" @@ -12,136 +28,72 @@ echo "=== Cachekit Fuzzing Corpus Validator ===" echo "Corpus directory: $CORPUS_DIR" echo "" -# Check if corpus directory exists if [ ! -d "$CORPUS_DIR" ]; then echo "ERROR: Corpus directory does not exist: $CORPUS_DIR" exit 1 fi -# Validate single category -validate_category() { - local category=$1 - local category_path="$CORPUS_DIR/$category" - - if [ ! -d "$category_path" ]; then - echo "⏭️ Skipping $category (directory not found)" - return - fi - - echo "📊 Category: $category" +# Same target derivation as the Makefile and CI: the [[bin]] stanzas are the +# single source of truth, so a new target automatically becomes a required +# corpus directory here. +TARGETS=$(grep -A1 '^\[\[bin\]\]' "$FUZZ_DIR/Cargo.toml" | sed -n 's/^name = "\(.*\)"/\1/p') +if [ -z "$TARGETS" ]; then + echo "ERROR: no [[bin]] targets found in $FUZZ_DIR/Cargo.toml" + exit 1 +fi - # Count files (excluding .gitkeep) - local file_count=$(find "$category_path" -type f ! -name '.gitkeep' | wc -l | tr -d ' ') - local dir_count=$(find "$category_path" -mindepth 1 -type d | wc -l | tr -d ' ') +failures=0 - # Get size metrics - local total_size=$(du -sh "$category_path" 2>/dev/null | cut -f1 || echo "0B") - local total_bytes=$(du -sb "$category_path" 2>/dev/null | cut -f1 || echo "0") +for target in $TARGETS; do + target_dir="$CORPUS_DIR/$target" - # Calculate average file size - local avg_size="N/A" - if [ "$file_count" -gt 0 ] && [ "$total_bytes" -gt 0 ]; then - avg_size=$(awk "BEGIN {printf \"%.1f\", $total_bytes / $file_count / 1024}") - avg_size="${avg_size}KB" + if [ ! -d "$target_dir" ]; then + echo "❌ $target: corpus/$target/ missing" + echo " Run scripts/generate_corpus.sh (and add seeds for new targets to it)" + failures=$((failures + 1)) + continue fi - echo " Files: $file_count" - echo " Subdirectories: $dir_count" - echo " Total size: $total_size" - echo " Average file size: $avg_size" - - # Validate file integrity - if [ "$file_count" -gt 0 ]; then - # Check for empty files - local empty_count=$(find "$category_path" -type f ! -name '.gitkeep' -size 0 | wc -l | tr -d ' ') - if [ "$empty_count" -gt 0 ]; then - echo " ⚠️ Warning: $empty_count empty files found" - fi - - # Check for very large files (>1MB) - local large_files=$(find "$category_path" -type f ! -name '.gitkeep' -size +1M) - if [ -n "$large_files" ]; then - local large_count=$(echo "$large_files" | wc -l | tr -d ' ') - echo " ⚠️ Warning: $large_count files exceed 1MB" - echo "$large_files" | while read -r file; do - local size=$(du -sh "$file" | cut -f1) - echo " - $(basename "$file"): $size" - done - fi - - # List subdirectories with counts - if [ "$dir_count" -gt 0 ]; then - echo " Subdirectory breakdown:" - find "$category_path" -mindepth 1 -maxdepth 1 -type d | while read -r subdir; do - local sub_count=$(find "$subdir" -type f ! -name '.gitkeep' | wc -l | tr -d ' ') - local sub_size=$(du -sh "$subdir" 2>/dev/null | cut -f1 || echo "0B") - echo " - $(basename "$subdir"): $sub_count files, $sub_size" - done - fi - else - echo " ℹ️ Empty corpus (run generate_corpus.sh to populate)" + file_count=$(find "$target_dir" -type f ! -name '.gitkeep' | wc -l | tr -d ' ') + if [ "$file_count" -eq 0 ]; then + echo "❌ $target: corpus/$target/ has no seeds" + failures=$((failures + 1)) + continue fi - echo "" -} - -# Main execution -main() { - echo "=== Corpus Structure Validation ===" - echo "" - - # Validate each major category - validate_category "byte_storage" - validate_category "encryption" - validate_category "integration" - - # Overall corpus statistics - echo "=== Overall Corpus Statistics ===" - local total_files=$(find "$CORPUS_DIR" -type f ! -name '.gitkeep' | wc -l | tr -d ' ') - local total_size=$(du -sh "$CORPUS_DIR" 2>/dev/null | cut -f1 || echo "0B") - local total_mb=$(du -sm "$CORPUS_DIR" 2>/dev/null | cut -f1 || echo "0") - - echo "Total files: $total_files" - echo "Total size: $total_size (${total_mb}MB)" - echo "" + size=$(du -sh "$target_dir" 2>/dev/null | cut -f1 || echo "0B") + echo "✅ $target: $file_count seeds, $size" - # Validate against 10MB target - if [ "$total_mb" -gt 10 ]; then - echo "❌ VALIDATION FAILED: Corpus size (${total_mb}MB) exceeds 10MB target" - echo " Run minimize_corpus.sh to reduce size" - exit 1 - elif [ "$total_mb" -gt 8 ]; then - echo "⚠️ WARNING: Corpus size (${total_mb}MB) is approaching 10MB limit" - echo " Consider running minimize_corpus.sh" - else - echo "✅ VALIDATION PASSED: Corpus size (${total_mb}MB) is within 10MB target" + # Oversized seeds slow every fuzz run that loads them + large_files=$(find "$target_dir" -type f -size +1M) + if [ -n "$large_files" ]; then + echo " ⚠️ seeds over 1MB:" + echo "$large_files" | while read -r f; do + echo " - $(basename "$f"): $(du -sh "$f" | cut -f1)" + done fi +done - # Check for recommended minimum corpus size - if [ "$total_files" -lt 10 ]; then - echo "⚠️ WARNING: Corpus has only $total_files files (recommend 50+)" - echo " Run generate_corpus.sh to populate corpus" - else - echo "✅ Corpus has sufficient samples ($total_files files)" - fi +echo "" +echo "=== Overall Corpus Statistics ===" +total_files=$(find "$CORPUS_DIR" -type f ! -name '.gitkeep' ! -name 'CORPUS_INFO.md' | wc -l | tr -d ' ') +total_size=$(du -sh "$CORPUS_DIR" 2>/dev/null | cut -f1 || echo "0B") +total_mb=$(du -sm "$CORPUS_DIR" 2>/dev/null | cut -f1 || echo "0") +echo "Total seeds: $total_files" +echo "Total size: $total_size (${total_mb}MB)" +echo "" - echo "" - echo "=== Validation Complete ===" -} +if [ "$total_mb" -gt 10 ]; then + echo "❌ VALIDATION FAILED: corpus size (${total_mb}MB) exceeds 10MB CI budget" + echo " Run minimize_corpus.sh or drop oversized seeds" + failures=$((failures + 1)) +elif [ "$total_mb" -gt 8 ]; then + echo "⚠️ WARNING: corpus size (${total_mb}MB) is approaching the 10MB budget" +fi -# Usage information -if [ "${1:-}" = "--help" ] || [ "${1:-}" = "-h" ]; then - echo "Usage: $0" - echo "" - echo "Validate fuzzing corpus integrity and report health metrics." - echo "" - echo "Checks:" - echo " - Corpus size (must be < 10MB for CI)" - echo " - File counts per category" - echo " - Empty files" - echo " - Oversized files (> 1MB)" - echo " - Directory structure" - exit 0 +if [ "$failures" -gt 0 ]; then + echo "❌ VALIDATION FAILED: $failures problem(s) above" + exit 1 fi -main "$@" +echo "✅ VALIDATION PASSED: every target has seeds, size within budget" From 2beaca9bea6208111526718460ecc1c2bbc37d81 Mon Sep 17 00:00:00 2001 From: Ray Walker Date: Fri, 14 Aug 2026 21:11:20 +1000 Subject: [PATCH 2/4] fix(fuzz): apply expert-panel findings to corpus tooling (LAB-1149) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Panel: bug-hunter-supreme, security-specialist, code-craftsman, catchphrase-agent (high stakes). Security: no findings. Applied: - fuzz-smoke.yml: validate corpus layout before the build - without this step the every-target-has-seeds guarantee was manual-only, and a target added tomorrow would fuzz cold forever behind a green badge. The step can only fail loudly; no existing guarantee weakened. - validate_corpus.sh: assert grep-derived target count matches fuzz_targets/*.rs (a [[bin]] stanza whose name line drifts from the grep pattern would silently stop requiring seeds); drop dead .gitkeep filters, the 8MB soft tier, and the --help block. - minimize_corpus.sh: reject unknown target names (a typo'd target previously printed 'Skipping' and exited 0); --help before env checks; drop the duplicate 10MB check (validate_corpus.sh is the single budget enforcer) and dead .gitkeep filters. - rust/fuzz/Makefile: fail quick/deep when FUZZ_TARGETS derives empty - a zero-target loop reported '✓ No crashes found' having fuzzed nothing. - README.md: fix Quick Start commands (make fuzz-* lives at the repo root, not rust/Makefile); delete the AFL++ section and multi-engine claims (no afl feature, no fuzz-afl target - doc fiction); honest large-payload numbers; corpus section now points at CORPUS_INFO.md instead of duplicating it. - generate_corpus.sh: drop 10 filler seeds (key-derivation content variants the target already hard-loops every exec, redundant large-payload sizes, trivial invalid-msgpack bytes) - 72 seeds, 696K total. Re-measured with the final corpus (60s, nightly-2026-04-27): - encryption_large_payload cold: cov 185, ft 194, lim 53b, 5,553 execs. Seeded (3 files): ft 300, 256KB inputs. - byte_storage_decompress cold: cov 2358, ft 3770. Seeded (13 files): cov 2423, ft 3968. --- .github/workflows/fuzz-smoke.yml | 10 +++ rust/fuzz/Makefile | 2 + rust/fuzz/README.md | 76 ++++++------------ .../corpus/byte_storage_compress/unicode.bin | 1 - .../invalid_msgpack.bin | 1 - .../invalid_msgpack.bin | 1 - .../corpus/encryption_key_derivation/bom.bin | 1 - .../empty_tenant.bin | 1 - .../encryption_key_derivation/null_byte.bin | Bin 27 -> 0 bytes .../path_traversal.bin | 1 - .../encryption_key_derivation/unicode.bin | 1 - .../key_100k_random.bin | Bin 102432 -> 0 bytes .../encryption_large_payload/key_1k.bin | Bin 1056 -> 0 bytes .../encryption_large_payload/key_64k.bin | Bin 65568 -> 65568 bytes .../key_random.bin | 4 +- rust/fuzz/scripts/generate_corpus.sh | 21 +---- rust/fuzz/scripts/minimize_corpus.sh | 61 +++++++------- rust/fuzz/scripts/validate_corpus.sh | 30 ++++--- 18 files changed, 85 insertions(+), 126 deletions(-) delete mode 100644 rust/fuzz/corpus/byte_storage_compress/unicode.bin delete mode 100644 rust/fuzz/corpus/byte_storage_corrupted_envelope/invalid_msgpack.bin delete mode 100644 rust/fuzz/corpus/byte_storage_decompress/invalid_msgpack.bin delete mode 100644 rust/fuzz/corpus/encryption_key_derivation/bom.bin delete mode 100644 rust/fuzz/corpus/encryption_key_derivation/empty_tenant.bin delete mode 100644 rust/fuzz/corpus/encryption_key_derivation/null_byte.bin delete mode 100644 rust/fuzz/corpus/encryption_key_derivation/path_traversal.bin delete mode 100644 rust/fuzz/corpus/encryption_key_derivation/unicode.bin delete mode 100644 rust/fuzz/corpus/encryption_large_payload/key_100k_random.bin delete mode 100644 rust/fuzz/corpus/encryption_large_payload/key_1k.bin diff --git a/.github/workflows/fuzz-smoke.yml b/.github/workflows/fuzz-smoke.yml index a018662..65297c0 100644 --- a/.github/workflows/fuzz-smoke.yml +++ b/.github/workflows/fuzz-smoke.yml @@ -59,6 +59,16 @@ jobs: # it fails loudly on drift, and warms the empty CARGO_HOME besides. cargo +nightly-2026-04-27 fetch --locked + - name: Validate corpus layout + run: | + cd rust/fuzz + # Every [[bin]] target must have committed seeds in corpus// — + # a target without them fuzzes cold from random bytes and the run is + # far shallower than its green badge suggests (LAB-1149). Pure bash, + # fails loudly on a missing/empty seed directory or a blown 10MB + # budget. Without this step the seed requirement is manual-only. + bash scripts/validate_corpus.sh + - name: Build all fuzz targets run: | cd rust/fuzz diff --git a/rust/fuzz/Makefile b/rust/fuzz/Makefile index cfa9ab2..69fc57a 100644 --- a/rust/fuzz/Makefile +++ b/rust/fuzz/Makefile @@ -68,6 +68,7 @@ quick: ## Run quick fuzzing smoke test (60s per target, ~14min total) @echo "$(YELLOW)Logging to $(LOG_FUZZ_DIR)/quick_$(TIMESTAMP).log$(RESET)" $(call require_binary,cargo,Install Rust: https://rustup.rs) $(call warn_if_missing,cargo-fuzz,Install: cargo install cargo-fuzz) + @if [ -z "$(strip $(FUZZ_TARGETS))" ]; then echo "$(YELLOW)❌ no [[bin]] targets derived from Cargo.toml — a zero-target loop would report green having fuzzed nothing$(RESET)"; exit 1; fi @{ \ for target in $(FUZZ_TARGETS); do \ echo "$(YELLOW)Fuzzing $$target (60s)...$(RESET)"; \ @@ -89,6 +90,7 @@ deep: ## Run deep fuzzing (8 hours per target, production-grade) @echo "$(YELLOW)Logging to $(LOG_FUZZ_DIR)/deep_$(TIMESTAMP).log$(RESET)" $(call require_binary,cargo,Install Rust: https://rustup.rs) $(call warn_if_missing,cargo-fuzz,Install: cargo install cargo-fuzz) + @if [ -z "$(strip $(FUZZ_TARGETS))" ]; then echo "$(YELLOW)❌ no [[bin]] targets derived from Cargo.toml — a zero-target loop would report green having fuzzed nothing$(RESET)"; exit 1; fi @{ \ for target in $(FUZZ_TARGETS); do \ echo "$(YELLOW)Deep fuzzing $$target (8 hours)...$(RESET)"; \ diff --git a/rust/fuzz/README.md b/rust/fuzz/README.md index 58e72a0..0e5a81a 100644 --- a/rust/fuzz/README.md +++ b/rust/fuzz/README.md @@ -17,24 +17,28 @@ This fuzzing suite provides **14 fuzz targets** covering: ```bash # Install cargo-fuzz (libfuzzer-based) cargo install cargo-fuzz - -# Install AFL++ (optional, for mutation-based fuzzing) -cargo install cargo-afl ``` ### Basic Fuzzing Workflow + +Run from the repository root (`make fuzz-*` delegates to `rust/fuzz/Makefile`; +equivalently `cd rust/fuzz && make quick|target|deep|coverage`): + ```bash # Quick smoke test (60s per target, ~14min total) -cd rust && make fuzz-quick +make fuzz-quick # Fuzz single target for development -cd rust && make fuzz-target TARGET=byte_storage_corrupted_envelope +make fuzz-target TARGET=byte_storage_corrupted_envelope + +# Deep fuzzing of one target (8 hours, production validation) +make fuzz-target TARGET=encryption_key_derivation TIME=28800 -# Deep fuzzing (8 hours per target, production validation) -cd rust && make fuzz-deep TARGET=encryption_key_derivation +# Deep fuzzing of every target (8 hours each) +make fuzz-deep # Generate coverage report -cd rust && make fuzz-coverage +make fuzz-coverage ``` ## Fuzz Targets @@ -89,7 +93,7 @@ cd rust && make fuzz-coverage - Tests: Null bytes, control characters, Unicode, 1-bit AAD modification **encryption_large_payload.rs** -- Attack: Production-scale payloads (1MB, 10MB, 100MB) +- Attack: Production-scale payloads (seeded up to 256KB; harness accepts up to 100MB) - Validates: Performance and correctness at scale - Tests: Large allocations, memory efficiency, no artificial 4KB limits @@ -104,24 +108,11 @@ cd rust && make fuzz-coverage ### Directory Structure -One committed seed directory per fuzz target, named exactly after the -`[[bin]]` stanza in `Cargo.toml`: - -``` -rust/fuzz/corpus/ -├── CORPUS_INFO.md # Layout contract and maintenance guide -├── byte_storage_compress/ # Raw plaintext seeds -├── byte_storage_decompress/ # Valid + corrupted StorageEnvelope bytes -├── … # One directory per [[bin]] target -└── integration_layered_security/ -``` - -This is the layout `cargo fuzz run ` loads by default — locally and -in CI, with no corpus argument. Seeds are shaped per target's input format -(e.g. `32-byte key ++ plaintext` for encryption targets); the envelope seeds -are byte-exact against cachekit-core's wire format so their xxHash3-64 -checksums verify, reaching branches random inputs essentially never hit. -See `corpus/CORPUS_INFO.md` for the full contract. +One committed seed directory per fuzz target — `corpus//`, named +exactly after the `[[bin]]` stanza in `Cargo.toml`, because that is the +layout `cargo fuzz run ` loads by default (locally and in CI, no +corpus argument). The full contract — seed provenance, growth, regression +seeds — lives in [`corpus/CORPUS_INFO.md`](corpus/CORPUS_INFO.md). ### Corpus Scripts ```bash @@ -153,15 +144,15 @@ reproducer into `corpus//` so it is re-tested on every future run. - Uploads crash artifacts on failure ```bash -# Simulate CI smoke tests locally -cd rust && make fuzz-quick +# Simulate CI smoke tests locally (repo root) +make fuzz-quick ``` ### Deep Fuzzing (Production Validation) Run before releases or periodically: ```bash -# 8 hours per target (production-grade validation) -cd rust && make fuzz-deep TARGET=encryption_key_derivation +# 8 hours on one target (repo root) +make fuzz-target TARGET=encryption_key_derivation TIME=28800 ``` ## Crash Triage @@ -189,23 +180,11 @@ cargo fuzz run byte_storage_corrupted_envelope artifacts/crash-xyz cargo fuzz cmin byte_storage_corrupted_envelope ``` -## AFL++ Fuzzing (Alternative Engine) - -AFL++ provides mutation-based fuzzing complementary to libfuzzer's coverage-guided approach: - -```bash -# Build AFL++ target -cd rust && cargo afl build --features afl - -# Run AFL++ fuzzer -cd rust && make fuzz-afl TARGET=byte_storage_corrupted_envelope -``` - ## Coverage Reporting ```bash -# Generate LLVM coverage report -cd rust && make fuzz-coverage +# Generate LLVM coverage report (repo root) +make fuzz-coverage # View HTML report open rust/fuzz/coverage/html/index.html @@ -262,12 +241,6 @@ All fuzz targets enforce fail-closed behavior: - **Panic** = Test failure (fuzzer reports bug) - **Undefined behavior** = Instant failure (sanitizers catch) -### Multi-Engine Strategy - -- **Libfuzzer** (default): Coverage-guided, fast iteration, LLVM sanitizers -- **AFL++**: Mutation-based, finds different bug classes, mature tooling -- Both engines share corpus for cross-pollination - ## Contributing When adding new fuzz targets: @@ -284,5 +257,4 @@ When adding new fuzz targets: - [Rust Fuzz Book](https://rust-fuzz.github.io/book/) - [libfuzzer documentation](https://llvm.org/docs/LibFuzzer.html) -- [AFL++ documentation](https://aflplus.plus/) - [cachekit security architecture](../../SECURITY.md) diff --git a/rust/fuzz/corpus/byte_storage_compress/unicode.bin b/rust/fuzz/corpus/byte_storage_compress/unicode.bin deleted file mode 100644 index fb77344..0000000 --- a/rust/fuzz/corpus/byte_storage_compress/unicode.bin +++ /dev/null @@ -1 +0,0 @@ -café ✨ 한국어 テスト \ No newline at end of file diff --git a/rust/fuzz/corpus/byte_storage_corrupted_envelope/invalid_msgpack.bin b/rust/fuzz/corpus/byte_storage_corrupted_envelope/invalid_msgpack.bin deleted file mode 100644 index 8663f7d..0000000 --- a/rust/fuzz/corpus/byte_storage_corrupted_envelope/invalid_msgpack.bin +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/rust/fuzz/corpus/byte_storage_decompress/invalid_msgpack.bin b/rust/fuzz/corpus/byte_storage_decompress/invalid_msgpack.bin deleted file mode 100644 index 8663f7d..0000000 --- a/rust/fuzz/corpus/byte_storage_decompress/invalid_msgpack.bin +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/rust/fuzz/corpus/encryption_key_derivation/bom.bin b/rust/fuzz/corpus/encryption_key_derivation/bom.bin deleted file mode 100644 index 11c4c07..0000000 --- a/rust/fuzz/corpus/encryption_key_derivation/bom.bin +++ /dev/null @@ -1 +0,0 @@ -o%)I;yxJh~bom_tenant \ No newline at end of file diff --git a/rust/fuzz/corpus/encryption_key_derivation/empty_tenant.bin b/rust/fuzz/corpus/encryption_key_derivation/empty_tenant.bin deleted file mode 100644 index b1b1f68..0000000 --- a/rust/fuzz/corpus/encryption_key_derivation/empty_tenant.bin +++ /dev/null @@ -1 +0,0 @@ -o%)I;yxJh~ \ No newline at end of file diff --git a/rust/fuzz/corpus/encryption_key_derivation/null_byte.bin b/rust/fuzz/corpus/encryption_key_derivation/null_byte.bin deleted file mode 100644 index d0e546b81657e541a59af079e1b7832731f17684..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27 icmd1bc>jj#2~AJy$`=(ky)x=bQu7k?N*MA=b8-N`3=Ek7 diff --git a/rust/fuzz/corpus/encryption_key_derivation/path_traversal.bin b/rust/fuzz/corpus/encryption_key_derivation/path_traversal.bin deleted file mode 100644 index 420ef2c..0000000 --- a/rust/fuzz/corpus/encryption_key_derivation/path_traversal.bin +++ /dev/null @@ -1 +0,0 @@ -o%)I;yxJh~../../../admin \ No newline at end of file diff --git a/rust/fuzz/corpus/encryption_key_derivation/unicode.bin b/rust/fuzz/corpus/encryption_key_derivation/unicode.bin deleted file mode 100644 index d37efdb..0000000 --- a/rust/fuzz/corpus/encryption_key_derivation/unicode.bin +++ /dev/null @@ -1 +0,0 @@ -o%)I;yxJh~한국어✨ \ No newline at end of file diff --git a/rust/fuzz/corpus/encryption_large_payload/key_100k_random.bin b/rust/fuzz/corpus/encryption_large_payload/key_100k_random.bin deleted file mode 100644 index b08bc9f34c3a04f45cb0d972b3d8f71798cc5d3e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 102432 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 PYb&}4g;R~k*4-|DAZ!ko diff --git a/rust/fuzz/corpus/integration_layered_security/key_random.bin b/rust/fuzz/corpus/integration_layered_security/key_random.bin index 9cf3e92..1b62d42 100644 --- a/rust/fuzz/corpus/integration_layered_security/key_random.bin +++ b/rust/fuzz/corpus/integration_layered_security/key_random.bin @@ -1 +1,3 @@ -QP!+U=i.d3'r"CQHs.Ƶ8anEv0hvrc0AbF]Ѷ:6nf?w= 9f3Nm"5h&k${b ABU \ No newline at end of file +QP!+U=i.d3'r"W>AK|UZt2, +*v#ߒȨ܏ h7SdTL%], +z͇ytW# ( »3̋T8{O&KE"J1 \ No newline at end of file diff --git a/rust/fuzz/scripts/generate_corpus.sh b/rust/fuzz/scripts/generate_corpus.sh index 4c6a99d..22b48c0 100755 --- a/rust/fuzz/scripts/generate_corpus.sh +++ b/rust/fuzz/scripts/generate_corpus.sh @@ -88,7 +88,6 @@ seed("byte_storage_compress", "text.bin", text) seed("byte_storage_compress", "compressible.bin", compressible) seed("byte_storage_compress", "gradient.bin", gradient) seed("byte_storage_compress", "random_1k.bin", random_1k) -seed("byte_storage_compress", "unicode.bin", "café ✨ 한국어 テスト".encode()) # ── byte_storage_decompress + byte_storage_corrupted_envelope: # both parse envelope bytes (retrieve() / rmp_serde::from_slice) ───────── @@ -136,7 +135,6 @@ env_samples = { }, use_bin_type=True, ), - "invalid_msgpack.bin": b"\xff" * 8, } for name, data in env_samples.items(): seed("byte_storage_decompress", name, data) @@ -182,11 +180,6 @@ seed("encryption_roundtrip", "key_random.bin", key32 + rng.randbytes(256)) # encryption_key_derivation: 16-byte master key ++ tenant salt mk16 = rng.randbytes(16) seed("encryption_key_derivation", "normal_tenant.bin", mk16 + b"customer-12345") -seed("encryption_key_derivation", "path_traversal.bin", mk16 + b"../../../admin") -seed("encryption_key_derivation", "null_byte.bin", mk16 + b"tenant\x00null") -seed("encryption_key_derivation", "bom.bin", mk16 + "bom_tenant".encode()) -seed("encryption_key_derivation", "empty_tenant.bin", mk16) -seed("encryption_key_derivation", "unicode.bin", mk16 + "한국어✨".encode()) seed("encryption_key_derivation", "long_tenant.bin", mk16 + b"x" * 4096) # encryption_nonce_reuse: small plaintexts → 100-iteration uniqueness loop @@ -204,28 +197,18 @@ seed("encryption_aad_injection", "key_nulls.bin", key32 + b"p" * 60 + b"aad\x00n seed("encryption_aad_injection", "key_random.bin", key32 + rng.randbytes(1000)) # encryption_large_payload: sizes libFuzzer is slow to grow into on its own -seed("encryption_large_payload", "key_1k.bin", key32 + rng.randbytes(1024)) seed("encryption_large_payload", "key_16k_compressible.bin", key32 + b"a" * 16_384) seed("encryption_large_payload", "key_64k.bin", key32 + rng.randbytes(65_536)) seed("encryption_large_payload", "key_256k_compressible.bin", key32 + b"ab" * 131_072) -seed("encryption_large_payload", "key_100k_random.bin", key32 + rng.randbytes(102_400)) # integration_layered_security: 32-byte key + plaintext (total ≥ 64, ≤ 4096+32) seed("integration_layered_security", "key_text.bin", key32 + text + b" layered." * 4) seed("integration_layered_security", "key_compressible.bin", key32 + b"a" * 512) seed("integration_layered_security", "key_random.bin", key32 + rng.randbytes(128)) -total = sum(written.values()) -print(f"Wrote {total} seeds across {len(written)} target directories:") -for target in sorted(written): - print(f" corpus/{target}/: {written[target]} seeds") +# Per-target breakdown lives in validate_corpus.sh — the single count surface. +print(f"Wrote {sum(written.values())} seeds across {len(written)} target directories") PYTHON -echo "" echo "=== Corpus Generation Complete ===" du -sh "$CORPUS_DIR" -echo "" -echo "Next steps:" -echo " 1. Validate layout matches Cargo.toml targets: ./scripts/validate_corpus.sh" -echo " 2. Sanity-run every seed once: cargo +nightly fuzz run -- -runs=0" -echo " 3. After growth runs, minimize: ./scripts/minimize_corpus.sh" diff --git a/rust/fuzz/scripts/minimize_corpus.sh b/rust/fuzz/scripts/minimize_corpus.sh index 4b4db49..2a23ae7 100755 --- a/rust/fuzz/scripts/minimize_corpus.sh +++ b/rust/fuzz/scripts/minimize_corpus.sh @@ -4,6 +4,20 @@ set -euo pipefail # Corpus minimization script for cachekit fuzzing # Runs cargo fuzz cmin to deduplicate and reduce corpus size +if [ "${1:-}" = "--help" ] || [ "${1:-}" = "-h" ]; then + echo "Usage: $0 [TARGET]" + echo "" + echo "Minimize fuzzing corpus to remove redundant test cases." + echo "" + echo "Arguments:" + echo " TARGET Optional: minimize specific target only" + echo "" + echo "Examples:" + echo " $0 # Minimize all targets" + echo " $0 byte_storage_corrupted_envelope # Minimize single target" + exit 0 +fi + SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" FUZZ_DIR="$(dirname "$SCRIPT_DIR")" CORPUS_DIR="$FUZZ_DIR/corpus" @@ -17,10 +31,8 @@ if ! command -v cargo-fuzz &> /dev/null; then exit 1 fi -# Targets derived from the [[bin]] stanzas in Cargo.toml — the same source -# `cargo fuzz list`, the Makefile, and validate_corpus.sh read. A -# hand-maintained copy here is the drift hazard that buried the original -# corpus (LAB-1149). +# Targets derived from the [[bin]] stanzas in Cargo.toml — the single source +# of truth `cargo fuzz list`, the Makefile, and validate_corpus.sh all read. mapfile -t FUZZ_TARGETS < <(grep -A1 '^\[\[bin\]\]' "$FUZZ_DIR/Cargo.toml" | sed -n 's/^name = "\(.*\)"/\1/p') if [ "${#FUZZ_TARGETS[@]}" -eq 0 ]; then echo "ERROR: no [[bin]] targets found in $FUZZ_DIR/Cargo.toml" @@ -39,7 +51,7 @@ minimize_target() { fi # Count files before minimization - local before_count=$(find "$corpus_path" -type f ! -name '.gitkeep' | wc -l | tr -d ' ') + local before_count=$(find "$corpus_path" -type f | wc -l | tr -d ' ') local before_size=$(du -sh "$corpus_path" 2>/dev/null | cut -f1 || echo "0B") if [ "$before_count" -eq 0 ]; then @@ -58,7 +70,7 @@ minimize_target() { exit 1 fi - local after_count=$(find "$corpus_path" -type f ! -name '.gitkeep' | wc -l | tr -d ' ') + local after_count=$(find "$corpus_path" -type f | wc -l | tr -d ' ') local after_size=$(du -sh "$corpus_path" 2>/dev/null | cut -f1 || echo "0B") local removed=$((before_count - after_count)) echo "✅ Minimized $target: ${before_count} → ${after_count} files (-${removed}), ${before_size} → ${after_size}" @@ -72,6 +84,16 @@ main() { echo "" if [ -n "$target_filter" ]; then + # Reject unknown names: a typo'd target must not "succeed" as a no-op. + local known=0 + for t in "${FUZZ_TARGETS[@]}"; do + [ "$t" = "$target_filter" ] && known=1 + done + if [ "$known" -eq 0 ]; then + echo "ERROR: '$target_filter' is not a [[bin]] target in Cargo.toml" + printf 'Known targets:\n%s\n' "${FUZZ_TARGETS[@]/#/ - }" + exit 1 + fi echo "Minimizing single target: $target_filter" minimize_target "$target_filter" else @@ -85,31 +107,8 @@ main() { echo "=== Corpus Minimization Complete ===" echo "Total corpus size:" du -sh "$CORPUS_DIR" - - # Check if corpus exceeds 10MB - local total_size_mb=$(du -sm "$CORPUS_DIR" 2>/dev/null | cut -f1 || echo "0") - if [ "$total_size_mb" -gt 10 ]; then - echo "" - echo "⚠️ WARNING: Corpus size (${total_size_mb}MB) exceeds 10MB target" - echo "Consider removing large files or further minimizing corpus" - else - echo "✅ Corpus size (${total_size_mb}MB) is within 10MB target" - fi + # Size budget is enforced by validate_corpus.sh — the single enforcer. + echo "Run scripts/validate_corpus.sh to check layout and the 10MB budget." } -# Usage information -if [ "${1:-}" = "--help" ] || [ "${1:-}" = "-h" ]; then - echo "Usage: $0 [TARGET]" - echo "" - echo "Minimize fuzzing corpus to remove redundant test cases." - echo "" - echo "Arguments:" - echo " TARGET Optional: minimize specific target only" - echo "" - echo "Examples:" - echo " $0 # Minimize all targets" - echo " $0 byte_storage_corrupted_envelope # Minimize single target" - exit 0 -fi - main "$@" diff --git a/rust/fuzz/scripts/validate_corpus.sh b/rust/fuzz/scripts/validate_corpus.sh index c15a13b..2e92130 100755 --- a/rust/fuzz/scripts/validate_corpus.sh +++ b/rust/fuzz/scripts/validate_corpus.sh @@ -8,18 +8,6 @@ set -euo pipefail # This script fails if any target has no seeds (the drift that buried the # original corpus: LAB-1149) or if the total exceeds the 10MB CI budget. -if [ "${1:-}" = "--help" ] || [ "${1:-}" = "-h" ]; then - echo "Usage: $0" - echo "" - echo "Validate the per-target fuzzing corpus." - echo "" - echo "Checks:" - echo " - Every [[bin]] target in Cargo.toml has a non-empty corpus//" - echo " - Total corpus size within the 10MB CI budget" - echo " - Flags individual seeds over 1MB" - exit 0 -fi - SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" FUZZ_DIR="$(dirname "$SCRIPT_DIR")" CORPUS_DIR="$FUZZ_DIR/corpus" @@ -42,6 +30,18 @@ if [ -z "$TARGETS" ]; then exit 1 fi +# The grep/sed above silently drops a stanza whose `name` line drifts from the +# exact expected format — and a dropped target would stop requiring seeds here +# while still fuzzing (cold) in CI. Assert parity against fuzz_targets/*.rs, +# the same cross-check fuzz-smoke.yml applies to `cargo fuzz list`. +TARGET_COUNT=$(printf '%s\n' "$TARGETS" | wc -l | tr -d ' ') +SRC_COUNT=$(find "$FUZZ_DIR/fuzz_targets" -maxdepth 1 -name '*.rs' | wc -l | tr -d ' ') +if [ "$TARGET_COUNT" -ne "$SRC_COUNT" ]; then + echo "ERROR: derived $TARGET_COUNT targets from Cargo.toml but fuzz_targets/ holds $SRC_COUNT sources" + echo " — a [[bin]] stanza is missing or its name line no longer matches 'name = \"…\"'" + exit 1 +fi + failures=0 for target in $TARGETS; do @@ -54,7 +54,7 @@ for target in $TARGETS; do continue fi - file_count=$(find "$target_dir" -type f ! -name '.gitkeep' | wc -l | tr -d ' ') + file_count=$(find "$target_dir" -type f | wc -l | tr -d ' ') if [ "$file_count" -eq 0 ]; then echo "❌ $target: corpus/$target/ has no seeds" failures=$((failures + 1)) @@ -76,7 +76,7 @@ done echo "" echo "=== Overall Corpus Statistics ===" -total_files=$(find "$CORPUS_DIR" -type f ! -name '.gitkeep' ! -name 'CORPUS_INFO.md' | wc -l | tr -d ' ') +total_files=$(find "$CORPUS_DIR" -type f ! -name 'CORPUS_INFO.md' | wc -l | tr -d ' ') total_size=$(du -sh "$CORPUS_DIR" 2>/dev/null | cut -f1 || echo "0B") total_mb=$(du -sm "$CORPUS_DIR" 2>/dev/null | cut -f1 || echo "0") echo "Total seeds: $total_files" @@ -87,8 +87,6 @@ if [ "$total_mb" -gt 10 ]; then echo "❌ VALIDATION FAILED: corpus size (${total_mb}MB) exceeds 10MB CI budget" echo " Run minimize_corpus.sh or drop oversized seeds" failures=$((failures + 1)) -elif [ "$total_mb" -gt 8 ]; then - echo "⚠️ WARNING: corpus size (${total_mb}MB) is approaching the 10MB budget" fi if [ "$failures" -gt 0 ]; then From d61cdaf21ff66727e38c06631652564a89ced7b4 Mon Sep 17 00:00:00 2001 From: Mark S Date: Fri, 14 Aug 2026 22:15:13 +1000 Subject: [PATCH 3/4] =?UTF-8?q?fix:=20address=20coderabbit=20review=20?= =?UTF-8?q?=E2=80=94=20corpus=20tooling=20correctness=20(LAB-1149)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Parity check (Kody medium + CodeRabbit): the old check compared a count of Cargo.toml [[bin]] names against a count of every *.rs in fuzz_targets/. That was both too strict and too loose — a shared helper module in that directory failed the whole CI step unconditionally, while a duplicated or misspelled name kept the counts equal and slipped through. Neither bot's suggested name-set comparison fixes the helper-module case, so the check now asserts the invariant the comment actually claimed: every [[bin]] stanza must yield exactly one name (stanza count == derived name count), names must be unique, and each must have a fuzz_targets/.rs source. Extra .rs files are now tolerated. minimize_corpus.sh: mapfile is bash 4+, so the script died immediately on stock macOS bash 3.2 — replaced with a portable read loop. `cargo fuzz cmin` needed +nightly like every other cargo-fuzz call in the Makefile; it failed outright on a stable default toolchain. SC2155 split on all four locals. generate_corpus.sh: regeneration was not idempotent — a renamed or dropped seed left its old file committed forever, invisible to a validator that checks presence and size but not provenance. First write per target now clears the *.bin names the script owns, leaving libFuzzer's extensionless hash-named discoveries and committed crash reproducers untouched. The byte-identical claim is scoped to a pinned dependency set (msgpack 1.2.1, lz4 4.4.5, xxhash 4.0.0 — verified to reproduce corpus/ with a clean git status), since the LZ4 block format constrains decoding, not encoder match-finding. fuzz-smoke.yml: corpus validation moved ahead of the toolchain install. It is pure bash over files present at checkout, so a missing seed directory now fails in seconds instead of after ~12 min of rustup + cargo-fuzz install. Makefile: the byte-identical zero-target guard in quick and deep extracted into a require_targets define, matching the file's existing require_binary / warn_if_missing idiom. Docs: MD040 fence language and the missing working directory in CORPUS_INFO.md (its commands resolve from rust/fuzz/, one level up from the file); non-copy-pasteable `make fuzz-*` and `make quick|target|deep|coverage` forms in README.md replaced with the real goal names; MD022/MD031 blank lines added at the three flagged sections. Verified: shellcheck clean on all three scripts; 8/8 checks in a throwaway harness covering each parity failure mode, the helper-module regression, seed orphan removal, discovery preservation, and byte-identical regeneration. Rejected, with reasons on the PR: Kody's print-vs-logging rule (fires on a progress line in an inline heredoc in a one-shot generator whose entire interface is stdout) and CodeRabbit's request to extract the target-derivation grep into a shared helper (the expert panel already rejected this; the fragility it cites is now detected loudly rather than silent). CodeRabbit-Resolved: rust/fuzz/scripts/validate_corpus.sh:43:Compare target na CodeRabbit-Resolved: rust/fuzz/scripts/validate_corpus.sh:31:One fragile targe CodeRabbit-Resolved: rust/fuzz/scripts/minimize_corpus.sh:36:mapfile requires CodeRabbit-Resolved: rust/fuzz/scripts/minimize_corpus.sh:54:Split the local d CodeRabbit-Resolved: rust/fuzz/scripts/minimize_corpus.sh:71:Run corpus minimi CodeRabbit-Resolved: rust/fuzz/scripts/generate_corpus.sh:62:Generation does n CodeRabbit-Resolved: rust/fuzz/scripts/generate_corpus.sh:15:Pin the corpus-ge CodeRabbit-Resolved: .github/workflows/fuzz-smoke.yml:71:Move the corpus valid CodeRabbit-Resolved: rust/fuzz/corpus/CORPUS_INFO.md:9:Add a language to the f CodeRabbit-Resolved: rust/fuzz/Makefile:71:Extract the duplicated zero-target CodeRabbit-Resolved: rust/fuzz/README.md:25:Make these commands copy-paste saf CodeRabbit-Resolved: rust/fuzz/README.md:118:Add the blank lines required by m --- .github/workflows/fuzz-smoke.yml | 25 +++++++++------- rust/fuzz/Makefile | 12 ++++++-- rust/fuzz/README.md | 19 ++++++++---- rust/fuzz/corpus/CORPUS_INFO.md | 15 +++++++--- rust/fuzz/scripts/generate_corpus.sh | 43 ++++++++++++++++++++++------ rust/fuzz/scripts/minimize_corpus.sh | 33 +++++++++++++++------ rust/fuzz/scripts/validate_corpus.sh | 37 +++++++++++++++++++----- 7 files changed, 139 insertions(+), 45 deletions(-) diff --git a/.github/workflows/fuzz-smoke.yml b/.github/workflows/fuzz-smoke.yml index 65297c0..032145d 100644 --- a/.github/workflows/fuzz-smoke.yml +++ b/.github/workflows/fuzz-smoke.yml @@ -36,6 +36,21 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - name: Validate corpus layout + run: | + cd rust/fuzz + # Every [[bin]] target must have committed seeds in corpus// — + # a target without them fuzzes cold from random bytes and the run is + # far shallower than its green badge suggests (LAB-1149). Pure bash, + # fails loudly on a missing/empty seed directory or a blown 10MB + # budget. Without this step the seed requirement is manual-only. + # + # Runs before the toolchain install deliberately: it needs only bash + + # coreutils and reads files present straight from checkout, so putting + # it here fails a missing seed directory in seconds instead of after + # ~12 min of rustup + cargo-fuzz install. + bash scripts/validate_corpus.sh + - name: Install Rust nightly run: | # Pin nightly: cargo-fuzz's rustix dependency uses @@ -59,16 +74,6 @@ jobs: # it fails loudly on drift, and warms the empty CARGO_HOME besides. cargo +nightly-2026-04-27 fetch --locked - - name: Validate corpus layout - run: | - cd rust/fuzz - # Every [[bin]] target must have committed seeds in corpus// — - # a target without them fuzzes cold from random bytes and the run is - # far shallower than its green badge suggests (LAB-1149). Pure bash, - # fails loudly on a missing/empty seed directory or a blown 10MB - # budget. Without this step the seed requirement is manual-only. - bash scripts/validate_corpus.sh - - name: Build all fuzz targets run: | cd rust/fuzz diff --git a/rust/fuzz/Makefile b/rust/fuzz/Makefile index 69fc57a..12813d8 100644 --- a/rust/fuzz/Makefile +++ b/rust/fuzz/Makefile @@ -39,6 +39,14 @@ define warn_if_missing @command -v $(1) >/dev/null 2>&1 || echo "$(YELLOW)⚠️ $(1) not found. $(2)$(RESET)" endef +# Guard every recipe that loops over FUZZ_TARGETS: an empty list makes the loop +# body run zero times and the recipe exit 0, reporting green having fuzzed +# nothing. `target` does not need this — it lists FUZZ_TARGETS only on its +# missing-TARGET error path, which already exits 1. +define require_targets + @if [ -z "$(strip $(FUZZ_TARGETS))" ]; then echo "$(YELLOW)❌ no [[bin]] targets derived from Cargo.toml — a zero-target loop would report green having fuzzed nothing$(RESET)"; exit 1; fi +endef + help: ## Show fuzzing-specific commands @echo "$(BLUE)cachekit/rust/fuzz - Fuzzing Commands$(RESET)" @echo "" @@ -68,7 +76,7 @@ quick: ## Run quick fuzzing smoke test (60s per target, ~14min total) @echo "$(YELLOW)Logging to $(LOG_FUZZ_DIR)/quick_$(TIMESTAMP).log$(RESET)" $(call require_binary,cargo,Install Rust: https://rustup.rs) $(call warn_if_missing,cargo-fuzz,Install: cargo install cargo-fuzz) - @if [ -z "$(strip $(FUZZ_TARGETS))" ]; then echo "$(YELLOW)❌ no [[bin]] targets derived from Cargo.toml — a zero-target loop would report green having fuzzed nothing$(RESET)"; exit 1; fi + $(call require_targets) @{ \ for target in $(FUZZ_TARGETS); do \ echo "$(YELLOW)Fuzzing $$target (60s)...$(RESET)"; \ @@ -90,7 +98,7 @@ deep: ## Run deep fuzzing (8 hours per target, production-grade) @echo "$(YELLOW)Logging to $(LOG_FUZZ_DIR)/deep_$(TIMESTAMP).log$(RESET)" $(call require_binary,cargo,Install Rust: https://rustup.rs) $(call warn_if_missing,cargo-fuzz,Install: cargo install cargo-fuzz) - @if [ -z "$(strip $(FUZZ_TARGETS))" ]; then echo "$(YELLOW)❌ no [[bin]] targets derived from Cargo.toml — a zero-target loop would report green having fuzzed nothing$(RESET)"; exit 1; fi + $(call require_targets) @{ \ for target in $(FUZZ_TARGETS); do \ echo "$(YELLOW)Deep fuzzing $$target (8 hours)...$(RESET)"; \ diff --git a/rust/fuzz/README.md b/rust/fuzz/README.md index 0e5a81a..1855312 100644 --- a/rust/fuzz/README.md +++ b/rust/fuzz/README.md @@ -21,8 +21,10 @@ cargo install cargo-fuzz ### Basic Fuzzing Workflow -Run from the repository root (`make fuzz-*` delegates to `rust/fuzz/Makefile`; -equivalently `cd rust/fuzz && make quick|target|deep|coverage`): +Run from the repository root. The root Makefile's `fuzz-quick`, `fuzz-target`, +`fuzz-deep` and `fuzz-coverage` goals delegate to `rust/fuzz/Makefile`, whose +own goals drop the prefix — `cd rust/fuzz && make quick` is equivalent to +`make fuzz-quick` from the root: ```bash # Quick smoke test (60s per target, ~14min total) @@ -115,13 +117,15 @@ corpus argument). The full contract — seed provenance, growth, regression seeds — lives in [`corpus/CORPUS_INFO.md`](corpus/CORPUS_INFO.md). ### Corpus Scripts + ```bash -# (Re)generate the deterministic per-target seed set -# Needs python3 with msgpack, lz4, xxhash — or via uv: -# uv run --no-project --with msgpack --with lz4 --with xxhash bash scripts/generate_corpus.sh +# (Re)generate the deterministic per-target seed set. +# Needs python3 with msgpack, lz4, xxhash at the versions pinned in the +# script — or via uv: +# uv run --no-project --with msgpack==1.2.1 --with lz4==4.4.5 --with xxhash==4.0.0 bash scripts/generate_corpus.sh cd rust/fuzz && ./scripts/generate_corpus.sh -# Minimize corpus after growth runs (cargo fuzz cmin per target) +# Minimize corpus after growth runs (cargo +nightly fuzz cmin per target) cd rust/fuzz && ./scripts/minimize_corpus.sh # Validate: every Cargo.toml target has seeds, total < 10MB @@ -136,6 +140,7 @@ reproducer into `corpus//` so it is re-tested on every future run. ## CI Integration ### Smoke Tests (PR Validation) + `.github/workflows/fuzz-smoke.yml` runs on every pull request: - 60 seconds per target (~14 minutes total) - Starts from the committed seeds in `corpus//` (cargo-fuzz's default @@ -149,7 +154,9 @@ make fuzz-quick ``` ### Deep Fuzzing (Production Validation) + Run before releases or periodically: + ```bash # 8 hours on one target (repo root) make fuzz-target TARGET=encryption_key_derivation TIME=28800 diff --git a/rust/fuzz/corpus/CORPUS_INFO.md b/rust/fuzz/corpus/CORPUS_INFO.md index cb0cf64..8a1cd6e 100644 --- a/rust/fuzz/corpus/CORPUS_INFO.md +++ b/rust/fuzz/corpus/CORPUS_INFO.md @@ -4,7 +4,7 @@ Committed seed inputs for the fuzz targets in this crate. ## Layout: one directory per target -``` +```text corpus// ``` @@ -15,9 +15,11 @@ fuzzer: an earlier category tree (`byte_storage/`, `encryption/`, …) sat here for months without a single target ever reading it (LAB-1149). No file counts or sizes are recorded here — a written-down count is stale the -day someone adds a seed. For live numbers run: +day someone adds a seed. For live numbers run, from `rust/fuzz/` (one level up +from this file — the scripts resolve their paths relative to that directory): ```bash +cd rust/fuzz ./scripts/validate_corpus.sh ``` @@ -41,11 +43,16 @@ CI budget. ## Maintenance +All three run from `rust/fuzz/`, not from this directory: + ```bash -# Regenerate the deterministic seed set (safe: same version → same bytes) +cd rust/fuzz + +# Regenerate the deterministic seed set. Byte-identical under the dependency +# versions pinned at the top of the script; see its header for the caveat. ./scripts/generate_corpus.sh -# Deduplicate / shrink after growth runs +# Deduplicate / shrink after growth runs (needs a nightly toolchain) ./scripts/minimize_corpus.sh # Check layout and size budget diff --git a/rust/fuzz/scripts/generate_corpus.sh b/rust/fuzz/scripts/generate_corpus.sh index 22b48c0..65b199e 100755 --- a/rust/fuzz/scripts/generate_corpus.sh +++ b/rust/fuzz/scripts/generate_corpus.sh @@ -8,11 +8,19 @@ set -euo pipefail # default. (A previous version wrote a category tree, corpus/byte_storage/…, # which no target ever read: LAB-1149.) # -# Deterministic: same script version → byte-identical seeds, so re-runs -# produce clean git diffs. Valid StorageEnvelope seeds are byte-exact against -# cachekit-core 0.4.0's wire format (raw LZ4 block + xxHash3-64 big-endian -# checksum + rmp-serde array-form msgpack), verified against the crate's -# pinned empty-input checksum test vector. +# Deterministic *within a pinned dependency set*: same script version + the +# versions pinned below → byte-identical seeds, so re-runs produce clean git +# diffs. The LZ4 block format fixes how a block is decoded, not how an encoder +# searches for matches, so a different liblz4 build may emit different — still +# valid — bytes for the same input. Regenerating under an unpinned lz4 can +# therefore produce a legitimate-but-noisy diff; that is a diff to inspect, not +# a corruption. +# +# Valid StorageEnvelope seeds are byte-exact against cachekit-core 0.4.0's wire +# format (raw LZ4 block + xxHash3-64 big-endian checksum + rmp-serde array-form +# msgpack), verified against the crate's pinned empty-input checksum test +# vector. That framing is format-pinned and version-independent; only the +# compressed payload bytes carry the encoder caveat above. SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" FUZZ_DIR="$(dirname "$SCRIPT_DIR")" @@ -29,12 +37,19 @@ fi # msgpack for envelope framing; lz4 + xxhash to mint envelopes whose checksum # actually verifies — those are the seeds that reach extract()'s deepest # branch (checksum check runs AFTER decompression; random bytes never get -# there). With uv: uv run --no-project --with lz4 --with xxhash --with msgpack … +# there). +# +# Versions pinned because the committed seeds are byte-exact artifacts: this +# set reproduces corpus/ with a clean `git status` (verified 2026-08-14). Bump +# them deliberately and re-inspect the resulting diff. +PINNED_DEPS=("msgpack==1.2.1" "lz4==4.4.5" "xxhash==4.0.0") +UV_RUN_HINT="uv run --no-project ${PINNED_DEPS[*]/#/--with } bash scripts/generate_corpus.sh" + for mod in msgpack lz4.block xxhash; do if ! python3 -c "import $mod" 2>/dev/null; then echo "ERROR: Python module '$mod' is required" - echo "Install with: pip install msgpack lz4 xxhash" - echo "Or run via uv: uv run --no-project --with msgpack --with lz4 --with xxhash bash scripts/generate_corpus.sh" + echo "Install with: pip install ${PINNED_DEPS[*]}" + echo "Or run via uv: $UV_RUN_HINT" exit 1 fi done @@ -58,6 +73,18 @@ written = {} def seed(target: str, name: str, data: bytes) -> None: d = corpus / target d.mkdir(parents=True, exist_ok=True) + # First write to this target clears the seeds a previous script version + # owned. Without it, renaming or dropping a seed leaves the old file + # committed forever: validate_corpus.sh checks presence and size, not + # provenance, so the orphan is invisible — corpus drift in the opposite + # direction to LAB-1149. + # + # Scoped to `*.bin`, the naming this script owns. libFuzzer writes its + # discoveries as extensionless hex digests, so growth runs and committed + # crash reproducers survive regeneration untouched. + if target not in written: + for stale in d.glob("*.bin"): + stale.unlink() (d / name).write_bytes(data) written[target] = written.get(target, 0) + 1 diff --git a/rust/fuzz/scripts/minimize_corpus.sh b/rust/fuzz/scripts/minimize_corpus.sh index 2a23ae7..54ea661 100755 --- a/rust/fuzz/scripts/minimize_corpus.sh +++ b/rust/fuzz/scripts/minimize_corpus.sh @@ -33,7 +33,13 @@ fi # Targets derived from the [[bin]] stanzas in Cargo.toml — the single source # of truth `cargo fuzz list`, the Makefile, and validate_corpus.sh all read. -mapfile -t FUZZ_TARGETS < <(grep -A1 '^\[\[bin\]\]' "$FUZZ_DIR/Cargo.toml" | sed -n 's/^name = "\(.*\)"/\1/p') +# Read loop rather than `mapfile`: mapfile is bash 4+, and macOS still ships +# bash 3.2 as /bin/bash, where this script would otherwise die before doing any +# work. validate_corpus.sh derives the same list without it. +FUZZ_TARGETS=() +while IFS= read -r _target; do + [ -n "$_target" ] && FUZZ_TARGETS+=("$_target") +done < <(grep -A1 '^\[\[bin\]\]' "$FUZZ_DIR/Cargo.toml" | sed -n 's/^name = "\(.*\)"/\1/p') if [ "${#FUZZ_TARGETS[@]}" -eq 0 ]; then echo "ERROR: no [[bin]] targets found in $FUZZ_DIR/Cargo.toml" exit 1 @@ -50,9 +56,13 @@ minimize_target() { return fi - # Count files before minimization - local before_count=$(find "$corpus_path" -type f | wc -l | tr -d ' ') - local before_size=$(du -sh "$corpus_path" 2>/dev/null | cut -f1 || echo "0B") + # Count files before minimization. Declaration split from assignment: + # `local x=$(...)` returns the exit status of `local`, not of the command + # substitution, so a failing find/du would sail past `set -e` (SC2155). + local before_count before_size + before_count=$(find "$corpus_path" -type f | wc -l | tr -d ' ') + before_size=$({ du -sh "$corpus_path" 2>/dev/null | cut -f1; } || true) + before_size=${before_size:-0B} if [ "$before_count" -eq 0 ]; then echo "⏭️ Skipping $target (empty corpus)" @@ -64,15 +74,22 @@ minimize_target() { # Run corpus minimization — a failed cmin fails the script (targets are # derived from Cargo.toml, so "target may not exist" is a real error). + # `+nightly` for the same reason every cargo-fuzz call in the Makefile + # carries it: cmin builds the instrumented target, which needs the -Z flags + # only nightly accepts. Bare `cargo fuzz cmin` fails outright when the + # default toolchain is stable. cd "$FUZZ_DIR" - if ! cargo fuzz cmin "$target"; then + if ! cargo +nightly fuzz cmin "$target"; then echo "❌ Minimization failed for $target" + echo " cargo-fuzz needs a nightly toolchain: rustup toolchain install nightly" exit 1 fi - local after_count=$(find "$corpus_path" -type f | wc -l | tr -d ' ') - local after_size=$(du -sh "$corpus_path" 2>/dev/null | cut -f1 || echo "0B") - local removed=$((before_count - after_count)) + local after_count after_size removed + after_count=$(find "$corpus_path" -type f | wc -l | tr -d ' ') + after_size=$({ du -sh "$corpus_path" 2>/dev/null | cut -f1; } || true) + after_size=${after_size:-0B} + removed=$((before_count - after_count)) echo "✅ Minimized $target: ${before_count} → ${after_count} files (-${removed}), ${before_size} → ${after_size}" } diff --git a/rust/fuzz/scripts/validate_corpus.sh b/rust/fuzz/scripts/validate_corpus.sh index 2e92130..2c529c1 100755 --- a/rust/fuzz/scripts/validate_corpus.sh +++ b/rust/fuzz/scripts/validate_corpus.sh @@ -32,13 +32,36 @@ fi # The grep/sed above silently drops a stanza whose `name` line drifts from the # exact expected format — and a dropped target would stop requiring seeds here -# while still fuzzing (cold) in CI. Assert parity against fuzz_targets/*.rs, -# the same cross-check fuzz-smoke.yml applies to `cargo fuzz list`. -TARGET_COUNT=$(printf '%s\n' "$TARGETS" | wc -l | tr -d ' ') -SRC_COUNT=$(find "$FUZZ_DIR/fuzz_targets" -maxdepth 1 -name '*.rs' | wc -l | tr -d ' ') -if [ "$TARGET_COUNT" -ne "$SRC_COUNT" ]; then - echo "ERROR: derived $TARGET_COUNT targets from Cargo.toml but fuzz_targets/ holds $SRC_COUNT sources" - echo " — a [[bin]] stanza is missing or its name line no longer matches 'name = \"…\"'" +# while still fuzzing (cold) in CI. Catch that directly: every [[bin]] stanza +# must yield exactly one name. Comparing counts against fuzz_targets/*.rs +# cannot do this job — a shared helper module in that directory is not a target +# and would fail the check spuriously, while a duplicated or misspelled name +# keeps the count equal and slips through. +STANZA_COUNT=$(grep -c '^\[\[bin\]\]' "$FUZZ_DIR/Cargo.toml" || true) +NAME_COUNT=$(printf '%s\n' "$TARGETS" | grep -c . || true) +if [ "$NAME_COUNT" -ne "$STANZA_COUNT" ]; then + echo "ERROR: Cargo.toml has $STANZA_COUNT [[bin]] stanzas but only $NAME_COUNT yielded a name" + echo " — a stanza's name line no longer matches 'name = \"…\"' on the line directly after [[bin]]" + exit 1 +fi + +# Duplicate names would make one target silently shadow another's seed check. +DUPES=$(printf '%s\n' "$TARGETS" | sort | uniq -d) +if [ -n "$DUPES" ]; then + echo "ERROR: duplicate [[bin]] names in Cargo.toml:" + printf ' - %s\n' "$DUPES" + exit 1 +fi + +# Each declared target must have a source file. Extra .rs files are fine — +# they are helper modules, not targets. +missing_src="" +for target in $TARGETS; do + [ -f "$FUZZ_DIR/fuzz_targets/$target.rs" ] || missing_src="$missing_src $target" +done +if [ -n "$missing_src" ]; then + echo "ERROR: [[bin]] targets with no fuzz_targets/.rs source:" + for t in $missing_src; do echo " - $t"; done exit 1 fi From 37c27dba12c4a9b5b11952f5c5113a50d5b398fc Mon Sep 17 00:00:00 2001 From: Ray Walker Date: Fri, 14 Aug 2026 22:26:22 +1000 Subject: [PATCH 4/4] =?UTF-8?q?fix:=20address=20coderabbit=20review=20?= =?UTF-8?q?=E2=80=94=20working-dir=20docs=20+=20parity-filter=20coherence?= =?UTF-8?q?=20(LAB-1149)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Round 3. CodeRabbit: the README's uv one-liner invoked scripts/generate_corpus.sh from the repo root where that path does not resolve, and CORPUS_INFO.md said 'run from rust/fuzz/' above blocks whose first line is 'cd rust/fuzz' (only correct from the root). One convention now, both files: commands run from the repository root and the cd is part of the recipe. fuzz-smoke.yml source-parity check: filter SRC_COUNT to files containing fuzz_target!. validate_corpus.sh (previous commit) deliberately tolerates a shared helper module in fuzz_targets/, but the workflow's unfiltered *.rs count would fail the job on the same tree that just passed validation — 12 minutes after the fast-fail step, with a misleading 'add the missing stanza' error. The filtered count still catches the real drift (a fuzz_target! source with no [[bin]] stanza). Kody's base-image-digest rule fired on CORPUS_INFO.md line 19 — a markdown doc with no container images; rejected on the thread. CodeRabbit-Resolved: rust/fuzz/README.md:121:working-directory consistency CodeRabbit-Resolved: rust/fuzz/corpus/CORPUS_INFO.md:18:working-directory --- .github/workflows/fuzz-smoke.yml | 8 ++++++-- rust/fuzz/README.md | 2 +- rust/fuzz/corpus/CORPUS_INFO.md | 8 +++++--- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/.github/workflows/fuzz-smoke.yml b/.github/workflows/fuzz-smoke.yml index 032145d..b6066c6 100644 --- a/.github/workflows/fuzz-smoke.yml +++ b/.github/workflows/fuzz-smoke.yml @@ -104,8 +104,12 @@ jobs: # files in fuzz_targets/. So a new fuzz_targets/*.rs added without its # stanza is never built and never run, and this job still goes green — # the same silent-dark mode the old hardcoded array caused. Nothing in - # cargo enforces that the two agree, so assert it here. - SRC_COUNT=$(find fuzz_targets -maxdepth 1 -name '*.rs' | wc -l) + # cargo enforces that the two agree, so assert it here. Count only + # fuzz_target! sources: validate_corpus.sh deliberately tolerates a + # shared helper module in fuzz_targets/, and an unfiltered count would + # fail this job on the same tree that just passed validation — 12 + # minutes later, with a misleading "add the missing stanza" error. + SRC_COUNT=$(grep -l 'fuzz_target!' fuzz_targets/*.rs | wc -l) LIST_COUNT=$(printf '%s\n' "$TARGETS" | wc -l) if [ "$SRC_COUNT" -ne "$LIST_COUNT" ]; then echo "::error::fuzz_targets/ holds $SRC_COUNT sources but Cargo.toml declares $LIST_COUNT [[bin]] targets — add the missing [[bin]] stanza so the new target actually runs" diff --git a/rust/fuzz/README.md b/rust/fuzz/README.md index 1855312..72d6314 100644 --- a/rust/fuzz/README.md +++ b/rust/fuzz/README.md @@ -122,7 +122,7 @@ seeds — lives in [`corpus/CORPUS_INFO.md`](corpus/CORPUS_INFO.md). # (Re)generate the deterministic per-target seed set. # Needs python3 with msgpack, lz4, xxhash at the versions pinned in the # script — or via uv: -# uv run --no-project --with msgpack==1.2.1 --with lz4==4.4.5 --with xxhash==4.0.0 bash scripts/generate_corpus.sh +# cd rust/fuzz && uv run --no-project --with msgpack==1.2.1 --with lz4==4.4.5 --with xxhash==4.0.0 bash scripts/generate_corpus.sh cd rust/fuzz && ./scripts/generate_corpus.sh # Minimize corpus after growth runs (cargo +nightly fuzz cmin per target) diff --git a/rust/fuzz/corpus/CORPUS_INFO.md b/rust/fuzz/corpus/CORPUS_INFO.md index 8a1cd6e..5cf30a9 100644 --- a/rust/fuzz/corpus/CORPUS_INFO.md +++ b/rust/fuzz/corpus/CORPUS_INFO.md @@ -15,8 +15,9 @@ fuzzer: an earlier category tree (`byte_storage/`, `encryption/`, …) sat here for months without a single target ever reading it (LAB-1149). No file counts or sizes are recorded here — a written-down count is stale the -day someone adds a seed. For live numbers run, from `rust/fuzz/` (one level up -from this file — the scripts resolve their paths relative to that directory): +day someone adds a seed. For live numbers run, from the repository root (the +scripts resolve their paths relative to `rust/fuzz/`, one level up from this +file): ```bash cd rust/fuzz @@ -43,7 +44,8 @@ CI budget. ## Maintenance -All three run from `rust/fuzz/`, not from this directory: +All three below run from the repository root — the `cd rust/fuzz` is part of +the recipe, since the scripts resolve their paths relative to `rust/fuzz/`: ```bash cd rust/fuzz