拜登:“一切非 Rust 项目均为非法”

编译 | 核子可乐、褚杏娟

“程序员编写代码并非没有后果,他们的⼯作⽅式于国家利益而言至关重要。”白宫国家网络总监办公室(ONCD,以下简称网总办)在本周一发布的报告中说道。在该报告中,拜登政府希望软件开发人员尽量使用 Rust 这样的内存安全编程语言,并放弃 C 和 C++ 等安全性薄弱的语言。另外,参议院还强调会努力为内存安全立法。

图源:报告文件

科技巨头要为安全负责

这并不是拜登政府对内存安全语言的首次提倡。

美国网络安全与基础设施安全局(CISA)在去年 9 月的一篇博文中,也曾公开敦促开发人员使用内存安全编程语言。网络与基础设施安全局、联邦调查局(FBI)、国家安全局及各盟国机构随后于 12 月发布了题为《内存安全路线图案例》(The Case for Memory Safe Roadmaps)的研究报告,其中就点名 C/C++ 存在内存安全漏洞,软件开发商应放弃使用,改用 C#、Rust、Go、Java、Python 和 Swift 等内存安全的编程语言 (MSL)。

此外,早在 2022 年 11 月,国安局网络安全信息表就将 C#、Go、Java、Ruby、Swift 以及 Rust 列为认定的内存安全编程语言。

在这份 19 页的最新报告中,白宫则将 C 和 C++ 作为存在内存安全漏洞的两大编程语言示例,相应的内存安全正面典型则是 Rust 语言。

微软和谷歌最近的研究发现,约有 70% 的安全漏洞由内存安全问题引发。国家网络总监 Harry Coker 在白宫新闻稿中表示,“我们美国有能力、也有责任缩小网络空间的攻击面,并防止各类安全漏洞侵入数字生态系统。而这要求我们首先解决转向内存安全编程这一根本难题。”

白宫在一份新闻稿明确提出,科技企业可通过采用内存安全编程语言“防止各类漏洞侵入数字生态系统”。内存安全编程语言能够免受与内存访问相关的各类软件 bug 及漏洞的影响,具体包括缓冲区溢出、越界读取和内存泄漏。

白宫新闻稿提到,这份报告的目标之一是将网络安全责任从个人和小型企业,转移到大型组织、科技巨头及美国政府身上,因为后者“更有能力应对不断变化的威胁形势”。

网总办称其与科技企业、学术界及其他组织等私营部门合作制定了报告中的建议条款。网总办自去年 8 月起就该主题发出了公众意见征集请求,随后收集到多家科技企业的支持回应,包括 HPE、埃森哲和 Palantir。其他软件安全专家也对报告内容表示赞赏。

有人欢喜有人愁

网总办公室还公布了报告筹备过程中征集到的意见:

  • Rust 基金会呼吁“公共资助组织及其承包商应默认使用内存安全编程语言(例如 Rust),并将此作为良好实践要求”。

  • 微软将重点放在软件供应链以及行业对开源项目投入不足的现实问题上。

  • IBM 表示,重写软件可能过于昂贵,并主张“保护现有软件免受内存安全漏洞影响”的方法。

  • 谷歌提到其正与政府机构一道倡导“向内存安全语言和框架的过渡”。

  • 亚马逊云科技则给出更为详尽的回应,称“完全支持用内存安全语言编写新项目的做法”,但这“只是提高开源软件安全性整体努力中的一项具体因素”,并强调开发人员有可能禁用掉 Rust 中的内存安全功能;此外,逻辑错误造成的“安全威胁可能远大于内存安全”。

另一组织也给出引人注目的回应,该组织自称“拥有多位在 ISO C++ (ISO/IEC SC22/WG21) 领域拥有数十年经验的 C++ 高级成员,主要负责指导 ISO C++ 发展方向”。

他们提到“内存安全只是整体安全保护中的一小部分”,而且“C++ 的安全实践主要得益于正式规范、充分指定的内存模型以及活跃的用户与实现者社区。相比之下,某些理论上更安全的语言反而缺少正式规范”,这部分针对的很可能就是 Rust。

在他们看来,C++ 显然是受到了不公平的对待。“对 C++ 的大部分批评主要集中在以传统风格甚至 C 语言编写的代码,这部分代码没有用到旨在提高类型与资源安全性的现代功能。”

他们还在回应中强调,还有很多其他方式会导致编程错误,包括逻辑错误、资源泄露、并发错误、类型错误、计时错误、终止错误等等。该小组希望改善对 C++ 程序员的教育和指导,“从根本上解决安全问题”。还有部分 C++ 语言专家认为,内存保护机制只能解决少部分安全难题。

而华盛顿大学计算机科学教授 Dan Grossman 表示,网总办的报告及时且具有指导意见。他认为尽管“几十年来,C 和 C++ 的安全风险已经众所周知”,但考虑到实用且成熟的替代方案终于出现,现在正是白宫推动内存安全普及的最佳时机。

与此同时,他认为“恶意攻击者利用内存安全违规实施威胁的手段非常复杂”,因此变革已刻不容缓。

在 Grossman 看来,涵盖政府、行业及学术界的内存安全相关讨论能够带来有意义的转变。“当然,联邦政府的诸多部门都是重要的软件开发者与提供者,他们可以基于自身立场为后续系统调整或全新系统的开发划定优先级。”

Rust 不会立刻取代 C 和 C++

然而,替代 C 和 C++ 绝不可能一蹴而就,特别是在嵌入式系统领域。

根据 Statista 公布的数据,截至 2023 年,约有 22% 的软件程序员仍在使用 C++,其中 19% 使用 C 语言,总体人气已经不及 JavaScript、Python、Java 等其他流行语言。但 TIOBE 编程社区指数榜则仅将 Python 列为流行度领先语言,紧随其后的分别是 C、C++ 和 Java。

Grossman 指出,“好消息是系统软件中其他语言、特别是 Rust 的应用已经显著增长,我发现人们普遍认为这种演变将进一步加速。而 C 和 C++ 开发的份额只会逐步降低,而非一夜之间遭到弃用,其巨大的业界整体影响力仍然存在。”

互联网安全研究小组执行董事兼联合创始人 Josh Aas 则补充称,放弃 C 和 C++ 将是一个“漫长且艰难的过程。改变人们思考事物的方式离不开持续努力,而现在这样的沟通有助于巩固安全问题在人们思维中的存在感和重要性。”

在 Aas 看来,要想推动这一变革,政府与私营部门间必须协同努力,将安全编码视为优先事项。

他总结道,“最终,我们必然要编写并部署新代码。但实现这个目标离不开资源的加持,我们必须保证从政府到私营部门的各级领导者,都将此视为高优先级工作。相关负责人应当意识到这个问题,并保证他们在解决问题的过程中能得到有力支持。”

那从技术角度看,用 Rust 重写大型 C/C++ 系统组件后就绝对安全了吗?答案是否定的。

本质上讲,Rust 和 C/C++ 是不能直接交互的——它们在类型、内存管理和控制流方面都采取了截然不同的方法。结果就是,如果手动编写“胶水”代码,就很可能打破隐式假设(例如调用约定和数据表示)、关键不变量(例如内存和类型安全、同步和资源处理协议),并跨过语言边界引入未定义的行为错误,例如展开恐慌(unwinding panics)、整型表示错误、为枚举和标记的联合体类型静默创建无效值等。

内存管理方法方面,Rust 的类型系统会静态跟踪对象的生命周期和所有权,C 语言要求程序员手动管理内存,而 C++ 虽然提供内存安全抽象,但也允许自由将其与原始指针加以混合。

更重要的是,在将 C/C++ 系统迁移至 Rust 时,开发者必须通过 FFI 层来协调这些差异,其困难程度可见一斑。例如,跨 FFI 边界共享指针会引发跨语言内存管理问题,其中一种语言分配的指针会被另一种语言所释放。而当 C 和 Rust 代码试图共享内存所有权时,情况将变得更为复杂。

与此同时,Rust 代码往往高度依赖类型系统所保证的不变量,借此确保内存安全和代码正确性。由于 C/C++ 程序通常不遵循相同的不变量,因此 C/C++ 在与 Rust 代码交互时可能引发冲突,这类问题在重写后尤其多见。

Rust 和 C 间的不匹配,往往导致 FFI 边界处出现大量不安全代码——这令开发者很难安全将组件移植为 Rust 形式。更要命的是,哪怕是精通 Rust 和 Modula 3 系统架构的开发者,也几乎无法回避这些麻烦。

另外,报告里也承认,“在某些特殊情况下,可能无法正常使用内存安全语言”。以太空系统为例,垃圾收集语言就无法满足其健壮性要求。报告还提到,Rust 虽具有必要的内存安全特性,但“尚未在太空系统中得到证实。”

值得注意的是,C++ 之父 Bjarne Stroustrup 在去年底参加“CppCon”C++ 会议时向观众承诺,他将首先明确该编程语言所需的安全措施的具体类型。

Stroustrup 给出的解决方案是配置文件(指的是需要遵循的一组规则,可以实现特定的安全保证),它们由 ISO C++ 标准定义,解决常见的安全问题,例如指针和数组范围。Stroustrup 的总体策略是,使用静态分析来消除潜在错误,但全局静态分析无法承受,所以需要一些规则来简化正在编写的内容,以便有效且廉价地进行本地静态分析,然后提供一些库来更好地依赖这些规则。

与此同时,虽然被公认为“安全语言”,但 Rust 在 2023 年除了提升性能和做规范化,也在努力进行安全性补齐短板。比如 Rust 通过支持更多安全编译场景如异步 trait 方法、优化编译告警等,优化了用户体验,使用户得以更好地获取 Rust 安全性的优点。

结束语

除了编程语言,网总办也谈到硬件保护层面,例如将 Arm 芯片中的内存标记功能,或者 SRI Internatioanl 与剑桥大学的 CHERI(功能硬件增强 RISC 指令)研究项目作为潜在解决方案。

但对于软件的量化问题,这份报告提出的问题明显多于答案。“软件可量化性是最难解决的开放研究问题之一。”具体挑战包括:大部分软件缺乏统一结构,导致质量评估变得既主观又严重依赖上下文。此外,软件行为往往具有不确定性,软件的自身演进则意味着评估结论会快速过时。报告因此将软件可量化性确立为“研究重点”。

本文文字及图片出自 InfoQ

你也许感兴趣的:

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注