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

58 lines
2.5 KiB
Markdown

# 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