LWN:漫长的修复之路(CVE-2021-20316)!

Linux News搬运工

共 4383字,需浏览 9分钟

 ·

2022-03-05 20:57

关注了就能看到更多这么棒的文章哦~

The long road to a fix for CVE-2021-20316

By Jonathan Corbet
February 10, 2022
DeepL assisted translation
https://lwn.net/Articles/884052/

那些有着良好维护的自由软件项目,通常都会迅速 fix 已知的安全问题,用于在 Windows 和 Unix 系统之间提供交互的 Samba 项目也同样如此。因此,我们就非常想知道为什么 CVE-2021-20316(一个符号链接相关的漏洞)的修复工作要花费两年多的时间。有时候安全漏洞可以对代码的简单调整就能 fix。也有很多情况下的 fix 需要对一个项目中的大部分内部代码进行大规模重写。这个特殊的漏洞就属于后面这种情况,需要对 Samba 的虚拟文件系统(VFS)层进行公开方式地重写,来解决一个尚未公开的漏洞。

故事从 2019 年 5 月 Michael Hanselmann 的一份错误报告开始。当 SMB 客户端要求服务器端创建一个新目录时,服务器必须进行一些检查确保客户端有这个权限。其中,服务器需要确保请求的目录确实是位于这个 export 出来的 SMB 共享目录中,而不是位于服务器文件系统中其他地方的。不幸的是,在服务器端执行检查和实际创建目录这两个操作之间存在一个无法避免的时间窗口。如果恶意用户能够在这个窗口中用一个符号链接来替换新目录路径中的一个环节,那么 Samba 会傻乎乎地跟着这个链接跳到错误的地方来创建目录,这个结果肯定会让正常人感到不爽的,但是攻击者会很开心。

这是一个典型的检查时间/使用时间(TOCTOU,time-of-check/time-of-use)漏洞,已经是符号链接在各种漏洞场景中一种臭名昭著的利用方式了。这也是一个很难 fix 的漏洞,尤其是在 Samba 这样非常在乎可移植性的系统中。没有简单的、跨平台的方法来查询文件系统中的 path 的属性之后能安全地针对检查结果来采取行动,从而确保恶意攻击者不能在这个过程中篡改什么。不过,我们还是必须要做些工作的,所以 Samba 的开发者 Jeremy Allison 参与编写了一个 fix 程序。CVE 编号 CVE-2019-10151 就被正式分配给这个问题了。

The real problem

我们希望能想出一个快速的解决方案,但从一开始,Allison 就判定这里真正的问题是使用了 path name 跟与服务器端文件系统进行交互。每当一个 path 被传递给内核时,就必须重新执行一次 path walk through(也就是根据路径来逐层深入)操作;任何一个用户只要能够让这个对路径进行 walk through 的过程控制在某个时间到达某个位置(比如通过瞬间替换符号链接)都可以利用这种能力来迷惑我们的服务器。不过幸运的是,我们还有一种并不需要路径不可变的方法。

多年来,内核中已经支持了一组用来对文件句柄(打开了的文件的描述符,open file descriptor)而不是路径名称进行操作的系统调用。例如,仔细编写的服务器程序可以使用 openat2() 来为一个目标目录创建一个文件描述符,接下来进行检查来确保该目录是符合预设条件的,然后使用 mkdirat() 创建一个不会被重定向到错误地点的子目录。如果代码写得正确的话,就可以用这些系统调用来避免 Samba 中的这种 TOCTOU 竞态问题,但前提是必须要在代码里使用这些系统调用。而 Samba 在 2019 年的时候对这些系统调用的支持还不怎么好。当时,Allison 说:"最终我们需要修改 VFS 来使用所有系统调用的 syscallAT() 类型变体,但这是对 VFS 进行的一个重写工作,我们将不得不排好计划,无法现在完成"。

在花费了一个多月试图解决该漏洞(同时也包括人们开始找出来的其他跟符号链接相关的问题)的过程中,越来越明显地看到人们打算放弃了。到 2019 年 7 月中旬,Allison 似乎已经放弃了大规模的重写:"这将是一个漫长的过程,需要重写服务器中的路径名处理代码"。不过,这里有一个复杂的问题需要处理:在这项工作进行的同时,漏洞仍未得到修复,也未被披露。那么,如何向其他关注 Samba 项目开发工作的人来解释这些相关 patch 呢?Allison 说:

我们需要重写文件服务器端程序,从而[使]所有路径名操作中的符号链接竞态冲突的地方都改成安全实现。这事太大了,不能私下进行,所以我以 "让 VFS 现代化从而使用基于文件句柄的操作函数" 的名义来公开进行(没有明确说我 为什么 要这样做)。

这个改动除了需要隐藏其真正的目的之外还有几个方面要注意,因此使这个任务变得更加困难。其中之一就是 SMB 协议的第一版(SMB1)的核心代码就是基于 path name 的,因此服务端几乎无法使用其他方式。在 2019 年 9 月的 Samba 4.11 版本中,突然把 SMB1 废弃掉,就是由于这个问题所推动的决策。

相应地,SMB2 协议在很大程度上是基于文件句柄的,这就可以使服务器端软件实现可以更容易地采用同样的方式来工作了。但是 Samba 是一个有很多年历史包袱的古老程序了,所以很多内部接口仍然在使用 path name,哪怕可以很容易获取到文件句柄。这其中就包括了用来与具体的 host 文件系统对应的 kernel module 交互或者添加病毒扫描等功能的 VFS 接口。修改所有这些内部 API 是一项庞大的工作,将会触及到 Samba 服务器中的许多代码。

Thousands of changes

在接下来的两年里,Allison 为 Samba 仓库贡献了 1638 个提交(commit),占同期所有提交总数的 17%。并非所有的提交都是针对 VFS 的重写的,但其中大部分都是。而且 Allison 不是一个人在战斗,Ralph Böhme(1261 条提交)、Noel Power(438 条)和 Samuel Cabrero(251 条)也为这个项目做出了很大的贡献。Samba VFS 的 "现代化" 工作吸引了项目的大部分注意力,而对于那些不了解这里真正的问题的人来说,根本没意识到这件事情。

Böhme 在 2021 年的 SambaXP 活动中介绍了这项工作(视频在 https://www.youtube.com/watch?v=JUlT2QYddKY ,PPT 在 https://sambaxp.org/fileadmin/user_upload/sambaxp2021-slides/Boehme_The_New_VFS.pdf ),但从未提及到之所以推动这项(仍然紧迫的)工作的背后存在的安全问题。该讲座深入探讨了很多需要做的细节,以及各种问题是如何在 Linux 上解决的;对于任何想深入挖掘的人来说,建议观看该讲座。在 Samba 的 wiki 上也有一些信息。

在 2021 年 7 月,Allison 宣布胜利完成了工作:

随着 master 分支上的 commit e168a95c1bb1928cf206baf6d2db851c85f65fa9,我相信所有关于 meta-data 的竞态冲突问题现在在默认路径中都得到了 fix。async 进行的 DOS 属性读取仍然使用了基于 path 的 getxattr,还有一些 VFS module 目前对符号链接的处理也不是安全的,但我相信从 Samba 4.15.0 中开始缺省配置的 Samba 不会再有这种漏洞了。

在那之后,其余的基于 path 的扩展属性调用也被 fix 了。当然还有一些细节需要处理,包括原来的 CVE 编号由于太久没有更新而过期了。这就需要分配一个新的 CVE 编号,这就是为什么这个漏洞被称为 CVE-2021-43566。这项工作确实在 2021 年 9 月的 Samba 4.15.0 版本中出现的,但其实已经是在最初报告出漏洞的两年多之后了。

在漏洞披露文档中,Samba 项目是这样描述这个情况的:

我们花了两年半的时间来彻底重写 Samba VFS 层,以便在所有涉及到对返回给客户端的 metadata 进行读写的情况下不再使用基于 path name 的调用 API 了。这项工作最终在 Samba 4.15.0 中完成。[…]

由于现在所有的操作都是基于一个打开的句柄上完成的,我们相信在 Samba 4.15.0 以及所有未来版本的 Samba 中都已经完全消除了再次出现符号链接竞态冲突问题的可能性。

披露报告还指出,由于这个 rewrite 重写工作改动巨大,因此在早期的 Samba 版本中就无法修复这个漏洞了。

最终,Samba 项目成功地在这个漏洞的具体消息传播开来之前,在任何已知的对此漏洞利用的实例出现之前,将这个漏洞 fix 了。但这是一场赌博,攻击者往往会留意他感兴趣的项目的代码仓库,希望能注意到一些解决了尚未公开的漏洞的 patch。我们很自然地会将这个案例跟 Meltdown 和 Spectre 披露前的情况进行对比,当时这两个项目也需要进行大规模修改来解决尚未披露的漏洞。但是,与研究 Spectre 的开发者不同,Samba 的开发者们找到了一种公开进行工作的方式,确保了所有的 patch 都得到了该有的 review,并将问题披露后必须要解决掉的这个麻烦降到了最低。

这场赌博似乎已经得到了回报,尽管后续可能还是会有别的可能性。从那时开始,Allison 一直在指出,符号链接一般都很危险,而且其他项目几乎肯定也有类似的问题。他计划在今年晚些时候为 SambaXP 做一个演讲,估计会比 Böhme 在 2021 年的演讲有更多的细节和说服力。Samba 用户(至少是那些已经更新到最新版本的用户)可能可以对符号链接攻击方式免疫了,但我们仍在依赖的许多其他系统软件可能仍然会有这种问题。

(感谢 Jeremy Allison 回答问题并对本文的草稿进行技术审查)。

全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。

欢迎分享、转载及基于现有协议再创作~

长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~



浏览 24
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报