容器(container)技术的兴起有赖于内核层面提供的资源隔离机制(例如Linux kernel的namespace),但是这类隔离往往百密一疏,在实际生产环境下,厂商往往顾忌此类安全威胁而不敢大规模应用。今天推荐的ASPLOS 2023论文 KIT: Testing OS-Level Virtualization for Functional Interference Bugs 就讨论了如何在现实系统中发现一类典型的影响资源隔离安全的bug
作者指出,在内核维护的资源中,像socket、文件、计时器(timers)这类资源,由于存在非常多的system call可以访问到它们,因此对其进行严格、精确而完备的访问控制难度非常之大。一旦产生相关的疏忽,就会导致所谓的functional interference bug的出现,而这种bug往往是逻辑错误,用传统的程序分析方法(例如fuzzing)是很难检查出来的。为了更好地测试此类bug,作者设计了KIT
动态测试框架,按照如下图所示的流程来发现潜藏的functional interference bug
抽象不如具体,你如果看上图看不太懂,就看一下下面这个更实际的例子:在Linux的内核网络协议栈中,有一个packet_type
类型的数据结构,主要用来描述(面向网络设备的)不同协议的数据包。用户可以通过检查/proc/net/ptype
来查看系统中支持的packet_type
类型。在容器隔离的环境下,这个信息属于不同的net namespace,因而不同的容器应该拥有自己独立的/proc/net/ptype
文件。然而,如果下图中的sender容器(左上角)创建了一个packet socket(①),就会影响另一个receiver容器中去执行pread
的结果——也就是图中①→②→③和➊→➋→➌的差别。实际上,这个例子正是KIT
在现实中发现的functional interference bug之一。
当然,KIT
在实际应用中没你想象中这么简单,首先它需要找到一些好的测试用例来帮助触发functional interference bug,其次它还要确认因果性——分析执行差异是否确实是由于测试用例引起(例如有时候其他环境因素也会让测试结果产生偏差)。下面让我们看看作者是怎么分别解决这两个难题的。
对于第一个问题(如何产生测试用例),作者引入了一个名为profiling-based kernel data flow analysis的数据流分析,这个技术来源于作者在SOSP 2021上发表的论文 Snowboard: Finding Kernel Concurrency Bugs through Systematic Inter-thread Communication Analysis,有兴趣的读者可以延伸阅读一下。对于第二个问题(如何判定执行差异是不同测试用例导致),KIT
对不同的receiver容器中的system call trace(利用已有工具例如KASAN和KCSAN的hook function进行记录)进行比较,具体是通过对system call trace的abstract syntax tree也就是AST进行对比,如下图的算法所示:
在实际的测试中,KIT
在Linux 5.13内核中找到了9个functional interference bug(如下表所示)。
作者还对其中的一些bug进行了root cause分析。例如前面提到的那个packet_type
相关的functional interference bug,作者发现,在如下代码中,由于没有对当前运行环境的net namespace做判断(忘记了还需要考虑不同的namespace场景),因而产生了信息泄露。
对那些已知的functional interference bug,作者也用KIT
进行了复测。在CVE列表中能找到的所有7个相关的functional interference bug中,KIT
能够发现其中的5个,效果是非常不错的:
论文:https://dl.acm.org/doi/10.1145/3575693.3575731
代码:https://github.com/rssys/kit-artifact
原文始发于微信公众号(安全研究GoSSIP):G.O.S.S.I.P 阅读推荐 2023-04-03 KIT
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论