主要观点:Materialize 近期在 Rust 的 crossbeam
及标准库的无界通道中发现并发 bug,会导致双释放和未定义行为,此问题存在一年多未被发现,Rust 1.87.0 已包含修复,文中详述调试过程、竞争条件及内部不变量等。
关键信息:
- 2 月 26 日 CI 间歇性失败,错误为内存损坏,用 AddressSanitizer 发现问题与 2 月 7 日更新的
crossbeam-channel
有关。 - 分析无界通道结构,初始化时通道为半初始化状态,这是重现竞争条件的关键。
- 竞争条件分析得出特定条件下会出现双释放,如线程调度顺序等。
- 影响评估确定受影响的
crossbeam
和 Rust std 通道版本。 - 快速准备 PR 修复问题,两个社区反应迅速,Tor 社区发布安全咨询。
重要细节: crossbeam
提供多种通道类型,无界通道内部由链表实现,通过Sender<T>
和Receiver<T>
操作。disconnect_receivers
函数在最后接收者丢弃时调用,Channel::drop
函数在最后引用丢弃时执行类似逻辑。- 代码中部分修改导致引入双释放问题,如 2023 年 4 月和 2024 年 2 月的 PR 变更。
- 修复后
crossbeam
快速发布新版本并从 crates.io 移除受影响版本,Rust 侧也合并修复并提名回溯到 1.87.0 版本。 - 强调即使在 Rust 中,
unsafe
代码和宽松原子操作仍可能导致错误,需重视 CI、诊断工具和对抗性压力测试等。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。