Skip to content

Commit d381541

Browse files
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

File tree

src/a2ml/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -860,6 +860,7 @@ mod tests {
860860
allocation_sites: 0,
861861
io_operations: 0,
862862
threading_constructs: 0,
863+
ffi_safe_wrapper: false,
863864
}],
864865
recommended_attacks: vec![AttackAxis::Concurrency],
865866
dependency_graph: DependencyGraph::default(),

0 commit comments

Comments
 (0)