在Rust借用检查器中发现11年历史的健全性缺陷
11 year old unsoundness bugs found in Rust borrow checker

原始链接: https://github.com/rust-lang/rust/issues/164250

```rust ## 概述 这段 Rust 代码展示了一个编译器未能捕获的**栈内存超范围使用(stack-use-after-scope)**缺陷,该缺陷会导致未定义行为。 代码定义了一个结构体 `Q`,其 `Drop` 实现会将内部的值移动到全局向量 `KEPT` 中(以 `Box` 类型存储)。在 `main` 函数中,创建了一个 `String` 类型的变量 `l`,并将引用 `&l` 传给了 `Q`。当 `q` 被丢弃时,该引用会被装箱并存入 `KEPT`。然而,`l` 本身会在其所在作用域结束时被丢弃,导致 `KEPT` 持有一个悬垂指针。 随后,一个新的字符串 `z` 被分配,并复用了相同的栈内存。当 `KEPT[0]` 被向下转型为 `&'static String` 并打印时,输出的却是 `z` 的内容(`"XXXX..."`),而非原始的 `l` ——这是一个典型的释放后使用(use-after-free)问题。 **预期结果:**编译器应拒绝编译此代码,因为将 `&l` 存储为 `&'static` 类型是不安全的。 **实际结果:**该程序在稳定版(≥1.85.0)及 nightly 版本上均可编译通过,并静默地产生错误输出。在 AddressSanitizer 下,程序会因 `stack-use-after-scope` 错误而崩溃,从而确认了内存安全违规。 ```

一个 HN 帖子讨论了一个新提交的、已存在 11 年的 Rust 借用检查器健全性缺陷(rust-lang GitHub issue)。一个最小安全 Rust 示例可以把非 'static 引用赋入受 'static 约束的泛型类型;自定义 Drop 实现随后可以在被引用对象释放后观察/使用它,导致释放后使用/未定义行为。评论者强调这是 rustc/借用检查器的实现缺陷,不一定是生命周期规则的缺陷,应通过拒绝该代码来修复;Ferrocene 使用相同代码,因此很可能受影响。争论涵盖 Rust 的安全承诺:一些人指出 Rust 从未声称经过形式验证,编译器/类型系统的健全性缺陷确实存在,而且它仍比 C/C++ 更安全;在 C/C++ 中,此类 UB 是程序员的责任。其他人批评 Rust 的炒作和虚假的安全感。讨论还提到形式验证、AI 辅助的缺陷发现,以及真实 crate 是否会因此损坏。总体而言:这是一个严重但可修复的编译器缺陷,凸显了 Rust 安全保证的局限,并未否定 Rust 在实践中的
相关文章

原文

In the following code:

use std::sync::Mutex;
static KEPT: Mutex<Vec<Box<dyn std::any::Any + Send>>> = Mutex::new(Vec::new());
struct Q<T: 'static + Send>(Option<T>);
impl<T: 'static + Send> Drop for Q<T> {
    fn drop(&mut self) { if let Some(t) = self.0.take() { KEPT.lock().unwrap().push(Box::new(t)); } }
}
fn main() {
    {
        let l = String::from("hello world, this is long enough");
        let mut q = Q(None);
        q.0 = Some(&l);
    }
    let _z = String::from("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
    let k = KEPT.lock().unwrap();
    println!("{}", k[0].downcast_ref::<&'static String>().unwrap());
}

I expected to see this happen: program is not accepted

Instead, this happened: program compiles and prints XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. With asan, the program will crash with a AddressSanitizer: stack-use-after-scope

Meta

Issue on current nightly, and stables at least down to 1.85.0

Godbolt with asan: https://rust.godbolt.org/z/83MvfbKde
Godbolt without asan: https://rust.godbolt.org/z/GsGdqqMWe

联系我们 contact @ memedata.com