Fil-C: Garbage In, Memory Safety Out

Lobsters Hottest 工具

摘要

Fil-C 是一个完全内存安全的 C/C++ 实现,通过 LLVM IR 阶段的不可见能力(invisicaps)将指针值与边界信息捆绑,实现高兼容性,性能损失约 4 倍。

<p><a href="https://lobste.rs/s/badu44/fil_c_garbage_memory_safety_out">Comments</a></p>
查看原文
查看缓存全文

缓存时间: 2026/07/24 04:59

### TL;DR Fil-C 是一个完全内存安全的 C/C++ 实现,它通过不可见能力(invisicaps)将指针值与边界信息捆绑,并在 LLVM IR 阶段拦截指针操作,使得编译后的程序即使存在越界或释放后使用错误,也不会让攻击者控制整个内存。性能中位数约慢 4 倍,对 SQLite 约慢 6 倍,但兼容性极高,约一半 C/C++ 软件包可直接编译运行。 ## 什么是内存安全? 定义一个内存安全的编程语言:内存逻辑错误不会让攻击者控制整个内存。在非内存安全语言(如传统的 C/C++,演讲者称为“YOLO C”)中,攻击者可以利用数组越界访问、类型混淆等手段,将任意地址写入指针,从而访问或篡改任意内存位置。即使现代操作系统部署了 ASLR、NX bit、CFI、指针认证等缓解措施,攻击者仍能通过 ROP 链或覆盖关键数据(如命令缓冲区)绕过这些防护,甚至利用“怪异执行”将程序的指令序列拼接成任意操作。因此,核心目标是防止攻击者获得“不受限制的内存访问能力”,而是让越界访问仅访问错误索引,释放后使用仅导致程序崩溃。 ## 先前工作的不足 从 90 年代起,人们尝试让 C 语言内存安全,但大多数方案未成功: - **Safe C**:不支持完整的 C 语言、不支持 C++、不支持线程。 - **Sanitizers**:本身不提供内存安全(只检查访问已释放区域,但不阻止访问存活对象)。 - **MTE/PA**:概率性防御,攻击者约有 1/5 的概率绕过。 - **CHERI**:依赖特殊硬件,无法购买,且通用硬件性能长期领先。 ## Fil-C 的设计目标与范围 演讲者从管理角度对问题做了范围界定,放弃了不必要的目标: - **不追求二进制兼容性**:不能与未用 Fil-C 编译的对象混合链接。 - **初期不追求速度**:第一个版本慢了 200 倍,现在中位数约慢 4 倍,SQLite 约慢 6 倍,Blake 3 上甚至比 Rust 更快(得益于更好的 SIMD 支持)。 - **核心目标**:内存安全 + 高度兼容(约一半软件包零修改)。 ## 关键诀窍:利用 LLVM IR 的规整性 + 不可见能力 演讲者发现,在 Clang 刚生成 LLVM IR 但尚未经过优化时,指针值的使用方式非常规整: - 程序员在源码中声明为指针或引用类型的字段,在 LLVM IR 中对应 `ptr` 类型;非指针字段对应整数等其他类型。 - 因此,可以在 LLVM IR 阶段识别所有指针操作,并为每个指针植入**不可见能力(invisicaps)**。 不可见能力的工作原理: - 每个指针在数据流中表示为两个部分: - `int val`:指针的整数值(用户可见可操作)。 - 下界(lower bound):用户不可见,随指针流动,存储在局部数据流(寄存器)中。 - 通过下界可以找到能力头(capability header),其中包含上界(upper bound)和辅助字(ox word)。 - 任何分配产生的能力,其下界和上界永远不能包围“红色”标记的区域,因此用户无法修改边界。 - 当指针被存储到内存中时,辅助字会指向一个辅助分配,其中保存该内存中每个指针的下界。 这样,所有指针操作都携带边界信息,且边界信息不可篡改,实现了内存安全。 ## 编译器和运行时 Fil-C 基于 Clang/LLVM 修改,在 LLVM IR 阶段植入 invisicaps。运行时负责管理能力头、辅助分配等。演讲者承诺演示一个实际运行的例子(转录中未展开),但强调对于日常使用性能足够。 ## 总结 Fil-C 是一个个人项目,目前仅支持 Linux x86-64,但兼容性极高,性能损失可接受,是通往内存安全 C/C++ 的一个实用的垫脚石技术。 **Source**: https://www.youtube.com/watch?v=5F-2Y1LPRek

相似文章

InvisiCaps:Fil-C 能力模型

Lobsters Hottest

描述了 Fil-C 的 InvisiCaps 能力模型,该模型通过跟踪指针权限来确保 C 和 C++ 的内存安全,同时追求极致的兼容性和合理的性能。

内存安全的内联汇编

Hacker News Top

Fil-C 引入了内存安全的内联汇编,确保程序员错误导致 panic 或 trap,而不是错误编译。

Fil-C 优化调用约定

Hacker News Top

Fil-C 优化调用约定确保 C 程序即使在恶意滥用情况下也能保持内存安全性,同时通过在常见情况下省略安全检查来保持效率。它解释了通过 panic 或定义明确的行为来处理类型违规的通用优化和寄存器传递优化。