
AI 技能AI 插件应用安全网络安全AI 评测【免费下载链接】skillsTrail of Bits Claude Code skills for security research, vulnerability detection, and audit workflows项目地址https://gitcode.com/gh_mirrors/skills8/skills点击查看免费下载导读本文深入讲解 Trail of Bits rust-review 插件中foreign-drop-finder这一安全审计范式Finding ID 前缀FOREIGNDROP当 Rust 结构体包装了由 C 语言或其他语言分配器libc::malloc、g_malloc、CoTaskMemAlloc、CUDA、语言 VM 等分配的内存却在其Drop实现中把释放动作路由到 Rust 全局分配器时就会产生分配器层面的非法释放invalid free。读完本文你将掌握该缺陷的完整触发条件、误报排除规则、可直接运行的 ripgrep 搜索模式以及让释放动作与分配动作严格配对的修复方案并能理解它在 rust-review 全量审计流水线中的调度位置与去冲突规则。缺陷本质跨分配器的 invalid free在 FFI外部函数接口场景下内存的分配方与释放方必须严格配对。foreign-drop-finder检测的核心 bug 形态是一个 Rust 结构体包装了由外国分配器分配的指针 —— 例如libc::malloc、GLib 的g_malloc、CoreFoundation 的CFAllocator、Windows 的LocalAlloc/CoTaskMemAlloc、cudaMalloc、语言 VM 的分配器PyO3 的Py、napi-rs 的JsObject、JNI或某个 C 库自有的专用分配器。它的Drop实现或通过Box/Vec自动派生的所有权逻辑却把释放动作路由到了Rust 全局分配器Box::from_raw、Vec::from_raw_parts、dealloc、mem::drop而不是与之匹配的外国释放函数。这在分配器层面构成非法释放Rust 分配器把该指针交还给了它并不拥有的堆。常见的危险释放表达式如下// 危险内存来自 libc::malloc释放却走 Rust 全局分配器 impl Drop for CBuffer { fn drop(mut self) { unsafe { let layout Layout::array::u8(self.len).unwrap(); dealloc(self.ptr, layout); // ❌ invalid free // drop(Box::from_raw(self.ptr as *mut u8)); // ❌ 同样错误 // Vec::from_raw_parts(...) 自动 Drop // ❌ 同样错误 } } }该文档还明确划定了反向边界extern C fn接收一个由 Rust 分配的BoxT并将其返回给 C的情形属于 ABI/所有权转移规则范畴不在本 finding 范围内。本 finding 只聚焦于 Rust 侧的Drop释放动作。三条验证门全部满足才算命中foreign-drop-finder采用严格的验证门Verification gates机制所有三条必须同时成立才能判定为FOREIGNDROP#验证门判定要点1结构体持有来自 FFI 的原始指针字段类型为*mut T/*const T/NonNullT且由外国分配器填充 —— 需要向上追溯构造函数或From*mut T实现寻找libc::malloc、来自外部源的CString::into_raw、CoTaskMemAlloc等来源2释放路由指向 Rust 分配器类型存在显式impl Drop for X其函数体调用Box::from_raw(self.ptr)、Vec::from_raw_parts(...)、alloc::dealloc(...)、drop(Box::from_raw(...))或通过一个错误分配器的BoxT字段隐式释放3没有与之匹配的外国释放在此之前/替代位置上没有调用外国分配器对应的free如libc::free、g_free、CFRelease、LocalFree、CoTaskMemFree、cudaFree其中第 1 条强调追踪证据不能只看字段类型还要顺着构造函数和From*mut T的实现向上查找指针到底来自哪一方这是区分真实命中与误报的关键证据链。必须拒绝的误报清单foreign-drop-finder同时给出了四类典型误报FP用于在审计时排除正确代码Rust 分配的指针走Box::from_raw释放—— 这正是正确的对称配对不是缺陷外国分配的指针其Drop调用的是外国释放函数—— 配对正确类型为#[repr(C)]且所有权已转移给 C 侧—— 本侧只是借用查看该指针PhantomDataa T根本不需要Dropjemalloc/mimalloc被配置为 Rust 全局分配器—— 此时与Box::from_raw是自洽的对称关系。这四条规则与验证门互补验证门负责确认命中FP 清单负责排除误判两者共同保证审计结果的可信度。搜索模式可落地的 rg 正则与交叉引用文档提供了四条可直接交给ripgrep执行的搜索种子用于在两阶段审计中建立候选清单\bimpl\b[^{]*?\bDrop\sfor\s\w \bBox::from_raw\b|\bVec::from_raw_parts\b|\bdealloc\s*\( \blibc::(malloc|calloc|realloc|strdup)\b CoTaskMemAlloc|LocalAlloc|GlobalAlloc[^:]|CFAllocator|g_malloc命中后需要做交叉引用Cross-reference找出构造函数从外国分配器流出且Drop流入 Rust 分配器的类型 —— 即把第一组正则Drop实现的命中和第三、四组正则外国分配器的命中按类型进行双向关联只有两侧同时命中同一类型才进入验证门判定。值得注意的是在 rust-review 插件的 ffi-cross-language 集群提示 中FOREIGNDROP的 Phase A 阶段还有更宽的种子包括extern C/CString::/#[repr(C)]/bindgen等用于构建整个 FFI 安全域的候选库存而 Phase B 阶段才按顺序逐类执行各 finderFOREIGNDROP排在第 5 位。这两层种子在仓库里是分工明确的集群种子负责圈定 FFI 安全域finder 种子负责命中具体 bug 类。在 rust-review 流水线中的调度与去冲突从 集群 manifest 可以看到foreign-drop前缀FOREIGNDROP注册在ffi-cross-language集群下该集群的触发门是has_ffi能力标志同时它被声明为**非整合non-consolidated**集群意味着超过单 worker 负载上限时会被拆分成多个 chunk 并行执行。根据 SKILL.md 的编排流程has_ffi标志由以下探测正则决定非空输出即置真一旦置真整个 ffi-cross-language 集群才会被build_run_plan.py纳入计划grep -rlE extern\s(C|system|stdcall|...)|\bextern\sfn\b|extern\s\{|#\[repr\((C|transparent)\b|\b(CString|CStr)\b|use\s(libc|core::ffi|std::ffi|std::os::raw|cty)|\blibc::|\b(bindgen|cbindgen)\b|\bc_void\b --include*.rs .审计产生的每条 finding 以FOREIGNDROP-NNN.md的形式带 YAML frontmatter写入输出目录之后由去重法官合并重复项、由误报/严重度法官给出fp_verdict、severity与attack_vector最终汇入REPORT.md与REPORT.sarif。FOREIGNDROP与同集群内外的相邻 bug 类存在明确的**去冲突Deconfliction**边界审计时不可互相混报相邻 bug 类前缀与 FOREIGNDROP 的区分opaque-pointerOPAQUEPTR处理的是句柄的身份/有效性混淆而不透明句柄的Drop释放了外国拥有的内存应报FOREIGNDROPcstring-danglingCSTRDANGLERust 拥有的CStr生命周期过早结束对应外国侧释放了 Rust 仍引用的缓冲区时归FOREIGNDROPinvalid-freeINVFREE纯 Rust 内部的*ptr new_val对未初始化内存触发 Drop见 invalid-free-finder不含跨语言分配器错配double-freeDFREE同一 Rust 堆内存被ptr::read复制出双所有权见 double-free-finder不涉及外国分配器修复方案让释放与分配严格配对文档给出的修复策略有两类均围绕释放动作必须匹配分配来源这一核心原则方案一把 Rust 释放换成外国分配器的匹配释放函数。将dealloc/Box::from_raw替换为libc::free、g_free、CoTaskMemFree等对应函数并在// SAFETY:注释中记录分配器配对关系struct CBuffer { ptr: *mut u8, len: usize, } impl Drop for CBuffer { fn drop(mut self) { unsafe { // SAFETY: ptr 由 libc::malloc 分配必须且只能用 libc::free 释放 libc::free(self.ptr.cast()); } } }方案二在指针旁存储一个释放函数指针。当同一包装类型需要兼容多种分配来源时可以在结构体里存一个unsafe fn drop_fn(*mut T)在Drop中调用它把分配器配对的决策集中到构造处struct ForeignBuf { ptr: *mut u8, len: usize, drop_fn: unsafe fn(*mut u8), // 构造时按分配来源注入匹配的释放函数 } impl Drop for ForeignBuf { fn drop(mut self) { // SAFETY: drop_fn 与分配器配对见构造点注释 unsafe { (self.drop_fn)(self.ptr) }; } }两种方案的共同硬性要求是在// SAFETY:注释中显式记录分配器配对关系让后续维护者无需重新推断所有权来源。防御性设计在类型系统中封死错配结合相邻 finder 与 FFI 最佳实践可以在审计之外从设计层面消灭这类缺陷用 newtype 包装原始指针将*mut T封装为NonNullT的新类型让Drop的释放行为成为类型契约的一部分而不是散落的unsafe代码利用OptionNonNullTtake()在显式close/free包装器中consume self使释放后的句柄在编译期不可再被使用把 use-after-free 变成编译错误这正是 opaque-pointer-finder 推荐的句柄生命周期建模正确处理所有权转移 APIC 侧若提供_take_ownership语义Rust 侧应使用CString::into_raw等显式转移原语而不是在Drop里对不拥有的指针做隐式释放必要时用ManuallyDrop/mem::forget当所有权被刻意转移或双重释放风险存在时显式中和某一路Drop避免运行两次析构。延伸阅读核心范式文档plugins/rust-review/prompts/general/foreign-drop-finder.md集群组织与去冲突规则plugins/rust-review/prompts/clusters/ffi-cross-language.md 、插件集群清单 manifest.json插件编排流程与has_ffi探测plugins/rust-review/skills/rust-review/SKILL.md 、插件 README相邻 bug 类 finderopaque-pointer-finder.md 、cstring-dangling-finder.md 、invalid-free-finder.md 、double-free-finder.md在包含unsafe、FFI 或 C 绑定代码的 Rust 仓库上执行/rust-review:rust-review审计时FOREIGNDROP是 ffi-cross-language 集群中必查的 bug 类之一 —— 记住它的判定口诀看来源谁分配的、看释放走哪个堆、看配对有没有匹配的 free三者齐备即可上报。赞分享AI 技能AI 插件应用安全网络安全AI 评测【免费下载链接】skillsTrail of Bits Claude Code skills for security research, vulnerability detection, and audit workflows项目地址https://gitcode.com/gh_mirrors/skills8/skills点击查看免费下载相关推荐Rust内存安全模型Easy Rust解释所有权系统的核心原理Rust内存安全模型Easy Rust解释所有权系统的核心原理 Rust作为一种新兴编程语言以C/C的性能和控制能力与Python等现代语言的内存安全著文档教程ffsend内存安全保障Rust所有权系统应用ffsend内存安全保障Rust所有权系统应用 在命令行文件共享工具领域内存安全始终是用户最关心的核心问题之一。ffsend作为Firefox Send的全开发工具Next AI Draw.io 快速上手指南用自然语言 3 分钟生成专业图表Next AI Draw.io 快速上手指南用自然语言 3 分钟生成专业图表 开会时突然被要求把系统架构画出来你打开白板工具翻了半天还画不出来NextAI 应用大模型前端后端MCP 服务上一篇跨平台直播聚合工具Dart Simple Live完整使用指南下一篇MinIO Java SDK与Spring Boot集成教程构建企业级对象存储服务创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考