RUSTSEC-2020-0159 原因浅析
今天小编给大家讲一个有关安全边界的漏洞。小编最初关注 RUSTSEC-2020-0159 的原因是因为对练手项目进行审计( cargo audit
)的时候,审计反馈 chrono 这个的日期时间处理库有脆弱性,于是追究起其发生的原因。首先,最初的问题是来自于 chrono 库发现 localtime_r
在直接使用 libc 提供的 getenv
、setenv
时可能会引起不安全性(unsound) ,而该问题在使用 std 的时候可以通过上锁来保证安全性(sound)。在这个问题底下有网友指向了 rust-lang 关于 getaddrinfo
是否需要获取 ENV 锁 的讨论,里面 alexcrichton 贴出了 Linux man page 里的描述:
env Functions marked with env as an MT-Safety issue access the environment with getenv(3) or similar, without any guards to ensure safety in the presence of concurrent modifications. We do not mark these functions as MT-Unsafe, however, because functions that modify the environment are all marked with const:env and regarded as unsafe. Being unsafe, the latter are not to be called when multiple threads are running or asynchronous signals are enabled, and so the environment can be considered effectively constant in these contexts, which makes the former safe.
被多线程安全性(MT-Safety)标记 env 标记的函数在用
getenv
或者类似函数访问环境变量会出问题,如果不使用 guard 来保证在并发修改环境时的安全性。然而我们不把这些函数标记为多线程不安全(MT-Unsafe),因为修改环境的的函数均被用 const:env 标记并且认为是不安全的。因为不安全,所有后者不会在多线程运行或异步信号启用时被调用,所以这些环境变量可以被有效认为在上下文中是常量,因此前者(getenv,小编注)是安全的。
也即,在并发场景中,只要不修改环境变量(set_env)就会不会引起读取时安全问题——因为此时环境变量相当于常量(共享不可变原则)。而实际上 并不能阻止编程师在并发场景中调用相关修改环境变量的函数,也即前文描述的安全条件总会有被破坏的时候(尤其是在嵌入式高并发场景),因此这个问题可以认为是一个不合理性。
于是,为解决相关不合理性,我们提出了 可选方案:
- 将
std::env::set_var
标记为 unsafe - 不真实地调用
setenv
- 仅在单线程代码中调用
setenv
- 废弃
std::env::set_var
然而,在漏洞修复之前,如果不想被提示相关的问题,可以 --ignore
参数来忽略:
cargo audit --ignore RUSTSEC-2020-0159
评论区
写评论还没有评论