188 lines
9.1 KiB
Markdown
188 lines
9.1 KiB
Markdown
# Fold SAST / DAST / Symbolic Roadmap
|
|
|
|
> Date: 2026-06-02
|
|
> Scope: roadmap after recent Ghidra/P-Code, gadget, ROP-chain, and vendor-pruning work.
|
|
|
|
Fold should evolve as a **three-lane vulnerability engine** rather than one monolithic analyzer.
|
|
The lanes share reports and provenance, but keep their evidence separate.
|
|
|
|
```text
|
|
Source C/C++ ── Clang AST/CFG ──▶ Source facts ─┐
|
|
│
|
|
Binary ── LIEF/r2 metadata + Ghidra P-Code ───▶ Binary facts ─┐
|
|
▼
|
|
Fold fact/graph layer + symbolic obligations
|
|
│
|
|
▼
|
|
Z3 bounded proof / heuristic finding
|
|
│
|
|
▼
|
|
Existing + generalized confirmation layer
|
|
confirm runner / libFuzzer+ASan / KLEE / SymCC / angr
|
|
```
|
|
|
|
## Lane 1 — Source SAST
|
|
|
|
Keep Clang as the source of truth for C/C++ semantics. Detectors should move toward
|
|
this pipeline:
|
|
|
|
1. cheap AST/fact prefilter;
|
|
2. graph/data-flow query;
|
|
3. bounded Z3 proof obligation;
|
|
4. optional dynamic confirmation.
|
|
|
|
References:
|
|
|
|
- Clang Static Analyzer: https://clang.llvm.org/docs/ClangStaticAnalyzer.html
|
|
- Clang data-flow analysis intro: https://clang.llvm.org/docs/DataFlowAnalysisIntro.html
|
|
- CodeQL C/C++ library/data flow: https://codeql.github.com/docs/codeql-language-guides/codeql-library-for-cpp/
|
|
- Code Property Graphs: https://www.ieee-security.org/TC/SP2014/papers/ModelingandDiscoveringVulnerabilitieswithCodePropertyGraphs.pdf
|
|
|
|
## Lane 2 — Binary SAST
|
|
|
|
Keep binary evidence separate from source evidence.
|
|
|
|
| Tool | Fold role |
|
|
|---|---|
|
|
| r2 | fast fallback extraction: functions, strings, xrefs, rough metadata |
|
|
| LIEF | stable ELF/PE/Mach-O metadata candidate |
|
|
| Ghidra/SLEIGH | binary instruction semantics through raw/high P-Code |
|
|
| Capstone | gadget byte-window discovery only; not semantic proof |
|
|
|
|
References:
|
|
|
|
- Ghidra P-Code: https://ghidra.re/ghidra_docs/languages/html/pcoderef.html
|
|
- Ghidra SLEIGH: https://ghidra.re/ghidra_docs/languages/html/sleigh.html
|
|
- LIEF C++ API: https://lief.re/doc/latest/api/cpp/index.html
|
|
- radare2 book: https://book.rada.re/intro/overview.html
|
|
|
|
## Lane 3 — DAST / concolic confirmation
|
|
|
|
Fold already has two concrete confirmation surfaces:
|
|
|
|
- `fold confirm`: deeper bounded symbolic confirmation for selected findings,
|
|
with optional SV-COMP GraphML witnesses.
|
|
- `fold fuzz prep` + `fold fuzz run`: emits `findings.predicted.json`, compiles
|
|
libFuzzer/ASan harnesses, matches ASan crashes back to `Finding.id`, and
|
|
promotes matching findings to `Confidence::ConcreteWitness`.
|
|
|
|
Fold should not become KLEE, angr, or a web scanner. The shipped confirmation
|
|
paths now also have a shared machine-readable `FindingConfirmationTask` /
|
|
`FindingConfirmationResult` model, plus compatibility sidecars for the fuzz path.
|
|
The remaining design work is to deepen adapter coverage and attach stable fact
|
|
IDs at more detector emission sites.
|
|
|
|
Suggested schema:
|
|
|
|
```text
|
|
FindingConfirmationTask {
|
|
finding_id: string
|
|
backend: source | binary | hybrid
|
|
lane: clang | ghidra-pcode | r2-heuristic | lief-metadata
|
|
target: { file_or_binary, function, source_location?, binary_address? }
|
|
input_channel: argv | stdin | file | env | socket | harness | unknown
|
|
controlled_values: [name_or_register]
|
|
path_predicate: textual-or-SMTLIB summary
|
|
hazard: div-by-zero | null-deref | overflow | oob | uaf | taint-sink | rop-reachable
|
|
expected_violation: string
|
|
suggested_adapter: klee | symcc | libfuzzer | afl | angr | triton | manual
|
|
artifacts: [seed, harness, compile_db, binary]
|
|
}
|
|
```
|
|
|
|
Result states should align with Fold's existing confidence model:
|
|
|
|
```text
|
|
syntactic -> heuristic -> proved -> concrete-witness
|
|
↘ refuted | timeout | unsupported
|
|
```
|
|
|
|
`ConcreteWitness` is already first-class: a SAT-feasible/static finding was run
|
|
under ASan/libFuzzer and produced a matching crash. New adapters should preserve
|
|
that semantics instead of creating a parallel confidence vocabulary.
|
|
|
|
KLEE is the next source-confirmation adapter family. A narrow optional prototype
|
|
now consumes a `FindingConfirmationTask`, compiles a source artifact to LLVM
|
|
bitcode, runs KLEE when installed, and writes a `FindingConfirmationResult`.
|
|
Absent KLEE skips cleanly. The current smoke path is
|
|
`tests/confirmation/klee/run_klee_smoke.sh`.
|
|
|
|
References:
|
|
|
|
- KLEE: https://www.usenix.org/conference/osdi-08/presentation/klee-unassisted-and-automatic-generation-high-coverage-tests-complex
|
|
- SymCC: https://www.usenix.org/conference/usenixsecurity20/presentation/poeplau
|
|
- S2E: https://dl.acm.org/doi/10.1145/2110356.2110358
|
|
- Driller: https://www.ndss-symposium.org/wp-content/uploads/2017/09/driller-augmenting-fuzzing-through-selective-symbolic-execution.pdf
|
|
- QSYM: https://www.usenix.org/conference/usenixsecurity18/presentation/yun
|
|
- angr: https://docs.angr.io/en/latest/
|
|
- Triton: https://triton-library.github.io/
|
|
|
|
## Benchmark plan
|
|
|
|
| Benchmark | Purpose |
|
|
|---|---|
|
|
| Juliet C/C++ | source SAST CWE recall/precision |
|
|
| SV-COMP | verifier discipline and witness style |
|
|
| CGC | binary/concolic exploration |
|
|
| Magma | fuzz/DAST reached-vs-triggered bug metrics |
|
|
|
|
References:
|
|
|
|
- Juliet/SARD: https://samate.nist.gov/SARD/test-suites/112
|
|
- SV-COMP benchmarks: https://sv-comp.sosy-lab.org/2025/benchmarks.php
|
|
- Magma: https://hexhive.epfl.ch/magma/
|
|
|
|
## Near-term implementation order
|
|
|
|
1. Harden the current ROP planner correctness issues. **Done.**
|
|
2. Guard executable-section extraction by host memory, not fixed byte caps, so gadget scans preserve precision whenever the hardware can support the image. **Done.**
|
|
3. Add `FindingConfirmationTask` as a report/schema concept over the existing
|
|
`confirm` and `fuzz prep/run` paths. **Done: see `include/fold/confirm/confirmation_task.hpp`.**
|
|
4. Add optional KLEE/SymCC/angr adapters that consume the same task schema.
|
|
**KLEE smoke prototype done; SymCC/angr remain open.**
|
|
5. Define stable fact IDs before Souffle. **Done for the model: see
|
|
`include/fold/ir/fact_id.hpp`; broader detector emission-site population remains open.**
|
|
6. Harden binary P-Code false-positive controls for common libc and guarded-arithmetic cases.
|
|
**Done for the first curl-derived regressions and follow-up path-order cases:** P-Code call
|
|
semantics now preserve fortified `_chk` wrappers, SSA sink naming trusts raw call-site
|
|
correlation instead of synthesized target fallbacks, raw div/rem findings are gated by machine
|
|
division instruction addresses, and bounded forward P-Code path exploration forks `CBRANCH`
|
|
taken/fallthrough paths while stopping local fallthrough on forward `BRANCH`/`RETURN`. A full
|
|
basic-block CFG with joins remains future precision work.
|
|
|
|
## Status audit — 2026-06-03
|
|
|
|
Completed or substantially implemented:
|
|
|
|
- Source, binary, and confirmation lanes remain separate in implementation and report provenance.
|
|
- Confirmation task/result schema exists and is used by `confirm` and `fuzz prep/run` sidecars.
|
|
- KLEE smoke adapter exists and skips cleanly when unavailable.
|
|
- Stable fact ID model exists.
|
|
- ROP planner/gadget extraction has focused regression coverage.
|
|
- Binary P-Code curl-smoke false positives from `memchr`/`memcpy`, fortified `strncpy_chk`,
|
|
guarded `udiv`, taken-target ordering, and branch-skipped fallthrough hazards are covered by
|
|
unit tests and the `/usr/bin/curl` smoke scan.
|
|
- Latent/precondition evidence is now produced by null/div detector paths, not only serialized in
|
|
JSON/SARIF.
|
|
- Hybrid profile merging preserves lane timing/counter fields, keeping source and binary lanes
|
|
separately measurable in merge-only hybrid mode.
|
|
|
|
Future expansion ideas, not required for the current shipped scope:
|
|
|
|
- SymCC and angr adapters over the shared confirmation task/result schema. The shipped
|
|
confirmation lane is already useful with `confirm`, `fuzz prep/run`, and optional KLEE smoke.
|
|
- Broader fact ID population at additional detector emission sites. The current fact ID model is
|
|
in place; expanding coverage is incremental provenance work.
|
|
- Reproducible benchmark harness scripts for Juliet, SV-COMP, CGC, and Magma. These are evaluation
|
|
infrastructure, not core feature blockers.
|
|
- Full P-Code basic-block CFG/path exploration with join policies. The shipped binary lane now has
|
|
bounded forward path exploration for observed false positives and block-order regressions; full
|
|
CFG joins remain a precision upgrade, not a prerequisite.
|
|
|
|
## Guardrails
|
|
|
|
- Do not route decompiled C from binaries through source detectors.
|
|
- Do not let dynamic confirmation erase unconfirmed static findings; report it as a separate state.
|
|
- Keep binary metadata, binary semantics, source semantics, and dynamic witnesses separately measurable.
|
|
- Every finding and confirmation task must preserve backend/lane provenance.
|
|
- Keep `confirmation.tasks.json` and `confirmation.results.json` sidecars compatible with legacy `findings.predicted.json` and augmented findings JSON.
|