fold/docs/internal/cpp-fuzz-coverage-research.md
trvon 18ce5a6050
docs: Swift/C++ ABI, fuzzing, IR, MIR research for multi-language pipeline
- Swift ABI: tagged pointers, garbage-input abort path, ObjC bridging
- C++ fuzz: libFuzzer dlopen coverage limits, AFL++ QEMU mode, vtable seeding
- Cross-language IR: CodeQL/Infer/Joern patterns, Swift SIL gaps in fold IR
- MIR verification: Kani/Prusti/Creusot approaches, BorrowTracker wiring
2026-05-28 10:28:41 -04:00

2.5 KiB

C++ Fuzz Coverage Research for fold Binary Pipeline

Generated 2026-05-28. Research on binary fuzzing coverage for fold.

libFuzzer + dlopen Coverage

  • -fsanitize=fuzzer instruments the harness compilation unit only
  • Code in the dlopen'd library is NOT instrumented
  • Result: coverage guided by the harness's own basic blocks (which is just LLVMFuzzerTestOneInput + call wrappers)
  • cov:2 observed — only the harness entry + function call, no library code coverage

AFL++ Options for Binary-Only Targets

QEMU mode (afl-fuzz -Q):

  • Runs the entire binary under QEMU user-mode emulation
  • QEMU's TCG (Tiny Code Generator) inserts coverage instrumentation at runtime
  • Works with any binary — no source needed, no recompilation
  • ~2-5x slowdown vs native execution
  • Output: afl-fuzz -Q -i corpus -o out -- ./harness

Binary-only instrumentation (afl-fuzz -n):

  • No instrumentation, purely black-box
  • Much less effective than coverage-guided modes
  • Not recommended for real campaigns

RetroWrite / E9AFL:

  • Static binary rewriting to inject AFL coverage
  • Works on x86_64 binaries without source
  • Not available for ARM64 (macOS) targets

C++ Vtable Fuzzing

Vtable entries are reachable through:

  • Object construction → virtual call dispatch
  • Each _ZTV* symbol in the binary maps to a vtable
  • Functions pointed to by vtable entries are valid fuzz targets

Approach for fold:

  1. Parse _ZTV* symbols to extract vtable function pointers
  2. Generate harnesses that construct mock objects with those vtables
  3. Call through the vtable slots with fuzzer-generated arguments

ASan + dlopen Behavior

  • ASan instruments the harness at compile time
  • dlopen'd libraries are NOT instrumented unless compiled with -fsanitize=address
  • But: ASan runtime can catch crashes in non-instrumented code (SIGSEGV, SIGABRT)
  • Shadow memory tracking only works within instrumented code
  • For binary-only targets: crashes caught, memory errors missed

Recommendation: Compile harness with ASan, accept that only crash-level findings are captured.

Recommendations for fold

  1. Current approach works for crash-finding: -fsanitize=fuzzer,address on harness catches crashes from non-instrumented code
  2. Coverage is limited: QEMU-mode AFL++ would give real coverage at the cost of complexity
  3. Vtable fuzzing is the next high-impact addition: parse _ZTV* symbols, generate harnesses with mock vtables
  4. ASan pragmas: add __attribute__((no_sanitize("address"))) to the harness's memcpy calls to avoid false ASan reports on fuzzer input copying