Ripples from Stack Clash原文
作者: Jonathan Corbet 于2017年6月28日
从某种意义上说,6月19日宣布的堆栈冲突漏洞( Stack Clash vulnerability)并没有产生巨大的影响:到目前为止,至少在野外几乎没有(如果有的话)活动漏洞的故事。然而,在其他层面上,这似乎是一个重要的漏洞,因为它提出了一些关于社区如何处理安全问题和今后可以有何预期的问题。 不幸的是,迹象并不全是积极的。
对于不熟悉此漏洞的用户,可能会需要对此进行快速回顾。 进程的地址空间分为几个区域,其中两个是堆栈和堆区。 堆栈包含与运行程序的调用链相关联的短寿命(short-lived)数据; 如果程序访问堆栈当前下边界以下的内存,堆栈通常会放置在高地址处,并自动增长(向较低地址方向)。 相反,堆包含更长寿命(longer-lived)的内存并向上增长。 截至2010年,内核将一个防护页面(guard page)放置在堆栈下方,以防止堆栈访问进入堆区。
“堆栈冲突(Stack Clash)” 研究人员表示,通过一点细节处理(a bit of care),有可能跳过这个防护页面。 结果是,程序可能被愚弄从而使用大量堆栈空间,进而可能会覆盖堆数据,从而导致其被攻陷(compromise); 在这种情况下,setuid程序是特别受关心的。 已采取的修复措施是将防护页面(guard page )变成1MB的防护区域(guard region); 希望这足够多,从而不能轻易被跳过。
不是一个新问题
有些开发人员在安全领域工作,非常喜欢说 “我跟你说过这个情况的” 。 在这个案例下,他们似乎真的告诉过我们。解决这个问题的早期尝试可以在Andrea Arcangeli的2004年补丁中找到,它在堆栈和堆之间施加了可配置大小的隔离区。 尽管在SUSE的内核中持续了一段时间,但这个补丁从来没有进入主线。
在2010年,X服务器漏洞(X server exploit)利用了堆栈和堆之间的隔离缺陷,迫使内核社区采取了一些行动; 结果是Linus Torvalds的补丁在堆栈的底部添加了一个保护页面(无可配置性)。 它阻止了X的利用,许多人(以及LWN)宣布已经解决这个问题。 或者,至少,一旦处理了初始修复程序引入的各种错误(various bugs introduced by the initial fix),它似乎就被解决了。
在上述链接的LWN文章(发布后两天)的评论中, Brad Spengler和 “PaX团队” 声称单页隔离区是不足的。 最近,Spengler以他的经典风格发布了一个博客文章 ,说明他们如何告诉我们这个问题,但是从来没有解决,因为没有人知道他们在做什么。 但他们没有做的事情是,如果真正关心Linux内核的安全性,可能会做的是发布一个修正问题的补丁。
当然,还没有人贴上这样的补丁; 社区只能因为没有解决这个问题而自责。 也许LWN分担了这个责任的一部分,将问题描述为已经解决而实际并没修复的问题; 如果是这样,我们今后只能道歉并尝试做得更好。 但是我们可能认为真正的问题是缺乏专注于内核本身安全性的人。 确实有几个开发人员的工作需要他们如此,例如,检查和解决堆栈超限威胁(stack-overrun threats)。 确保这个问题得到妥善解决并不是任何人的工作,所以没有人做到这一点。
企业界大力支持Linux内核开发,但是对一些边缘领域(ghetto areas),似乎每个公司都认为是其他人的问题; 安全性是其中之一。 近期情况有所改善,但核心问题依然存在。
同时,可能有人会问:这次堆栈的问题是否真的已经被修复? 我们可以用一个带防护的 “是” 来回答(answer with a guarded "yes") - 至少一旦新补丁引起的各种问题被修复之后; 攻击者跳过1MB的隔离区可能很难。 但是,这是很难确定的。
禁运(Embargoes)
Alexander "Solar Designer" Peslyak是开放的oss安全(open oss-security)和封闭的 “发行版(distros)” 邮件组的经理; 后者用于讨论尚未公开披露的漏洞。 该邮件组的正常政策是,披露的脆弱性只能在两个星期内受到禁运; 它旨在打击公司在准备修复时尽可能长时间保持问题秘密的共同倾向。
如Peslyak所述,Stack Clash的披露没有遵循该政策。该邮件组首次在5月3日被通知有问题,5月17日披露的细节。原本5月30日的最初披露日期由Qualys推迟到6月19日的实际披露日期。Peslyak明确表示他认为禁运经历了漫长的时间,今后不会再重蹈覆辙了。
也许扩大禁运的最大问题是,把讨论放给公众看之前保持太久了。 (加密)发行版邮件组中的绝对数量显然在一段时间后很难处理。 但是,延迟也使提议的修复没得到足够多的审视(kept eyes off the proposed fix),结果是在披露日期合并的补丁包含了一些错误。尽快合并解决方案的冲动并不是禁运期的一个功能,但长期的禁运相当清楚地延迟了对这些修复的详细审查。由于缺乏已知的零日漏洞利用,早些时候披露这个问题更好,并开放的进行修复工作。
这是特别真实的,因为根据Qualys,延期禁运的原因是修复还没有准备好。更长的禁运显然也没有导致准备好。 有一个内核补丁,但等式的用户空间方面更糟糕。像 “用GCC的-fstack-check选项重新编译所有用户空间代码” 的目标在短时间内永远都不会发生,即使-fstack-check非常适合这个应用程序,目前还没有。
有一个相关的问题是,OpenBSD通过公开提交修补程序,在私人披露问题的一天后,在5月18日 - 1天后添加了1MB的防护区,打破了禁运。这引起了一些问题,包括OpenBSD(它不是发行版邮件组的成员)是否应该被纳入禁运的未来披露中。 但也许最有趣的一点是,尽管这个早期的披露,所有的地狱都固执地拒绝在其余地中松动(all hell stubbornly refused to break loose in its aftermath)。 Peslyak指出 :
讨论了这个问题,有些人对OpenBSD的行动感到不高兴,但最终决定,正如你正确地说,基本问题已经公 开,OpenBSD的提交并不会改变任何事情。
如上所述, “潜在问题” 已经知道多年。面向安全的系统在这一领域突然发生变化,应该是那些追踪提交流(follow commit streams),希望发现漏洞的人员的红旗。 但似乎没有证据表明这种披露 - 或者在长期禁运中显然出现的这种泄露 - 导致在其他系统准备就绪之前有开发利用。所以再说一次,并不清楚长期的禁运有助于这个局面。
进攻性的CVE派号机制(Offensive CVE assignment)
这整个剧集的另一个可能令人沮丧的结果就是使用CVE号码作为商业武器。 它可以说是从Kurt Seifried的这个推文开始,写到:“ CVE-2017-1000377哦,你以为运行GRsecurity PAX会救你吗?” Seifried提交的CVE-2017-1000377指出,grsecurity/PaX补丁集也受到Stack Clash漏洞的影响,这个声明引起一个开发人员争议。Seifried没有说过他是否将这些动作作为他在红帽的安全工作的一部分,但是Spengler至少在那里清楚地看到了关联。
Seifried的推理似乎是基于发送到oss-security邮件组的Qualys咨询文件的这个文本:
在2010年,grsecurity/PaX引入了一个可配置的堆栈保护页面:它的大小可以通过/proc/sys/vm/heap_stack_gap进行修改,默认情况下为64KB(与vanilla内核中的硬编码的4KB堆栈保护页面不同)。 不幸的是,64KB堆栈的保护页面不够大,可以用ld.so或者gettext()跳过。
这个咨询是值得阅读的。 它描述了一个针对sudo的攻击,而这个漏洞依赖于第二个漏洞,并禁用了一些安全保护。 Qualys说,通过这些保护措施,成功的漏洞利用可能需要数千年的时间。
因此,Spengler强烈否认CVE号是有效的,这并不完全令人惊讶。他以独特的方式表明,他认为整个事情是有商业动机的; 他说:“这会影响CVE进程”。Seifried辩称CVE为 “合法” ,但暗示他对整个节目已经感到厌倦,可能会放弃。
同时,Spengler不甘示弱(not to be outdone),针对主线内核提交了一大堆CVE号码 ,并提供了大量相关代码的作者Andy Lutomirski的报导。 Spengler似乎认为这是一个报复行为,并建议Lutomirski与Seifried谈谈清理事宜。 “我相信他会对待一个上游Linux的成员,就像我受到的一样,因为他是一个非常专业和公平的人”。
创建CVE机制是为了更容易地跟踪和讨论特定的漏洞。 有些人质疑了它的价值,但每个问题的唯一标识符似乎是有真正用途的。然而,如果CVE派号机制成为制造扔向竞争对手的泥球的工厂,那么它可能会失去任何现在的价值。人们只能希望社区意识到,把CVE数据库变成一个假消息,对任何人来说都不会有好处,不要这样做。
结论
我们社区处理安全问题的流程已经发展了几十年,在很多方面,他们在这个时期为我们服务。但他们也显示出严重压力的迹象。在紧急情况下积极识别和解决安全问题缺乏投资,已经伤害了我们很多次,并将继续这样做。 我们制定的禁运流程显然不是理想的,可以改进 - 如果我们知道改进将采取什么样的形式。
对于整个世界来说,我们行业的安全还没到达它所需要的水平,这一点越来越明显。 希望这将为改善形势创造一些商业激励。 但它也创造了攻击他人的动机,而不是将问题在家里修复。 这将导致一些越来越丑的行为; 让我们只希望我们的社区能够找出一种解决问题的方法,而不会采取分裂和破坏性的手段。 我们的努力比使用其他方法更有利于使Linux对所有用户更安全。