本文主要是介绍LWN: 该如何改善CVE漏洞管理流程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
What to do about CVE numbers
By Jonathan Corbet
Kernel Recipes
CVE是Common Vulnerability and Exposure的简称。CVE 编号已经沿用了很多年,每一个都代表了一个独立的软件漏洞。近年来越来越多人认识到CVE编号有一些问题,并且有越来越多的漏洞甚至都没来得及分配CVE编号。在2019年Kernel Recipes集会上,Greg Kroah-Hartman有一个40分钟的介绍,涵盖了CVE编号的局限以及如何改进,希望抛砖引玉能带来更多观点。
CVE编号是一串字符串,每当大家讨论到某个CVE编号的时候,大家都能明确知道它代表了是哪一个具体的issue。在CVE编号诞生之前,大家讨论问题时没有对issue命名,所以难以高效跟踪。尤其是很常见的在自己的系统里面用到的一个库文件里面有漏洞的情况。就像zlib,绝大多数系统里面都带有zlib,过去十五年里有很多安全问题暴露出来,有CVE编号之后大家就能清晰了解和讨论了。
CVE编号是独一无二的,因此必须要有个人来做统一分配。目前大概有110个组织能够分配CVE编号,有些是公司,有些是国家,不过kernel社区内并没有人做这个工作。除了编号分配意外,肯定还需要有一个统一的数据库来存储相关信息,这个数据库就是NVD(National Vulnerability Database)了。NVD数据库里可以查找漏洞,并且每个漏洞都有一个评分。数据库虽然有更新,不过更新很慢。并且虽然名为National的,其实只是美国而已。中国还维护着一个CNNVD,内容更多,响应得更频繁,不过缺点是加入漏洞后一般不会再更新。
CVE problems
CVE编号有很多问题,Kroah-Hartman没来得及介绍完他ppt里列出的各种问题。首先,数据库本身不完整,有很多漏洞没有录入,甚至是被由于某些原因拒绝被录入。哪怕某个漏洞已经被分配了CVE编号,也会需要很长时间完成流程,等到NVD更新的话那就更久远了。
有一个影响很大的问题,就是这个系统是由美国政府运营的。通常大家并不完全信任政府,其他国家的政府机构也越来越不新人美国政府了。不巧这个系统是由国土安全局(Department of Homeland Security)自助的,而且一直很缺资金。大家总是希望这么重要的系统一定要确保不能有信息泄露,不过由政府管理的系统通常都会面临各种压力。此前在参议院对Meltdown and Spectre进行听证的时候,议员责怪NVD的代表,为什么参议院没有提前得到这个漏洞的通知。这就是一个政府施压影响的例子。Kroah-Hartman本人信任运营NVD的MITRE,不过这些希望能提早看到漏洞细节的政府代表看起来令人不放心。
还有个问题是现实情况的复杂性。对于Spectre version 1漏洞,有一个CVE-2017-5753编号代表了,不过对应的已经有超过100个patch在试图解决这个问题,目前还有更多patch在路上。CVE编号目前并不能用来找到相关的patch,因此人们需要更多精力查找对比才能确认自己的系统里是否已经关闭了这个漏洞。他认为用一个简单的编号是没法处理好这么复杂的工作的。
CVE编号也经常被安全开发者滥用来充实自己的简历。因此,很多不正确的东西也被提交上来分配了CVE编号,而要经过很麻烦的流程才能把这些无效的漏洞编号收回。例如5月27日公开的CVE-2019-12379,描述了console驱动里的一个可能的内存泄露,而Kroah-Hartman认为这个根本无法导致安全风险。甚至最后查下来这根本不算是一个内存泄露。尽管这样,NVD在收到这个报告的时候也马上给了一个"medium"的评级。后来这个报告引起了争议,人们发现所谓的"fix"才真正引入了一个内存泄露问题。在6月4日,Ben Hutchings把所谓的fix patch回退掉了。
大家可能以为此时这个故事该结束了,可是这个CVE编号直到7月份才被标为“disputed”(有争议)。像Fedora这一类的发行版提供商有严格的流程,要求他们发布的软件需要包含所有CVE漏洞的fix,因此Fedora那段时间发布的版本里就带着这个引入问题的fix patch。要把这一切都清理干净需要更长时间了。最后这个问题本身被处理干净了,不过类似的问题每个月甚至每周都会出现。
并且,CVE编号还有时候被工程师滥用来跳过一些内部的流程,从而要求他们公司发布软件更新的时候包含某个patch。简单来说,拿到一个CVE编号的话,就能强制把某个patch给放进企业发行版的内核里。在2006到2018年之间,有1005个kernel CVE编号被新分配了。其中有414个(占比40%)的"fix date"都是个负数(意味着patch创建时间早于EVB编号申请时间),平均来说这些patch在申请CVE编号之前100天就创建好了。其中有不少虽然都是有价值的bug fix,不过如果没有CVE编号的话,企业发行版里不会选择把它们放进去。他认为,这恰恰表明CVE编号并不重要,因为根本没有包含任何有价值信息。
Bug fixes
内核社区目前平均每天会提取22个bug fix到stable tree之上,差不多占mainline kernel每天数量的5%,其实应该再多拿一些。平均每周有一到两个stable-kernel发布版本。每个stable kernel发布版本都经过测试,并且是免费发布。kernel开发者平均每周都会修复一个安全问题,还会有其他很多bug在fix时还是没有被作为安全问题来处理的。所有这些fix的处理方式都是一致的,按照bug来管理。
他提到一个TTY fix,直到3年之后大家才意识到这个fix修复了一个严重的安全风险。原始的代码和fix都是他写的,在那之前他其实一直没有意识到这个代码里有安全问题。企业发行版kernel的用户有3年的时间都暴露在这个漏洞的影响之下,但是运行stable kernel的用户没有这个问题。只有很少数的kernel安全问题的fix是拿到了CVE编号,也就是说任何人只要是只取带有CVE信息的bug fix的话,他的系统肯定是不安全的。哪怕有CVE编号的fix,也可能后来又有了新的fix,但是没有记录在文档里。
他审查过很多手机的Linux内核。其中一台很流行的手机在运行4.14.85版本kernel,在官方kernel代码之上额外增加了三百万行代码。如果比一下5月份的时候最新的4.14.108 stable版本,就会发现这台手机缺少1759个patch。手机供应商从4.14.85的kernel之后back port了36个patch,不过还缺少12个CVE问题的fix,也缺少kernel tree里面的很多严重bug fix。因此,这台手机可以在远程攻击中导致crash,甚至数据泄露。
他说,Google安全团队有一个巨型工具来在网络上搜寻安全报告。2018年,每个报出来的问题的fix都已经在Google发现这个问题之前合入了long-term stable kernel。所有的例外,都是在mainline kernel里没有的那些代码中。也就是说根本不需要cherry-pick任何patch。每个使用最新版long-term stable kernel的用户都已经拥有了对已知问题的抵抗力。因此,目前Google已经开始要求Android平台供应商都要使用long-term stable kernel。他特别指出Sony和Essential都在使用最新版本kernel方面做的非常好。Pixel设备则有些落后,不过基本还跟得上。
据他说,现在Android手机上已经有25亿个Linux在运行。这是Linux的一个主流应用环境。所有其他Linux应用场景与之比起来就好像是九牛一毛。因此,安全在这里会非常重要。如果这些设备都使用stable-kernel发布版本,那就会是安全的。
How to fix CVE numbers
Kroah Hartman展示了一个ppt来解释如何改进CVE编号。首先要“忽略它”,某种意义上,目前很多人都这么做了。第二步,我们可以选择来强化它,也就是要求kernel所打的每个patch都要有CVE编号。估计这可能是需要一些实习生来做6个月来完成,甚至还有人提过愿意赞助来实现。不过我们知道这个系统有很多问题,强迫大家使用也不一定能解决那些问题。因此,可以采用第三步,另一个选项,“从头创建一套方案”。
替代方案该是什么样子,这个很容易想到。首先要对每个漏洞分配一个独立编号,就跟CVE编号差不多。不过新系统需要是分布式的,不应该依赖其他人来生成编号。并且需要随时更新,可以搜索,而且要是公开的。
他用commit 7caac62ed (https://git.kernel.org/linus/7caac62ed )来做了例子介绍,这个是8月份合入的patch。changelog里面引用了3个CVE编号。kernel社区一直希望开发者把改动分成多个更简单的patch来做,不过这一例子里面一个patch fix了多个CVE问题也仍然被接受了。因为这些其实是同一个问题,大家应该用commit ID来代表这个patch,而不是用那一堆CVE编号来指代。他还过了一下其他几个patch,都包含了它所fix的问题的commit ID,通常用"Fixes" tag来标记的。这些ID的好处是,它在kernel代码里面是不会引起歧义的。
因此,bug fix其实早就有了一个独立的ID,也就是"Fixes" tag里标记的哪个commit开始有了这个bug。这个ID就能作为独立ID来指代安全漏洞,不需要再创建一个新的了。我们的commit ID已经用了14年了,大家甚至都没有留意。所以剩下的工作就是能推广这种用法。其实CVE编号就是推广出来的,为每个问题介绍了一下背景故事。我们的新机制也需要这样的推广。
要想开始推广,首先要有一个抓人眼球的名字。他举了几个例子,例如Linux Git Kernel ID (LGKI),Kernel Git ID (KGI),或者Kernel Hash (GKH)。这里大家哄堂大笑,因为明显他是在把自己名字往里套。最后,他认为最好的名字是“change ID”,这就是我们过去14年一直用的名字。change ID是独一无二的,全球通用的ID,我们可以继续用。格式可以类似CID-012345678ab。
Kroah-Hartman最后回到了他的action list里,他认为我们应该真的需要忽略CVE了,不过他又加了一条第四条:把我们一直在用的机制要改个名字推广开来。
Questions
Dmitry Vyukov首先问stable kernel发行版测试是否充分,每个stable release版本都修复了很多问题,如何彻底测试?Kroah-Hartman回答说kernel里面肯定有太多bug了,stable release利用了很多人的努力来减少质量回退(regression),他生成stable kernel上新加的patch里只有0.01%的patch导致了regression。
Vyukov说他的syzkaller test里面发现的bug,并没有人增加任何针对性的test。那么社区怎么能避免regression呢?回答是我们确实需要增加更多测试。
编者在会议中质疑这个0.01%数字,因为几年前的一次分析看下来regression patch大概是2%左右的比例。Kroah-Hartman说这个数字来自Chrome OS team,他们在统计"noticeable regressions"。
最后一个问题是关于那些被供应商不再提供新升级kernel的用户。他们该怎么办?Kroah-Hartman也认为这确实是一个问题。这些供应商可能会在kernel代码里加上三百万行代码,所以他们运行的其实是一个准Linux系统(Linux-like system)。他的回答是应该强制这些供应商来把代码推送到upstream kernel,也就是客户需要来推动。以Sony为例,他们就一直坚持他们的供应商必须得把代码放到mainline kernel。很多年前我们在服务器领域就是这么解决问题的,现在也是解决目前问题的有效方法。
[Your editor thanks the Linux Foundation, LWN's travel sponsor, for supporting his travel to this event.]
全文完
LWN文章遵循CC BY-SA 4.0许可协议。
热烈欢迎转载以及基于现有协议修改再创作~
长按下面二维码关注:Linux News搬运工,希望每周的深度文章以及开源社区的各种新近言论,能够让大家满意~
这篇关于LWN: 该如何改善CVE漏洞管理流程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!