Canonical 测试表明 AI 工具能将遗留 C 代码自动转换为安全可维护的 Rust,且编译通过无错误,引发安全边界讨论。
Canonical想知道,自动化工具能否在不改写软件的前提下,用安全、可维护的 Rust 重写遗留 C 代码。为此,布里斯托大学的研究人员将工具拉出来考验——测试对象是 AppArmor 和 snap-confine。
AppArmor 用于限制应用程序的访问行为(依据预设策略),snap-confine 则负责创建 snaps 运行所需的沙箱环境。两者都承担着安全关键职责,Canonical 并不急于将其中任何一个改写为 Rust,但想搞清楚:维护者在信任一段生产代码的自动化翻译之前,需要看到怎样的证据。
大规模行为等效性证明
Canonical 提出的系统先用语言模型生成 Rust 代码,再经过一轮验证流程——旨在捕获并修复行为差异。这是一个认知转变:大规模生成代码已经不是难题,难的是证明这些代码真的在做原来那件事。
生成的 Rust 代码可以编译通过,却仍然和原始 C 代码行为不同。研究人员计划将模糊测试与形式化程序分析相结合,对比两个实现的差异,找出常规测试可能遗漏的问题。
当系统检测到不匹配时,它使用符号修复来诊断具体失败原因并直接修复代码。这种反馈对于解决 unsafe 滥用问题至关重要。
Rust 的 unsafe 代码块允许安全 Rust 不允许的操作,包括某些形式的原始指针操作。翻译工具可以用它来承载难以转换的 C 语法,但如果过度依赖 unsafe,原本内存安全风险中的许多也会被带入新代码。
真正困难的目标是:让 Rust 代码既安全到足以交付这门语言的收益,又在行为上足够接近原始 C——让维护者可以信任它。
安全工具提升了翻译的 stakes
AppArmor 是一个有用的测试案例,因为翻译中的错误可能带来安全后果。
这个 Linux 安全模块依据定义的策略限制应用程序的访问权限。其周围的用户空间工具——用 C、Python 和 C++ 混合编写——必须正确解析、编译和加载这些策略。一段 Rust 重写如果对策略的解释与现有实现不同,可能完美编译却仍然出错。正如关注 AI 辅助开发的人都知道的那样,通过所有测试的代码仍然可能以无人预料的方式出问题。
snap-confine 带来了一个相关挑战,因为它负责建立 snaps 使用的执行环境和隔离机制。将 C 改写为 Rust 可以消除整类漏洞,包括 use-after-free 漏洞和缓冲区溢出,但自动化翻译仍可能引入逻辑错误。布里斯托团队还必须证明焦点(focus ion)行为与原始 C 一致。
Unsafe Rust 使目的落空
获得 Rust 的全部收益往往不仅仅是一行一行地翻译 C 语法。写出惯用的 Rust 可能需要跨多个函数甚至整个模块修改数据结构和生命周期。自动化翻译工具可以通过依赖 unsafe 来保持与原始 C 的接近,但这些风险也会将同样的 bug 带入 Rust 代码。
这就是 Canonical 资助布里斯托团队的原因——他们要找到答案:这种方法能否扩展到包含数十万行 C 代码的整个代码库。
信任,而非代码,才是瓶颈
过去数十年构建的操作系统、库和基础设施仍然用 C 编写,其中许多软件仍在活跃维护和部署。手工重写需要巨大的工程工作量,并且可能引入回归。但大规模生成代码已经是解决了的问题;真正的瓶颈是开发者的信任。Canonical 与布里斯托的合作正是要攻克这个实际障碍——证明生成的 Rust 既内存安全,又在功能上与它设计用来替代的数十年旧 C 代码完全一致。