【Rust日报】2026-09-22 Miri 缓存 target 时可能经 GitHub Actions 泄露密钥

💡 原文中文,约2100字,阅读约需5分钟。
📝

内容提要

Rust 安全团队公告:Miri 会将环境变量写入 target/ 目录,若 CI 缓存该目录且 PR 可读,密钥可能通过 PR 工作流泄露。修复方案是仅保留 CARGO_* 与 OUT_DIR 环境变量,自 nightly 2026-09-22 起生效。文章还讨论了命名参数的设计取舍、enum 适合编译器实现,以及用 Loom 复现无锁栈的 ABA 问题。

🔎

延伸解读

Miri 缓存泄露的触发条件与风险

泄露需要同时满足几个条件:CI 缓存了 target/ 目录,且 PR 工作流能读取该缓存;运行 cargo miri 的步骤能通过 step/env 或前序步骤获取密钥环境变量;攻击者曾合并过代码,从而能触发 PR CI。满足后,攻击者可从缓存中提取密钥,再推第二个 commit 覆盖痕迹,而 GitHub UI 有时会隐藏被覆盖的 commit,日志也会在数月后删除,增加了事后发现的难度。

修复进展与临时缓解措施

短期修复是让 Miri 只保留 CARGO_*(排除 CARGO_*_TOKEN)和 OUT_DIR 环境变量,该补丁自 nightly 2026-09-22 起生效,但可能尚未进入当前使用的 nightly。生态扫描发现 1 个确有问题的仓库和 7 个需谨慎的仓库,并已联系维护者。临时措施包括:对该 job 禁用缓存、把密钥限定到不调用 Miri 的 step、暂时关掉 Miri,然后清理缓存并考虑轮换可能泄露的密钥。即使不跑 Miri,也不应让能写公共缓存的 job 接触密钥。

命名参数的设计难点

Steve Klabnik 在讨论命名参数时指出,Rust 若引入该特性,需解决多个设计问题:trait 方法实现里参数名是否必须与 trait 定义一致;按定义顺序从左到右求值与调用处任意顺序命名实参如何共存,这会影响 data move 与 data.len() 等编译差异;是否与 struct 字面量统一;以及参数改名带来的兼容性。作者表示仍不确定命名参数是否适合 Rust,但比过去十年更开放,本文是一般性思考而非背书。

Loom 检测 ABA 问题的实践要点

作者 Sofia 用 Loom 按 C11 内存模型枚举合法并发交错,以复现无锁栈的 ABA 问题。具体做法是通过 RUSTFLAGS="--cfg loom" 与 shim,把 std::sync::atomic、thread、Arc、UnsafeCell 等替换为 Loom 对应实现;在 Cargo.toml 中把 loom 放在 cfg(loom) 目标依赖下,并为 unexpected_cfgs 登记自定义 cfg。还需用 Loom 的 UnsafeCell 包装裸指针访问,再对有缺陷的无锁栈跑测试,观察

Q&A

Miri 缓存 target 目录为什么会导致密钥泄露?

Miri 会把全部环境变量写入 target/ 目录,以便在多次调用 cargo miri 之间保留构建相关的环境。如果 CI 缓存了 target/,并且 PR 可以读取该缓存,那么密钥就可能被 PR 工作流读出。

针对 Miri 缓存泄露密钥的问题,官方修复方案是什么?

短期修复是让 Miri 只保留 CARGO_*(排除 CARGO_*_TOKEN)和 OUT_DIR 环境变量。该补丁从 nightly 2026-09-22 起生效,届时 Miri 将不再有此问题。

如果暂时无法升级 nightly,有哪些临时缓解措施?

临时措施包括:对该 job 禁用缓存、把密钥限定到不调用 Miri 的 step、暂时关掉 Miri,然后清理缓存并考虑轮换可能泄露的密钥。即使不跑 Miri,也不应让能写公共缓存的 job 接触密钥。

Steve Klabnik 对 Rust 命名参数的主要顾虑是什么?

主要顾虑包括:trait 方法实现里参数名是否必须与 trait 定义一致;按定义顺序从左到右求值与调用处任意顺序命名实参如何共存(涉及 data move 与 data.len() 的编译差异);是否与 struct 字面量统一;以及参数改名带来的兼容性。作者表示仍不确定命名参数是否适合 Rust,但比过去十年更开放。

为什么说 Rust 的 enum 特别适合编译器实现?

enum 可携带数据,比 C++/Python 里的 tag + 无类型列表更直接;可嵌套(如 Binary { x, y, bop: BOp });在对齐条件下可把嵌套 tag 压进更小布局(示例约 12 字节);match/守卫/match 元组组合便于写编译器 pass。作者因此能在每核每秒搜索并评估数千种 kernel 变体。

如何用 Loom 复现无锁栈的 ABA 问题?

通过 RUSTFLAGS="--cfg loom" 与 shim,把 std::sync::atomic、thread、Arc、UnsafeCell 等换成 Loom 对应实现;在 Cargo.toml 里把 loom 放在 cfg(loom) 目标依赖下,并为 unexpected_cfgs 登记自定义 cfg。还需用 Loom 的 UnsafeCell 包装裸指针访问,再对有缺陷的无锁栈跑测试,观察 Loom 能否检出 ABA。

🏷️

标签

➡️

继续阅读