-
Notifications
You must be signed in to change notification settings - Fork 582
test: add libfuzzer harness for bbapi API #19465
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
ludamad
wants to merge
56
commits into
next
Choose a base branch
from
ad/test/bbapi-fuzzer
base: next
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
+5,603
−46
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Updates the noir submodule to noir-lang/noir#10878 which adds C++ codegen support for msgpack-compact serialization format. Also exports NOIR_SERIALIZATION_FORMAT=msgpack-compact in source_bootstrap. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Copy the foundry cache folder to a temporary location before running forge scripts to avoid conflicts when multiple deployments run in parallel. The cache folder is small metadata that links to the out folder, so this is a fast operation. Also write broadcasts to the temp cache folder. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
…code This script modifies autogenerated C++ header files to only support the msgpack-compact format by: - Removing bincode serialization methods - Simplifying msgpack_pack to use array format instead of map format - Simplifying msgpack_unpack to only support ARRAY format (compact) - Removing unused Helpers functions for key-value map handling
- Updated Python filter to also transform enum variant msgpack_pack to avoid requiring msgpack::object adaptors - Replaced deserialize_any_format with deserialize_msgpack_compact - Added msgpack_compact_serialize helper to utils.hpp - Updated test files to use msgpack serialization - Removed bincode declarations and implementations from serde files 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The noir serialization now defaults to msgpack-compact, so we no longer need to set NOIR_SERIALIZATION_FORMAT in source_bootstrap. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Removed unused arguments for bulk testing.
…/msgpack-compact-only
Add comprehensive fuzzer harness targeting the bbapi API to detect memory corruption issues via ASAN. The fuzzer exercises: - Msgpack command deserialization and dispatch - ACIR bytecode parsing (msgpack-compact format) - Witness file parsing - Circuit prove/verify operations with malformed inputs - Chonk IVC command sequences - Cryptographic primitive commands (Poseidon2, Blake2s, Pedersen, AES, ECC) - Verification key parsing Includes custom mutator for structure-aware fuzzing with: - Format marker byte mutations - Field element mutations - Msgpack type marker injection - Length field modifications 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add comprehensive skill guide for writing libfuzzer harnesses covering: - File naming conventions (*.fuzzer.cpp) - Basic fuzzer structure with LLVMFuzzerTestOneInput - Custom mutator patterns for structure-aware fuzzing - Multi-mode dispatch, VM/instruction, and differential patterns - Barretenberg-specific utilities (FastRandom, field mutations) - Exception handling strategies for API vs circuit code - CMakeLists.txt integration - Msgpack format marker awareness - Namespace ambiguity resolution - Reference table of existing fuzzers Based on analysis of 36 existing fuzzers in the codebase including AVM, hash functions, field primitives, and proving system fuzzers. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…ties - Move circuit_should_fail definition to fuzzer.cpp - Add fuzzer_msgpack.hpp with msgpack mutation utilities - Remove duplicate circuit_should_fail from stdlib fuzzer headers - Simplify skill documents for fuzzer writing 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove fuzzing-acir skill (too verbose) - Move fuzzer_msgpack.hpp to bbapi/fuzzing/ - Add acir_bytecode.fuzzer.cpp - tests circuit_buf_to_acir_format - Add witness_data.fuzzer.cpp - tests witness_buf_to_witness_vector - Both use msgpack-aware custom mutators 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Also enhance fuzzer_msgpack.hpp with extreme length mutations to better test memory allocation edge cases. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use msgpack::unpack_limit to set reasonable bounds on array/map/str/bin sizes during deserialization. This prevents memory exhaustion attacks and invalid memory access from malformed msgpack data. Limits: - array/map: 10M elements - str/bin/ext: 100MB - depth: 15 levels 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Move msgpack unpack limits to msgpack_limits.hpp so they can be shared between deserialization code and fuzzers. Update fuzzer to target these specific limits (MAX_DEPTH, MAX_ARRAY, etc.) with 18% of mutations. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Also add targeted limit mutations to fuzzer (18% of mutations). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2c1ae99 to
bddae56
Compare
When deserializing enum variants from msgpack, the code allowed both MAP and STR types. For non-unit variants, after extracting the tag from either type, the code unconditionally accessed o.via.map.ptr[0].val to get the associated data. When o.type was STR, the via union contained string data (via.str), not map data (via.map), causing garbage pointer dereference. This fix adds a type check before accessing via.map for non-unit variants, throwing an error if STR encoding is used for variants that require data. Also refactors Helpers to use msgpack's convert() API instead of manual pointer iteration, and limits hash_index in fuzzer to avoid timeouts. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
- Add msgpack_limits.hpp with reasonable size limits for unpacking - Apply limits to deserialize_msgpack_compact to prevent memory exhaustion - Add type checking before o.via.map.ptr[0].val access in enum variant msgpack_unpack methods (71 locations) to prevent SEGV when STR type is incorrectly used for non-unit variants These changes prevent SEGV crashes from malformed msgpack data where the via union is accessed with incorrect type assumptions. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Generates valid ACIR Circuit objects directly and tests the constraint processing pipeline (circuit_serde_to_acir_format). Unlike the bytecode fuzzer that tests msgpack deserialization, this fuzzer: - Constructs syntactically valid ACIR structures - Randomizes field values, witness indices, opcode parameters - Creates sparse witness maps with gaps (1% chance 100-10000 gap) - Tests all BlackBoxFuncCall variants - Tests MemoryInit/MemoryOp opcodes - Tests BrilligCall opcodes No serialization overhead - objects go directly to processing logic. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add MAX_WITNESS_INDEX limit (10M) to prevent OOM when filling sparse witness vectors - Add safe_msgpack_unpack() utility function with security limits - Add witness index validation in circuit_serde_to_acir_format() and witness_map_to_witness_vector() - Update bbapi.fuzzer.cpp to use safe_msgpack_unpack() - Update acir_gen.fuzzer.cpp to use consistent witness index limits 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add 4 new specialized fuzzers for comprehensive coverage of bbapi deserialization attack surface: - blackbox_opcodes.fuzzer.cpp: All 14 BlackBoxFuncCall ACIR opcodes - crypto_commands.fuzzer.cpp: Cryptographic command inputs (Schnorr, ECDSA, etc.) - witness_deser.fuzzer.cpp: Witness map deserialization edge cases - verification.fuzzer.cpp: Proof/VK deserialization These fuzzers use structure-aware generation with seed-based determinism to test edge cases like empty inputs, max sizes, invalid bit widths, sparse witness maps, and malformed proofs. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add minimum size checks in VkAsFields, MegaVkAsFields, and CircuitWriteSolidityVerifier execute() methods before calling from_buffer() to deserialize verification keys. Without this check, a malformed VK with too few bytes causes from_buffer to read past the end of the buffer, resulting in a SEGV (null pointer dereference). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The custom mutators were returning input unchanged, preventing libfuzzer from effectively exploring code paths. Removing them allows libfuzzer's default mutation strategy to work, resulting in significantly better coverage (e.g., blackbox went from cov:2 to cov:1962). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add minimum size check in _verify() to prevent read overflow when deserializing verification keys. This fixes a SEGV crash when CircuitVerify is called with a malformed VK buffer. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Malformed msgpack objects can have type MAP but a null pointer for the map data. Add explicit check before iterating to prevent SEGV. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The null pointer check for MAP objects was unnecessary because: 1. msgpack's zone allocator always returns valid memory or throws 2. start_map() always allocates ptr when size > 0 3. The type check alone is sufficient protection Testing confirmed crash files are handled without this check. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace hardcoded minimum VK size checks with exact size validation computed from each Flavor's NUM_PRECOMPUTED_ENTITIES constant. VK serialized size = 3 * sizeof(uint64_t) + NUM_PRECOMPUTED_ENTITIES * 64 This removes magic numbers and ensures the size check is accurate for each flavor type (Ultra, Mega, UltraKeccak). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The msgpack zone allocator never returns null - it throws std::bad_alloc on failure. Type checking alone is sufficient protection. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add two new fuzzers to target fresh areas: - ecc_primitives.fuzzer: Tests fr/fq field elements, g1/g2/grumpkin points, and uint256_t/uint512_t deserialization via from_buffer - chonk_proof.fuzzer: Tests ChonkProof msgpack deserialization These complement the existing fuzzers to improve coverage of cryptographic primitive parsing and proof structure handling. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fuzzer found that several ECC functions were marked noexcept but could throw exceptions when inverting zero or converting points at infinity. Functions fixed: - field::invert() - throws when inverting zero - element::operator affine_element() - throws via invert when z=0 - affine_element::operator+ and operator* - call throwing functions Also adds two new fuzzers: - crypto_signatures: tests ECDSA and Schnorr signature verification - hash_operations: tests Blake2s, Blake3s, Keccak256, SHA256, Poseidon2 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add two new fuzzers to improve coverage of cryptographic primitives: - ecc_operations.fuzzer.cpp: Tests actual ECC operations including point addition, scalar multiplication, MSM, compression/decompression, batch normalization, and Grumpkin curve operations - pedersen_ops.fuzzer.cpp: Tests Pedersen hash and commitment operations with various input sizes and generator indices 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add a static constexpr serialized_size() method to NativeVerificationKey_ that calculates the expected byte size of a serialized VK. This replaces duplicated size calculations across bbapi_ultra_honk.cpp with a single source of truth. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add bbapi_msgpack.fuzzer.cpp: Fast fuzzer for bbapi command msgpack deserialization (~27k exec/s) - Add field_arithmetic.fuzzer.cpp: Fast fuzzer for field element operations (~66k exec/s) - Speed up witness_deser.fuzzer.cpp by reducing MAX_WITNESS_INDEX from 100k to 1k and entry count from 100 to 20 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- trace_to_polynomials: Use .at() for bounds checking on real_variable_index to prevent OOB access with malformed ACIR witness indices - bbapi_chonk: Validate VK buffer size before deserialization to prevent buffer overread attacks - bbapi_ultra_honk: Reject oversized proofs by checking all proof data was consumed during verification - transcript: Add verify_proof_fully_consumed() helper method 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
582b91a to
7af41a9
Compare
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Adds a libfuzzer fuzzing harness for the bbapi API to detect memory corruption and safety issues. The harness targets a variety of inputs including proof files, ACIR bytecode for Ultrahonk, nested msgpack inputs for Chonk, multiple ACIR opcodes, and witness files. The fuzzer runs under ASAN (AddressSanitizer) to catch memory safety violations and undefined behavior. This provides comprehensive fuzz testing coverage of the bbapi attack surface.