Commit graph

13 commits

Author SHA1 Message Date
trvon
76bc00f635
test(fanout): build the failure worker before the recovery tests
fold:subprocess_fanout reads FOLD_TEST_FANOUT_FAILURE_WORKER, but the
worker target is build_by_default: false and the test declared
`depends: []`, so a plain `meson test -C build/release` ran the two
recovery cases against a binary that was never built and failed both
(`REQUIRE(std::filesystem::exists(helper))`). The test now depends on
the worker, and the suite is green from a fresh build.
2026-09-24 20:00:17 -06:00
trvon
86b2f14a43
feat(analysis): harden project-wide scans
- persist TU-owned graphs and guarded configuration evidence
- add closed-world production reachability classification
- calibrate detector precision and reviewed self-scan policy
- terminate poisoned workers instead of longjmp recovery
2026-07-30 18:18:04 -04:00
trvon
bcdcb3036b
feat(analysis): harden quality and solver pipelines 2026-07-29 20:46:51 -04:00
trvon
b0b51f1e71
feat: converge quality and scan interfaces
- fail closed on MCP input and compile database policy
- add shared scan catalogs, finding queries, and tiered gates
2026-07-29 00:57:33 -04:00
trvon
45b31c6b5a
feat(swift): harden SIL scanner 2026-07-20 14:52:50 -04:00
trvon
374aa7475d
many good updates for binary and SAST / DAST scanning 2026-06-02 12:39:03 -04:00
trvon
95aac8209c
feat: expand rust security scanner coverage 2026-05-27 11:32:05 -04:00
trvon
ce1c353847
feat: harden security scanner routing 2026-05-27 10:36:57 -04:00
trvon
93eb1f09b2
feat(fuzz): M31 Phase 2 — closed-loop fuzz-run promotes to ConcreteWitness
End-to-end: fold scan → fuzz-prep emits Z3-derived seed → fuzz-run
compiles + libFuzzer + ASan → crash ingested → predicted Finding
promoted from Proved to ConcreteWitness in ~1s wall-clock.

P2.1 — Confidence::ConcreteWitness tier
* Strictly stronger than Proved: SMT-feasibility + observed runtime
  failure. confidenceRank() gives explicit numeric ordering so the
  enum integer values stay incidental.
* FindingKind::FuzzCrash for surprise crashes the SymEx side didn't
  predict.
* FuzzWitness evidence sub-struct (seed_path, asan_kind, asan_file,
  asan_line) + JSON round-trip.

P2.2 — ASan stderr parser
* include/fold/fuzz/asan_parser.{hpp,cpp} (~150 LOC)
* Parses the canonical SUMMARY tail line — stable across LLVM 15–22
  for both ASan (heap-buffer-overflow, SEGV, …) and UBSan
  (signed-integer-overflow, …)
* test_asan_parser.cpp: 6 cases / 27 assertions

P2.3 — FuzzRunner
* include/fold/fuzz/runner.{hpp,cpp}
* Synchronous: compile + posix_spawn + waitpid-with-deadline +
  artifact-scan. SIGTERM + 1s grace + SIGKILL on parent timeout.
* Per-source `-x c` / `-x c++` pinning so C targets keep their
  C linkage and the harness's extern "C" decl resolves.
* Drops -std= entirely — generated harnesses are pre-C++17.

P2.4 + P2.5 — fuzz-run CLI + crash ingestion
* src/cli/fuzz_run_runner.cpp: load findings.predicted.json, group
  by function, runFuzzCampaign per harness, replay each crash under
  ASan, parse SUMMARY, match (file, line) to predicted Finding.id.
* Matched crashes → augmented Finding with Confidence::ConcreteWitness
  + evidence.fuzz_witness. Unmatched → FindingKind::FuzzCrash.
* Subcommand: --prep-dir, --target-source (rep), --time-budget,
  --compiler, --report, --clang-flag.

P2.6 — integration test
* tests/integration/test_fuzz_run.cpp: probes for a clang++ that can
  link -fsanitize=fuzzer, builds the null-deref-behind-guard fixture,
  chains runFuzzPrep + runFuzzRun, asserts at least one
  concrete-witness Finding whose id matches a predicted Finding.id.
* WARN+SUCCEED when no libFuzzer-capable compiler is found so CI
  on stripped clang installs stays green.

Tests: 39 → 40 green.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 15:21:05 -04:00
trvon
075dd85669
feat(fuzz): R3-oob + P1.7 — full witness coverage + e2e test
R3-oob: oob_access now hoists z3::model out of both solver branches
and passes it to recordSinkWitnessWithModel. Predicted seeds for
`int buf[N]; return buf[idx];` now contain Z3's chosen boundary-
violating idx (e.g. `04 00 00 00` for buf[4]) instead of zeros.

P1.7: tests/integration/test_fuzz_prep.cpp materializes a
null-deref-behind-`flag==0xAB`-guard fixture, drives runFuzzPrep
in-process, and asserts the witness seed contains the exact magic
byte (0xAB at offset 0) plus a well-formed harness (extern "C",
size-gate at total_bytes, leaky(arg0, arg1) call).

Moves fuzz_prep_runner.cpp from the fold executable target into
fold_core_sources so the integration test can link runFuzzPrep
directly.

Tests: 37 → 38 green.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 14:39:17 -04:00
trvon
a51cdf5748
M19–M30 + scout-rule encoder refactor
Multi-phase work merged into one commit:

* M19: flow-sensitive guard tracking (stmtAlwaysExits, walkIf early-exit)
* M20–M27: non-null marking across deref, addr-of, callsite preconds,
  if/while/switch guards, AddrOf-of-subexpr, CFG-block-scoped maps
* M30 Phase A: dialect-agnostic SourceLoc + LocationMapper + frontend/
  boundary marker; ClangLocationMapper wired through SafetyObserver
* M30 Phase B v2: QueryTracer + 13 SafetyObserver hooks migrated to
  ir::Expr / ir::Call / ir::MemberRef / ir::Symbol / ir::SourceLoc
* M30 Phase C/D/D2/D3: ir::Symbol, ir::Expr (with Kind), ir::Call,
  ir::MemberRef opaque types; ir_expr_clang.cpp houses the clang
  adapters; encodeExpr migrated to switch(kind) dispatch

Scout-rule extractions from encoder.cpp (2800 → 2371 lines):
* encoder_callee_predicates.{hpp,cpp} — isMallocLikeCall, isFreeCall,
  isAssertCall as pure std::string_view predicates
* encoder_type_queries.{hpp,cpp} — typeSizeBytes, sourceWidth,
  isUnsignedLike, byteWidthExpr
* encoder_callee_names.{hpp,cpp} — calleeName, qualifiedFunctionName,
  qualifiedCalleeName (with internal-linkage @-suffix)
* encoder_coerce.{hpp,cpp} — coerceToBv, coerceToExactBv, coerceToBool,
  coerceToType (BV-64 storage model documented at the boundary)
* encoder_reachability.{hpp,cpp} — ReachabilityCounter impl, markEncoded,
  recordEncoded, recordBailedNode, public profiling glue
* encoder_summary_instantiate.cpp — SMT-LIB summary substitution
  (instantiateSummaryExpr / Predicate / PredicateInContext +
  applySummaryParamPost; kills the redundant *Impl pass-through layer)
2026-05-21 11:17:50 -04:00
trvon
c4e42cec0a
Add scan router and MCP job queue
Split source and binary scan routing with merge-only hybrid support, binary provenance, and router-backed MCP scan contexts.

Add async MCP scan jobs for long-running scans, detector precision fixes, benchmark scripts, docs, and integration coverage.
2026-05-19 00:24:12 -04:00
trvon
3f1234f7bb
fold: bounded symbolic SAST for C++
Clang LibTooling + Z3 BV-64 encoding.
11 detectors: clone, equiv, class-dup, dead, null-deref,
div-by-zero, int-overflow, oob, int-truncation,
sign-conversion, taint-track.

Interfaces: CLI, MCP (JSON-RPC 2.0), LSP.
Output: SARIF 2.1.0, JSON, Markdown.
2026-05-14 23:14:54 -04:00