Skip to content

Split AVM fuzzers into dedicated container#22601

Draft
randyquaye wants to merge 9 commits intonextfrom
rq/split-avm-fuzzing-container
Draft

Split AVM fuzzers into dedicated container#22601
randyquaye wants to merge 9 commits intonextfrom
rq/split-avm-fuzzing-container

Conversation

@randyquaye
Copy link
Copy Markdown
Collaborator

Summary

  • Remove fuzzing-avm preset build from the non-AVM fuzzing-container — it built AVM binaries but couldn't run them (no Node.js)
  • Rewrite avm-fuzzing-container to build all 14 AVM fuzzer targets with Node.js runtime, coverage variants, and a ContFuzzer v2 entrypoint
  • Auto-generate manifest via flatten_and_manifest.py (same pattern as fuzzing-container)

What changed

fuzzing-container (removal)

  • Dropped fuzzing-avm cmake configure + build steps
  • Removed bin-fuzzing-avm and --preset-resources fuzzing-avm:1:8 from flatten_and_manifest.py call

avm-fuzzing-container (rewrite)

  • Dockerfile: aztecprotocol/build:3.0-amd64 base, Node.js 24, full bootstrap + yarn-project, builds all AVM fuzzers + coverage variants, flatten_and_manifest.py for manifest generation, llvm-20 in runtime
  • entrypoint.sh: ContFuzzer v2 interface (FUZZ_MODE, FUZZ_TARGET, etc.), FUZZ_MEMORY → per-worker RSS derivation, -close_fd_mask=3 for Node.js noise, non-fatal regression, timeout/OOM artifact processing, corpus backup/restore, content hash generation for LCOV
  • run.sh: v2 local runner with --target/--mode/--list-targets/--workers/--max-len

Test plan

  • Review Dockerfiles for correctness (can't docker build on macOS ARM)
  • Verify fuzzing-container no longer references AVM in Dockerfile
  • Verify avm-fuzzing-container uses flatten_and_manifest.py for manifest generation
  • Build avm-fuzzing-container on amd64 and verify all 14 targets appear in /targets/

Remove the fuzzing-avm preset from the non-AVM fuzzing-container (it
built AVM binaries but couldn't run them without Node.js). Rewrite the
avm-fuzzing-container to build all 14 AVM fuzzer targets with Node.js
runtime, coverage variants, and a ContFuzzer v2 entrypoint.

Key changes:
- fuzzing-container: drop fuzzing-avm build and manifest references
- avm-fuzzing-container: full rewrite with aztecprotocol/build base,
  bootstrap + yarn-project, auto-generated manifest via
  flatten_and_manifest.py, coverage build, llvm-20 tooling
- New v2 entrypoint: FUZZ_MEMORY parsing, -close_fd_mask=3 for Node.js
  noise, non-fatal regression, timeout/OOM artifact handling, corpus
  backup/restore, content hash generation for LCOV
- run.sh adopts ContFuzzer v2 env-var interface with --target/--mode
Match the fuzzing-container and contfuzzer-claude behavior where
the regress mode is fatal when failures are found.
- Coverage build: use clang-20 to match the fuzzing-avm preset
  (was clang-18, causing a compiler mismatch)
- regress() helper: mv failures out of corpus instead of cp, so
  known-bad inputs don't stay in the corpus during fuzzing
The fuzzing-container workflows extract and attach the fuzzer manifest
via oras so the platform can discover targets without pulling the full
image. The AVM workflows were missing this step.
- Move source tree copy before builds to avoid copying gigabytes of
  build artifacts into the "clean" source snapshot
- Coverage source tree: place at /root/aztec-packages/ (same as build
  path) so llvm-cov finds source files without path remapping
- Add chmod a+rx /root so UID 65534 can traverse into /root/aztec-packages/
  for coverage reports
- Coverage build: add CMAKE_BUILD_TYPE=RelWithAssert, DISABLE_ASM=OFF,
  MULTITHREADING=ON to match the fuzzing-avm preset
- Align CRS path on /opt/bb-crs with explicit chmod in both Dockerfiles
- run.sh: remove -m short flag for --mode to avoid conflict with the
  old -m/--max-len usage
When fuzzing-avm is the first (or only) positional manifest, the dedup
logic was filtering every target against itself — producing an empty
manifest. The dedup is only needed when a prior non-AVM base manifest
exists (i > 0), so that collateral rebuilds of base targets in the AVM
preset are excluded. When fuzzing-avm is the sole manifest (as in the
avm-fuzzing-container), all targets should be scheduled.
- flatten_and_manifest.py: fix dedup filtering all targets when
  fuzzing-avm is the only positional manifest (add i > 0 guard)
- Dockerfile: build only 14 AVM-specific targets via --target list
  (avoids 17 collateral non-AVM rebuilds, cuts ~15 GB from image)
- Coverage build: set FUZZER_PRESET_NAME=fuzzing-cov so binaries get
  _cov suffix (was _unknown), matching entrypoint COV_BINARY lookup
- Coverage build: add CMAKE_BUILD_TYPE, DISABLE_ASM, MULTITHREADING
  to match fuzzing-avm preset settings
- Source tree: copy before builds to avoid including build artifacts
- Source tree: place at /root/aztec-packages/ to match builder paths
  so llvm-cov finds source files without path remapping
- chmod a+rx /root for UID 65534 traversal to coverage sources
- Align CRS on /opt/bb-crs in both Dockerfiles
- run.sh: drop -m short flag for --mode (conflicts with old --max-len)
module.cmake: register AVM-specific fuzzer targets into a new global
property BB_AVM_FUZZER_TARGETS (source path matches avm_fuzzer/).

avm_fuzzer/CMakeLists.txt: add `avm_fuzzers` umbrella target that
depends on BB_AVM_FUZZER_TARGETS + fuzzer_manifest. New fuzzers added
under avm_fuzzer/ are picked up automatically — no Dockerfile changes.

flatten_and_manifest.py: fix dedup filtering all targets when
fuzzing-avm is the only positional manifest (add i > 0 guard).

Dockerfiles: use `--target avm_fuzzers` instead of building entire
preset (avoids 17 collateral non-AVM rebuilds). Set
FUZZER_PRESET_NAME=fuzzing-cov for coverage build so binaries get
_cov suffix. Add CMAKE_BUILD_TYPE, DISABLE_ASM, MULTITHREADING.
Copy source tree before builds. Place coverage sources at build path
(/root/aztec-packages/) for llvm-cov. Align CRS on /opt/bb-crs.
Add chmod a+rx /root for UID 65534 traversal.

run.sh: drop -m short flag for --mode (conflicts with old --max-len).
The fuzzing-asan preset was missing FUZZER_PRESET_NAME, causing
generate_fuzzer_manifest.py to produce suffix _unknown instead of
_asan. The entrypoint looks for _asan companions for crash
reproduction and silently falls back to the main binary when they
have the wrong name.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant