这是官方安全公告的交叉发布。 官方帖子也包含使用我们的 PGP 密钥签名的版本。
此漏洞的 CVE 是 CVE-2019-12083。
Rust 团队最近收到通知,标准库中 `Error::type_id` 的手动实现及其与 `Error::downcast` 系列函数的交互存在安全漏洞。 如果您的代码没有手动实现 `Error::type_id`,则您的代码不受影响。
概述
标准库中的 `Error::type_id` 函数在 2019-04-11 发布的 1.34.0 版本中被稳定化。 此函数允许获取底层错误类型的具体 `TypeId`,以便向下转换为原始类型。 此函数在标准库中有一个默认实现,但也可以被下游 crate 重写。 例如,以下内容目前在 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-04-11 发布的 Rust 1.34.0 中被稳定化。 2019-04-25 发布的 Rust 1.34.1 版本也受到影响。 自 Rust 1.0.0 以来的所有 Rust 版本中都存在 `Error::type_id` 函数(不稳定),这意味着使用 nightly 编译的代码可能在任何时候都受到影响。
缓解措施
立即缓解此错误需要删除 `Error::type_id` 的手动实现,而是继承默认实现,从安全的角度来看,默认实现是正确的。 `Error::type_id` 的目的不是为其他类型返回 `TypeId` 实例。
对于长期缓解,我们将取消稳定此函数。 不幸的是,对于调用 `Error::type_id` 和覆盖 `Error::type_id` 的用户来说,这是一个破坏性更改。 对于覆盖的用户来说,这很可能是不安全的,但调用 `Error::type_id` 的用户自上一个 1.34.0 版本以来仅在稳定版上使用了几周,因此认为影响不会太大而无法克服。
我们将在 2019-05-14(明天)发布 1.34.2 点版本,该版本会还原 #58048 并取消 `Error::type_id` 函数的稳定化。 即将发布的 1.35.0 版本以及 beta/nightly 渠道也将全部更新为取消稳定化。
`Error::type_id` API 的最终命运尚未决定,它是 #60784 的主题。 目前没有计划采取超出取消稳定化的行动,因此 nightly 代码可能会继续出现此问题。 我们希望尽快在标准库中完全解决此问题。
事件时间线
- 2019 年 5 月 9 日,星期四,下午 2:07 - 错误报告给 security@rust-lang.org
- 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,他发现了此错误并按照我们的安全政策向我们报告了此错误。