在荷兰乌得勒支(Utrecht, Netherlands)举行的全球最大 Rust 语言大会上(Rust Week),Linux 稳定版内核维护者 Greg Kroah-Hartman 开场便表示:“我今天要谈的是不可信数据和 Linux,以及 Rust 将如何拯救我们。” 在内核安全邮件列表里连续处理了一两个月安全问题之后,他更坚定了这一说法:“我要发表一个更大胆的声明:‘将要拯救 Linux 的是你们这些开发者。’抱歉,这件事全靠你们了。”
拯救?Linux 需要被拯救吗?
他所指的是,随着新一代 AI 漏洞检测程序的出现,大量严重的 Linux 安全漏洞突然被发现,例如 Dirty Frag、Copy Fail 和 Fragnesia 等漏洞。
因此,自 2005 年以来“见过每一个内核安全漏洞”的 Kroah-Hartman 表示,内核团队如今平均每天都要发布“大约 13 个 CVE(Common Vulnerabilities and Exposures, 通用漏洞披露),或者类似这样一个疯狂的数字”。他认为,Rust 是少数几种现实可行的方法之一,能够大幅减少由 C 语言传统错误处理和资源管理陷阱导致的漏洞。
Kroah-Hartman 用内核真实 C 语言漏洞说明了这些问题,其中包括一个存在 15 年的蓝牙漏洞——代码在未检查指针是否有效的情况下直接解引用;以及一个 Xen 漏洞——“我们在错误处理路径里忘记解锁了”。他解释说:“内核中大多数漏洞其实都是这种微小的问题:错误条件没有检查,锁没有正确处理,内存没有释放……漏洞随着时间不断积累,它们会导致内核崩溃。这就是我们在 C 语言中长期面对的现实,这也是为什么我们不喜欢它。”
Kroah-Hartman 认为,Rust “最美妙的地方”在于,它能够在构建阶段而不是代码审查阶段捕获这些错误。以锁机制为例,他特别提到内核中的 Rust 锁抽象:“只有获取锁之后,你才能访问结构体内部的指针,而锁的释放是自动完成的。编译器会处理这一切,访问受到保护,锁会自动生效,一切都很顺利。你根本无法在不获取锁的情况下编写访问这些值的代码……编译器不允许你这么做。”
他认为,这些特性能够直接消除他所见到的大量漏洞:“这将帮我们解决两类问题。首先,内核中 60% 的漏洞会直接消失。” 更重要的是,这意味着更早、更自动化的约束机制:“如果这些问题发生在构建阶段,而不是审查阶段,就不用我这个维护者去阅读你的代码,然后说:‘哦,你真的检查了那个错误返回值吗?哦,你真的在正确位置获取锁了吗?’ Rust 免费为我们提供了这些保障。这简直是最棒的事情。”
即使 Rust 明天就从世界上消失,Kroah-Hartman 也认为,它已经迫使 Linux 内核清理了大量 C 代码和接口设计。他毫不掩饰地将这些改进归功于 Rust:“我们从 Rust 那里‘偷’来了这些思想。谢谢你们。这是个好主意。即便 Rust 明天消失了,我们也已经借鉴了它的理念,大幅清理了内核中的 C 代码。感谢你们,仅仅因为 Rust 的存在,Linux 就已经变得更好了。”
他介绍了受 Rust 启发而引入的 C 语言“守卫(guard)”和作用域锁(scoped lock)机制:“现在我们拥有了这些东西——C 语言作用域锁和分配器。我们新增了这些代码,使犯错变得更困难,更重要的是,它让编码变得更简单。”
他表示,Linux 社区拥有超过 5000 名开发者,却只有大约 700 名维护者,因此代码审查时间是最稀缺的资源。正因如此,那些能够让正确性一目了然的模式至关重要:“我们的目标是让代码更容易审查……如果我能更轻松地审查你的代码,我只需要扫一眼就能说:‘你显然写对了,因为你使用了这种模式。很好,漏洞也会更少。’”
Rust 绑定层(bindings)也正在迫使 C 语言一侧进行更深层次的变革。回忆早期一次 Rust-for-Linux 大会时,他说道,当看到“为了处理两行 C 代码,却写了数百行 Rust 代码”时,他意识到:“我可以修改 C 代码。我们完全可以修改 C 代码,让 Rust 代码变得更简单。我们没有理由不同时调整这道边界两侧的实现。”
如今,他认为 Rust-for-Linux 团队已经重塑了驱动程序接口:“驱动涉及的规则、trait 和接口设计,以及它们与内核 C 代码的交互方式,将使驱动程序更容易编写,也更难写错……他们做得非常、非常出色。”
除了语言特性之外,Kroah-Hartman 还将 Rust 与更广泛的“不可信数据”理念联系起来,即:“所有输入都是邪恶的(all input is evil)。”
借用微软安全团队多年前的一句名言,他告诉与会者:“如果你从我的演讲中什么都记不住,只记住这四个词就够了。这句话来自微软安全团队很多年前的经验:所有输入都是邪恶的。你必须验证所有输入。”
他介绍了一个正在进行中的设计:Rust 中的“untrusted(不可信)”类型包装器以及 validate 方法。这种机制要求数据在从“不可信”转变为“可信”时必须进行显式验证。
“我们有一个叫 untrusted 的类型包装器,可以把它附加到数据上。每次你真正想访问这些数据时——它本质上只是一个类型,而不是具体代码——它会向编译器发出提示:在访问之前,你必须先完成验证。”
他表示,这对代码审查者最大的好处在于,所有关注点都会集中到信任边界的转换位置:“整个验证过程都集中在一个地方。你可以在代码的某个区域看到所有负责把用户空间中的不可信数据转换为可信数据的验证逻辑。”
这种模型甚至延伸到了越来越不可信的硬件层面:“在我们的模型和内核设计中,我们甚至不信任硬件。硬件本来就充满漏洞,而现在还可能存在恶意硬件,这种情况越来越多。”
他的目标是将此类数据标记为“不可信”,并通过类型系统一路跟踪流转过程,从而把审查精力集中到关键位置:“这才是真正能拯救我们的东西,因为我们不信任数据……我准备说一句并不严谨的话:这将成为拯救 Linux 的关键。把这些机制与不可信数据模型结合起来,我认为能够消除现有 80% 的 CVE。这是一个极其巨大的数字。”
Rust 不是魔法
当然,这并不意味着 Rust 具有魔法,它不是包治百病的万能药。他举了一个最早被合并进 Linux 内核的 Rust 例子:当内核崩溃时用于显示二维码的逻辑。
“那段逻辑是用 Rust 写的。众所周知,它后来出现了一个内存漏洞。它接收一个缓冲区和大小,但从未检查缓冲区长度……结果写来写去就把内存写坏了,因为 Rust 会像 C 一样可怕地崩溃。”
所以Rust不是银弹。
他也不鼓励别人把现有 Linux 内核代码重写成 Rust。有听众提问:“你真的鼓励大家把内核里已有的代码改写成 Rust 吗?”
Greg 回答:“不,我们不想要重写。除非你就是那个文件的维护者和负责人,否则只为新功能使用 Rust。现有的 C 代码不要动,我们应该在此基础上继续演进。”
他以 Android IPC 系统 Binder 为例:目前 C 版和 Rust 版暂时共存,以便达到功能对等;之后,“他们会删除 C 代码,因为我信任他们,而且他们同时是两套实现的拥有者和维护者。”
随着时间推移,他预计新硬件支持将越来越偏向 Rust。
“Rust 将会在内核中不断发展。有些子系统已经表明:‘开发新的图形驱动应该用 Rust 编写。’……我们到达了一个关键节点:你能够使用 Rust 为各种不同类型的 Linux 子系统编写非常优秀的驱动程序。我认为未来一两年内你们就会看到这一趋势。”
按照 Kroah-Hartman 一贯的风格,他把这一过程总结为进化论模式:
“Linux 是进化,不是智能设计。随着时间不断演进,新的硬件会带来新的驱动,你会开始使用这些新硬件,旧驱动逐渐无人使用。最终,大约经过 20 年左右,我们就会把它们删除。”
与此同时,Kroah-Hartman 告诉听众:
“如今 Linux 有 3600 万行 C 代码,以及 11.3 万行 Rust 代码,大多数 Rust 代码都是绑定层。”
由于驱动程序占了内核大部分代码量,“顶尖 Rust Android 开发者Alice Ryhl以及Rust-for-Linux开发团队,不得不为各种内核接口编写绑定,仅仅为了能够用 Rust 写出一个小驱动程序。”
这也迫使社区放宽了一项长期规则——不允许合并未被使用的代码。
“我们不喜欢向内核中加入没有被使用的代码,如果没有实际用户存在,添加绑定会非常困难……这有点像先有鸡还是先有蛋的问题。我们不得不稍微放宽这条规则。”
他还提到了即将到来的真实部署案例:
“搭载 Binder 全套 Rust 实现的 Android 手机很快就会上市。所以,很快就有数十亿台设备运行 Rust 代码。”
最终说服包括他自己在内的许多核心维护者接受 Rust 的关键原因,是它“让代码审查变得更容易”。
在 CI(Continuous Integration, 持续集成) 机器人负责构建检查、Rust 类型系统负责保证关键不变量的情况下,维护者终于能够把注意力集中在业务逻辑本身、而不是资源管理细节上:
“我只需要关注那个函数本身。我不再担心其他东西,因为我假设它们已经正确工作了——因为它们已经通过了正确的构建和验证。”
最后他透露,Linux 核心维护者实际已经就 Rust 的地位达成了共识:
“Linux 内核维护者每年都聚在一起讨论开发流程。去年我们正式宣布:Rust 实验结束了,它不再是实验,而是真实可用的。”
原因很简单:
“推动这件事的人是真正可靠的人,我们信任他们,我们知道他们在做什么。他们已经通过实际行动证明,Rust 可以成为内核中的一种可行语言。我们会确保这件事持续下去。全速前进吧。”
随后,他带着一贯的幽默补充道:
“当然,一如既往——征服世界的计划仍在继续。”
参考
https://www.zdnet.com/article/rust-will-save-linux-from-ai-says-greg-kroah-hartman/