审计 Bun 的 Rust 移植:在 13,000 个 unsafe 块中航行

在高性能运行时从一种系统语言迁移到另一种系统语言时,往往并非轻而易举的任务。Bun 最初使用 Zig 编写,正在进行向 Rust 的移植——在发布了一份全面但有争议的代码库审计后,这一举动最近受到审视。

在 Rust 移植正式发布之前,Bun 团队进行了一次预发布审查,以量化和分类 unsafe 块的使用情况。结果令人震惊:当前的移植包含 13,365 个 unsafe 块。虽然数量很高,但审计旨在为在代码真正面向生产用户之前减少这部分技术债务提供路线图。

拆解 13,365 个 unsafe 块

Rust 代码库中大量的 unsafe 块常常让开发者警铃大作,因为 unsafe 是编译器安全保证被暂停的地方。然而,Bun 的审计认为,这些块中的大多数并非固有缺陷,而是移植过程的产物。

根本原因

根据审计,约三分之二的 unsafe 位置来源于三个主要来源:

  1. Zig 移植: 许多所有权惯用法和模式直接从原始 Zig 实现中迁移而来。
  2. FFI 边界: 为了与 C/C++ 库和外部引擎交互,需要使用 unsafe 块。
  3. 性能: 大约 3% 的 unsafe 块是有意使用的,以挤出最大性能。

通往安全的路径

Bun 的目标并非消除所有 unsafe 代码——对于与底层系统 API 交互的运行时来说,这几乎是不可能的——而是尽量减少。审计将这些块分为两大类结果:

  • 可替换(约 9,300 处): 这些块可以转换为安全的 Rust 代码。审计指出像 raw *mut Self 状态机和 &self&mut 的强制转换等模式是主要的移除目标。
  • 永久(约 4,000 处): 这些块将保持 unsafe,但计划将它们包装在安全抽象中,以确保安全的 Rust 代码无法触发未定义行为(UB)。

正确性 vs. 数量

审计的一个最关键发现是发现了五个根本 不安全 的函数。这些情况是指未定义行为可以从安全的 Rust 代码触发——这些实际的 bug 与 13,365 个 unsafe 块本身无关。审计的首要任务是先修复这些正确性漏洞,再处理 unsafe 块的总体数量。

社区反应:“AI 产物” 与技术怀疑

尽管有详细的拆解,公告在 Hacker News 上仍遭到开发者社区的强烈抵制。大量批评集中在审计页面本身标注为 “AI 生成”,导致人们指责该移植可能是 AI 驱动的翻译产物,而非手工工程。

批评者对如此大规模清理工作所需的移植可信度表示怀疑。正如一位评论者所说:

这个移植是 AI 产物,遍布 13k 个 unsafe 块。而这篇博客更是 AI 产物,声称提供一个‘计划’来减少这个数字。

其他开发者质疑一次性整体移植复杂系统的明智性,建议采用逐块迁移——将各个组件迁移到生产并单独测试——会是更稳妥的策略。

结论

Bun 的 Rust 移植是一次大规模的语言迁移实验。通过公开 unsafe 块的数量并提供公开审计,Bun 正在尝试展示对 Rust 安全保证的承诺。然而,高 unsafe 数量与“安全”实现之间的差距仍然很大,社区的反应表明,在移植过程中产生的技术债务可能是需要克服的重大障碍。

Sources