前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Rust生态安全漏洞总结系列 Part 4 | 请用 time 代替 chrono

Rust生态安全漏洞总结系列 Part 4 | 请用 time 代替 chrono

作者头像
张汉东
发布2021-11-10 15:59:14
1.1K0
发布2021-11-10 15:59:14
举报
文章被收录于专栏:Rust 编程Rust 编程Rust 编程

本系列主要是分析`RustSecurity` 安全数据库库[1]中记录的Rust生态社区中发现的安全问题,从中总结一些教训,学习Rust安全编程的经验。

本期主要是侧重于 ` Chrono`[2] 里面的一个情况比较复杂的漏洞分析。

TL;DR : 请使用 time 代替 Chrono


问题

本月在 Reddit Rust 频道有人发布了一个帖子,在询问Chrono 库是否还有人在维护。之所以问出这个问题,是该贴作者看到 Rust 安全依赖报告中显式 Chrono 有一个安全问题两年了还没有被修复,所以他不知道是怎么回事。

Chrono 遇到的安全问题在 rustsec.org : RUSTSEC-2020-0159[3] 有描述, 大概内容是:

  1. Chrono 调用 libclocaltime_r,用于将时间转换为本地时间。
  2. libc 实现库中大多数都是直接调用 getenv
  3. setenvgetenvlibc 中都不是线程安全的
  4. 为了确保 setenv 的健全性,Rust 的 libstd 为其添加了一个锁
  5. 这意味着在非 libstd下使用 getenv 将是不健全的。

这里面也涉及 Rust 中 std::env 的相关安全问题。目前当你在并发环境下使用 setenv会存在数据竞争的问题,建议使用 互斥锁来处理,但只能防止 std::env建议不要使用 `std::env::set_var`[4]。对此问题更详细的总结参见 [同步 FFI 访问 POSIX 环境变量函数[5]](https://internals.rust-lang.org/t/synchronized-ffi-access-to-posix-environment-variable-functions/15475)

但是,直接调用 libcsetenvgetenv 是线程不安全的。

发现这个漏洞的是 `tokio-rs/io-uring`[6] 作者 quininer。

解决方案:使用 time

Chrono 的作者现身回复:

  1. 出于个人原因,目前已经离开了该项目,但该项目目前有人维护。
  2. 这个安全漏洞目前有一些限制,所以无法修复。
    1. Chrono 必须支持系统本地时区(Local::now())等。
    2. 该系统本地时区必须与 C 的 localtime* 返回的内容相匹配。

避免该漏洞有一个解决办法就是用 time 0.3 代替 chrono

最近几天 chrono 也发布了一个公告:no time for chrono[7] ,主要内容是:

  1. chrono 用户可以切换到 time 0.3
  2. localtime_r 相当复杂,处理时区被认为是所有开发者的噩梦。
  3. time 0.3 通过移除对 localtime_r 的调用来缓解此问题。
  4. Rich Felkermusl的作者)有另一种观点。他认为,问题不在于调用 localtime_r函数,而在于修改环境。环境应该是不可改变的。

Time 的 0.3 版本添加了许多 API[8],它们涵盖了 Chrono 的诸多 API:

  • 无分配模式
  • Month类型
  • 日历/序数/ISO/儒略转换
  • 大日期(超过 +/- 9999 年)
  • 解析和 serde 支持

还有一些功能仅由较新的Time 支持, Chrono 则没有:

  • const 函数
  • datetime!在编译时构造日期时间的宏
  • 序列化non-ISO8601 表示
  • 随机日期/时间
  • 快速检查[9]支持

因此,您现在可以合理地将 Chrono 替换为 Time

相关链接

https://www.reddit.com/r/rust/comments/qamgyh/is_the_chrono_crate_unmaintained/

https://rustsec.org/advisories/RUSTSEC-2020-0159.html

https://github.com/chronotope/chrono/issues/499

https://passcod.name/technical/no-time-for-chrono.html

参考资料

[1]

RustSecurity 安全数据库库: https://rustsec.org/advisories/

[2]

Chrono: https://github.com/chronotope/chrono

[3]

rustsec.org : RUSTSEC-2020-0159: https://rustsec.org/advisories/RUSTSEC-2020-0159.html

[4]

建议不要使用 std::env::set_var: https://github.com/rust-lang/rust/issues/90308

[5]

[同步 FFI 访问 POSIX 环境变量函数: https://internals.rust-lang.org/t/synchronized-ffi-access-to-posix-environment-variable-functions/15475

[6]

tokio-rs/io-uring: https://github.com/tokio-rs/io-uring

[7]

no time for chrono: https://passcod.name/technical/no-time-for-chrono.html

[8]

Time 的 0.3 版本添加了许多 API: https://github.com/time-rs/time/blob/main/CHANGELOG.md#030-2021-07-30

[9]

快速检查: https://docs.rs/quickcheck

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-11-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 觉学社 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题
  • 解决方案:使用 time
  • 相关链接
    • 参考资料
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档