< 返回版块

huangjj27 发表于 2021-11-13 00:01

Tags:新闻,日报,

RUSTSEC-2020-0159 原因浅析

今天小编给大家讲一个有关安全边界的漏洞。小编最初关注 RUSTSEC-2020-0159 的原因是因为对练手项目进行审计( cargo audit )的时候,审计反馈 chrono 这个的日期时间处理库有脆弱性,于是追究起其发生的原因。首先,最初的问题是来自于 chrono 库发现 localtime_r 在直接使用 libc 提供的 getenvsetenv时可能会引起不安全性(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)就会不会引起读取时安全问题——因为此时环境变量相当于常量(共享不可变原则)。而实际上 并不能阻止编程师在并发场景中调用相关修改环境变量的函数,也即前文描述的安全条件总会有被破坏的时候(尤其是在嵌入式高并发场景),因此这个问题可以认为是一个不合理性。

于是,为解决相关不合理性,我们提出了 可选方案

  1. std::env::set_var 标记为 unsafe
  2. 不真实地调用 setenv
  3. 仅在单线程代码中调用 setenv
  4. 废弃 std::env::set_var

然而,在漏洞修复之前,如果不想被提示相关的问题,可以 --ignore参数来忽略:

cargo audit --ignore RUSTSEC-2020-0159

评论区

写评论

还没有评论

1 共 0 条评论, 1 页