LWN:内核unsafe Rust使用标准!

关注了就能看到更多这么棒的文章哦~

Standards for use of unsafe Rust in the kernel

By Daroc Alden
August 14, 2024
Gemini-1.5-flash translation
https://lwn.net/Articles/982868/

Rust 被设计来帮助程序员编写更安全的代码。但是,编译器并非无所不知的,编写与硬件交互(或在 Rust 生命周期范式之外使用内存)的 Rust 代码,需要程序员在某个时刻保证某些操作是可以进行的。Benno Lossin 建议增加一些文档到 Rust-for-Linux 项目 中,澄清了在内核代码中使用 unsafe 的注释标准。人们普遍认为这些标准是必要的,但对于何时使用 unsafe 是合理的,仍然存在分歧。

Lossin 提出的文档首先描述了 Rust 中 unsafe 关键字的目的:明确地标识代码何时依赖于编译器无法检查的保证。由于编写不安全代码的程序员依赖于编译器无法帮助检查的属性,因此确保这些属性得到记录尤为重要:包括属性本身以及它们为何成立。

Lossin 指出,关于程序安全性的这两种不同类型的信息实际上对应于 Rust 中 unsafe 关键字的两种微妙的用法。有时 unsafe 用于表示程序员知道他们正在使用编译器无法保证安全的操作,有时它用于告知编译器它无法完全理解何时调用新定义的函数是安全的。每种使用方式都有不同的内容应该记录;前者应该解释为什么该操作在这种情况下是安全的,而后者应该解释安全使用该函数的条件。

然而,补丁集中给出的示例有些不太够。Alice Ryhl 提出要求文档展示如何正确执行:

我认为值得明确指出,安全注释必须解释为什么满足先决条件,而不是先决条件是什么。将两者混淆是一个非常常见的错误,并且可能更有意义的是包含两个展示差异的示例。

Lossin 同意了这一点,并指出如果他的建议的文档标准被其他内核开发人员接受,他计划遍历代码树,尝试改进一些现有的安全注释,这应该会提供一些关于如何做或不应该做的良好示例。

这些补丁强调了为 Rust 项目编写安全文档的几个重要方面,例如安全性和健壮性之间的区别。在 Rust 中,安全代码有一些特定的保证。只要程序使用的所有不安全代码都是“健壮的”,它就不会访问未初始化的内存、发生数据竞争、修改不可变常量,或参与 Rust 中的任何其他 被认为未定义的行为。当不安全代码不使用任何安全抽象(例如,未标记为 unsafe 的函数调用)传递的任何值组合会导致不安全代码进行未定义行为时,则认为不安全代码是健壮的。

Lossin 的文档指出:“Rust 中的未定义行为比 C 或 C++ 中的含义要严格得多:Rust 中的 UB 是完全禁止的。”为了真正依赖 Rust 的安全保证,所有不安全代码都必须是健壮的,而不仅仅是依赖于编译器当前行为不会出现问题。Boqun Feng 担心这种要求将如何与 Linux 内核内存模型(LKMM)交互:

基本上,由于 LKMM 依赖于 C 标准没有规定的几个方面,例如,某些类型上的易失性访问是原子的,汇编块的行为、依赖关系。更不用说我们还有 data_race(),例如,诊断代码在核心同步设计之外访问共享变量。

最终,Feng 说,最好是让 Rust 了解 Linux 内核依赖的一些特殊行为。但现在,这根本不可行,他继续说道,有时开发人员需要自由地超越 Rust 的约束。Lossin 不同意,他说内核中的 Rust 代码是一个从头开始的机会,不需要依赖任何编译器特定的行为。他确实建议,可能可以合理地讨论针对具体情况的例外,但“‘有时 UB 实际上是可以的’是我不希望在 Rust 中作为一般性声明来接受的。”

Daniel Almeida 赞成添加额外的文档,但他认为仅仅是文档还不够,建议该项目应该使用 linter 来确保在适当的位置有注释。Miguel Ojeda 指出,Clippy 已经支持这种检查,因此可以轻松地添加到内核的构建中。一封 稍后的邮件表示 Ojeda 已从其他开发人员那里获得了共识,并将发布一个补丁集来做到这一点。

Almeida 还对 Lossin 文档中的一部分表达了担忧,该部分敦促开发人员集中使用 unsafe 代码块,以便更容易地推理其行为。 “当然,让我们努力将尽可能多的不安全代码段推到内核 crate 中。但是,在我看来,我们不应该将 Rust 驱动程序视为一些无特权的实体,它们毕竟也是内核代码。”

Ryhl 不同意 Almeida 的解释,她说 Lossin 的文档没有 Almeida 描述的那么严格。Danilo Krummrich 也认为 Lossin 的建议没有真正的问题,因为 Rust 使得构建抽象成为可能,这些抽象可以涵盖驱动程序中 unsafe 的最明显用例。然而,每个人都同意,这将可能成为即将到来的 Rust-for-Linux 会议 Kangrejos 上的一个很好的讨论话题。

无论如何,在这一文档更改被接受之前还有很多工作要做。Lossin 已经表示,他计划在文档不清楚的地方纳入一些建议,以及添加更多示例,并使现有代码符合文档中设置的标准。然而,所有这些任务都可能比让 Rust-for-Linux 开发人员就非安全代码的具体标准达成一致更容易,这肯定需要进一步讨论。

全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。

欢迎分享、转载及基于现有协议再创作~

长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~

e5f37cadfef5b5f541054c7b265e4881.jpeg

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值