Fil-C:垃圾输入,内存安全输出 [视频]

Fil-C 是一种在运行时强制内存安全的 C 实现,正在被评估为 Rust 主要依赖编译时安全模型的替代或补充。评论者争论 Fil-C 的保证能延伸到多远——尤其是在系统调用、数据竞争和 `mmap` 方面——以及 Rust 和其他语言(Go、C#、TypeScript、Python)通过安全封装、运行时和工具已经提供了什么。许多人认为 Fil-C 的主要价值在于用较少改动加固大型既有 C/C++ 代码库,同时也质疑它的性能开销、对新项目的适用性,以及那种有时把它宣传得“比 Rust 更安全”的表述方式。

Fil-C 与 Rust:安全模型

  • Fil-C 和 Rust 被描述为两种不同的方法:Rust 强调在编译时防止未定义行为;Fil-C 强调让未定义行为在运行时变得不可能。
  • 有人认为 Rust 虽然“偏向”静态检查,但仍然依赖运行时检查(边界检查、调试版中的溢出检查、RefCell 等),因此“它能在静态层面阻止 所有 未定义行为”的说法受到质疑。
  • 一些评论指出,这两种方法是互补的:可以在 Rust 的 unsafe 代码外层再包一层 Fil-C 风格的运行时检查,从而实现“纵深防御”的安全性。

系统调用、mmap 与运行时架构

  • Fil-C 的“user libc”会调用 Fil-C 运行时,后者过滤系统调用,再交给更底层的 libc。其主张是:Fil-C 程序在系统调用层面仍然保持内存安全,而且系统调用无法绕过这些保护(/proc 之类的技巧除外)。
  • 一个关键例子是 mmap:Fil-C 提供了一个包含许多 mmap 能力的 API,同时保证内存安全;Rust 的安全子集无法提供等价保证,而使用 mmap 通常是 unsafe 的。
  • 批评者回应说,Rust 也可以有安全的系统调用封装,而且这两种系统最终都依赖某种 unsafe 层。

Unsafe 代码与信任边界

  • 在 Rust 中,unsafe 代码可能出现在用户代码和依赖中;信任边界由用户控制(并且可以通过 forbid(unsafe_code) 和工具进一步收紧)。
  • 在 Fil-C 中,普通程序没有 unsafe 块;所有不安全行为都被限制在编译器/运行时中。有人认为这种集中化严格更安全;也有人认为这只是把同样的风险转移了位置。

数据竞争与安全边界

  • Fil-C 被描述为即使在数据竞争下也能保持内存安全;批评者则认为,在某些竞态场景中安全属性会退化(例如通过竞态指针访问另一个对象)。
  • 评论者强调,内核和硬件 bug、/proc 技巧、ptrace、process_vm_writev 以及类似机制,仍然不在任何用户态内存安全保证的范围内。

性能、用例与比较

  • Fil-C 会带来运行时开销(有评论粗略形容为“慢 2 倍、内存 4 倍”),因此不适合某些场景(例如内核、部分嵌入式环境)。
  • 许多人认为它的主要价值在于以最小改动加固大型既有 C/C++ 代码库;也有人认为它在部分用户态场景中足够快,可用于生产。
  • 对于绿地开发,怀疑者质疑为什么要选择 Fil-C,而不是已经提供内存安全且生态更成熟的 GC 语言(Go、C#、TypeScript、Python)。

社区与修辞

  • 多条评论指出,Fil-C 讨论中反复出现“我们 vs. 他们”的表述,尤其是相对于 Rust,并对被夸大或绝对化的说法表示担忧(例如关于数据竞争安全性的表述)。
  • 也有人认为,细致、甚至带有对抗性的比较有助于澄清权衡并增进共同理解。