Commit d381541
committed
feat(assail): structural FFI safe-wrapper detector + Rule 13 suppression
Motivating case: 007-lang's `crates/oo7-core/src/zig_bridge.rs` — the
safe Rust wrapper around liboo7c's C ABI. Pre-change, the file
surfaced as 2 active High `UnsafeCode` findings ("8 unsafe blocks" +
"Raw pointer cast"), blocking 007's TRG-D panic-attack zero-gate even
though every block is a documented `extern "C"` boundary with a
per-line SAFETY invariant.
Changes:
1. `is_rust_ffi_safe_wrapper` (analyzer.rs): new structural detector
that returns true when ALL four criteria hold —
(1) file declares `unsafe extern "C" {` / `extern "C" {` /
`extern "C" fn`, verified on the code-only view so
string-literal mentions do not qualify;
(2) file uses FFI idioms (CStr / CString / c_char /
std::os::raw / std::ffi / from_raw_parts);
(3) every `unsafe {` block has a `// SAFETY:` comment in the
preceding three lines (standard clippy
`undocumented_unsafe_blocks` convention);
(4) file contains no `mem::transmute` (those have their own
JIT-context classification — see audit-ffi-unsafe.md §2).
2. `FileStatistics.ffi_safe_wrapper` (types.rs): new serde-defaulted
bool field plumbing the detector result into the report. Set
during per-file analysis for Rust files; `extract_context_facts`
reads it and asserts `context(path, "ffi_safe_wrapper")`.
3. Rule 13 `suppress_ffi_safe_wrapper` (kanren/core.rs): scoped to
`UnsafeCode` category so that PanicPath / InsecureProtocol /
CommandInjection findings in the same file remain visible (they
are orthogonal to the FFI-boundary cost). Confidence 0.92 —
higher than Rule 12's JIT 0.88 — reflecting four-criterion
structural agreement.
4. `apply_suppression` (assail/mod.rs): remove the `break` after the
first matching weak point. Kanren facts are deduped by (name,
args), so `suppressed(UnsafeCode, zig_bridge.rs)` represents
"every UnsafeCode finding on that file is a FP," not "one
arbitrary one." The previous behaviour required the double-call
pattern in analyze() to flip multi-finding-per-tuple cases; now
one pass suffices. No regressions in the 200-test suite.
5. Tests: 8 new unit tests covering positive zig_bridge shape plus
each rejection counter-case (no-extern-C / no-FFI-idioms /
undocumented-unsafe / transmute-present / extern-C-only-in-
string-literal / mixed-case SAFETY / unsafe-fn-excluded-from-
tally). 4 new kanren integration tests covering context-fact
assertion, end-to-end Rule 13 suppression on both
zig_bridge-shape findings, and category scoping (PanicPath
survives).
End-to-end result on 007-lang: active findings drop from 2 to 1
(the remaining one is flake.nix SupplyChain, unchanged). The 2
zig_bridge.rs UnsafeCode findings now auto-suppress via the
structural pass, matching the treatment that jit_compiler.rs
already gets. See 007-lang/audits/audit-ffi-unsafe.md §1 for the
motivating classification.1 parent d024a9e commit d381541
6 files changed
Lines changed: 646 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
860 | 860 | | |
861 | 861 | | |
862 | 862 | | |
| 863 | + | |
863 | 864 | | |
864 | 865 | | |
865 | 866 | | |
| |||
0 commit comments