这是对 官方安全公告 的交叉发布。官方帖子还包含使用我们的 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,他发现了此错误并根据我们的 安全策略 向我们报告了此错误。