Commit graph

15 commits

Author SHA1 Message Date
trvon
8a32f08fd7
fix(int-overflow): render witnesses in the source type's width and sign
Problem: symbols are 64-bit bitvectors whose low bits carry the source
value, but int-overflow witnesses printed the whole bitvector. For a
32-bit `int a` the report showed a=2147483648 or a=-9223372034707292160,
which are not values of `a` and would make bad fuzz seeds
(tests/fixtures/clones/exact.cpp).

Fix: detect::sourceIntTypesOf() maps the function's integer parameters
and locals to their width and signedness (a name declared with two types
is left out). collectModelBindings() takes that map and prints each bound
symbol truncated to its source width with its signedness
(formatSourceIntValue). int-overflow passes the map for the current
function; other detectors are unchanged.

Test: test_int_overflow "[witness]": every binding for an `int` overflow
lies in int range, and formatSourceIntValue covers sign/width cases.
exact.cpp before: a=2147483648, a=3221225471. After: a=-2147483648,
a=-1073741825, the int values that actually overflow.
2026-09-24 20:56:27 -06:00
trvon
e158d3fdba
fix(detect): exclude container-bounded string methods from overflow sinks
std::basic_string / std::basic_string_view methods (substr/append/insert/...)
do size()-pos and pos+count arithmetic that is bounded by the container size
invariant, so an unbounded pos/length at a call site is a logic contract, not
signed-overflow UB. analyzeOverflowCallee now skips these, removing the
chromium file_path.cc substr/append FPs (6 signed findings -> 0) while
preserving the 10 genuine unsigned-wrap findings.

Adds positive tests (substr/append call sites are not flagged) and a clean
negative (free-function arithmetic is still flagged).
2026-08-20 21:54:55 -06:00
trvon
14aedf7417
fix(detect): suppress security-detector false positives
- int-overflow: unsigned wrap is defined, not UB — split to
  fold.unsigned-wrap so signed-UB findings aren't drowned; on by
  default (--report-unsigned-wrap=false opts out)
- use-after-free: model return/throw as path-terminating so
  `delete p; return;` in an error branch can't poison the fall-through
- oob-access: real sizeof for complete structs (was 1); recognize
  std::min/clamp/modulo index bounds
- memory-leak: static-storage singletons + return-to-caller are
  caller-owned, not leaks

YAMS scan: UAF 4→0, struct-OOB ~10→0, singleton-leak ~15→0,
min/modulo-bound OOB →0. 137/137 tests pass.
2026-08-16 14:29:35 -06:00
trvon
4bc62d721a
fix: scan namespaced/nested functions; timeout robustness; null-deref drift
Enumeration: replace the hand-rolled top-level `tu->decls()` walks (TU
security prefilter + every interprocedural pre-pass/cross-TU primer in
div-by-zero/int-overflow/null-deref/oob) with a shared RAV-based
`fold::detect::forEachFunctionWithBody`, so functions nested in namespaces
and classes are analyzed. Fixes 0-findings on namespaced C++ (dbench CTF).

TU prefilter: extracted to fold/cli/tu_security_prefilter; flags unsigned
-/* wraps so int-overflow candidates in size arithmetic are not skipped.

Timeout robustness: cooperative per-TU walk deadline (WalkOptions) checked
in the walk/unrollLoop/CFG-block checkpoints and the BatchSafetyObserver
flush loop, plus a non-progress unroll fixpoint — slow TUs degrade with
partial findings instead of being SIGALRM-quarantined.

OOB precheck: treat `*(p+i)` and indirect callees as candidates.

null-deref drift fix: remove the unsound `priorFunctionTextProvesNonNull`
source-text heuristic (added in 331a68467) that treated a textual `p!=0`
before a deref as proof of non-null, silently suppressing real null-derefs
(CWE-476 F1 0.485 -> 0.583, recall 0.379 -> 0.517).

Tests: test_function_enumeration, test_tu_security_prefilter, namespaced
cross-TU int-overflow regression. Full suite green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 18:04:15 -04:00
trvon
dcbbba73ff
fix: interprocedural buffer-bound pre-pass verification + test
- Verified seedInterproceduralContext() pipeline: SecurityWalker calls it
  before TraverseDecl, OOBObserver scans all call sites for ConstantArrayType
- OOB observer consumes param_buffer_sizes_ for ParmVarDecl base variables
- Test added for interprocedural buffer-bound detection
2026-05-30 00:48:07 -04:00
trvon
783d83cc45
Deduplicate null callsites and honor loop aliases 2026-05-24 20:02:53 -04:00
trvon
b3d7791aed
Skip pointer arithmetic overflow summaries 2026-05-24 19:17:07 -04:00
trvon
473dcb8a79
Avoid UI helper arithmetic summaries 2026-05-24 18:48:37 -04:00
trvon
e3cd897aa9
Suppress bounded local counter overflow FPs 2026-05-24 18:30:38 -04:00
trvon
d9477545a0
Use promoted arithmetic widths 2026-05-24 18:18:11 -04:00
trvon
331a68467c
Optimize security detectors and add quality gates 2026-05-23 20:42:05 -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
b73abea520
Optimize int-overflow: unsigned-skip, interval filter, range tracking
CWE-190 benchmark:
  Queries:   9045 -> 4385 (-52%)
  Z3 time:   164s -> 0.2s (-820x)
  Wall time: 457.8s -> 400.5s (-12.5%)
  TP:        1208 -> 1271 (+63)
2026-05-15 13:49:16 -04:00
trvon
f218af3d8b
Add githooks, clang-format all code, fix CI Z3 paths 2026-05-15 00:08:47 -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