标准库安全公告

2019 年 5 月 13 日 · Rust 核心团队

这是对 官方安全公告 的交叉发布。官方帖子还包含使用我们的 PGP 密钥签名的版本。

此漏洞的 CVE 为 CVE-2019-12083


Rust 团队最近被告知了一个影响标准库中 Error::type_id 的手动实现及其与 Error::downcast 函数族交互的安全漏洞。如果您的代码没有手动实现 Error::type_id,则您的代码不受影响。

概述

标准库中的 Error::type_id 函数在 2019 年 4 月 11 日的 1.34.0 版本中被稳定化。此函数允许获取底层错误类型的具体 TypeId,以便向下转换为原始类型。此函数在标准库中有一个默认实现,但也可以被下游箱子覆盖。例如,以下代码目前在 Rust 1.34.0 和 Rust 1.34.1 上是允许的

struct MyType;

impl Error for MyType {
    fn type_id(&self) -> TypeId {
        // Enable safe casting to `String` by accident.
        TypeId::of::<String>()
    }
}

当与 Error::downcast* 函数族结合使用时,这可以实现将类型安全地转换为错误类型,从而导致安全问题,例如越界读/写等。

在 1.34.0 版本之前,此函数不稳定,不能在稳定的 Rust 中实现或调用。

受影响的版本

Error::type_id 函数首次在 2019 年 4 月 11 日发布的 Rust 1.34.0 中被稳定化。2019 年 4 月 25 日发布的 Rust 1.34.1 版本也受到影响。Error::type_id 函数自 1.0.0 版本以来一直存在于所有 Rust 版本中,但处于不稳定状态,这意味着使用 nightly 编译的代码可能在任何时候都受到影响。

缓解措施

立即缓解此错误需要删除 Error::type_id 的手动实现,而是继承默认实现,该实现从安全角度来看是正确的。Error::type_id 不应该返回其他类型的 TypeId 实例。

为了长期缓解,我们将使此函数不稳定。这对于调用 Error::type_id 的用户和覆盖 Error::type_id 的用户来说是一个破坏性更改。对于覆盖它的用户来说,这可能是内存不安全的,但调用 Error::type_id 的用户只能够在 1.34.0 版本发布后的几周内在稳定版本上进行操作,因此认为克服影响不会太大。

我们将在 2019 年 5 月 14 日(明天)发布 1.34.2 版本,该版本将恢复 #58048 并使 Error::type_id 函数不稳定。即将发布的 1.35.0 版本以及 beta/nightly 通道也将更新为不稳定版本。

Error::type_id API 的最终命运尚未确定,是 #60784 的主题。目前没有计划采取超出不稳定的行动,因此 nightly 代码可能会继续出现此问题。我们希望很快在标准库中完全解决这个问题。

事件时间线

  • 2019 年 5 月 9 日星期四下午 2:07 - 错误报告给 [email protected]
  • 2019 年 5 月 9 日星期四下午 3:10 - Alex 回复,确认错误
  • 2019 年 5 月 10 日星期五 - 缓解计划制定并实施
  • 2019 年 5 月 13 日星期一 - PR 发布到 GitHub 的 stable/beta/master 分支
  • 2019 年 5 月 13 日星期一 - 安全列表被告知此问题
  • (计划) 2019 年 5 月 14 日星期二 - Rust 1.34.2 发布,其中包含此问题的修复程序

致谢

感谢 Sean McArthur,他发现了此错误并根据我们的 安全策略 向我们报告了此错误。