相关论文
最新的检查工作应该是《Precise and Scalable Detection of Double-Fetch Bugs in OS Kernels (SP’18)》(YouTube,GitHub,别名“Deadline”),它总结了前人对Double Fetch的刻画,形式化地描述了Double-Fetch Bug。作者列表中有Kangjie Lu和Taesoo Kim大佬。(远东的笔记)
Deadline之前针对Double Fetch的工作包括:
- 《Bochspwn: Identifying 0-days via System-wide Memory Access Pattern Analysis (BlackHat USA 2013)》/《Identifying and Exploiting Windows Kernel Race Conditions via Memory Access Patterns (BlackHat后作者写的论文)》(YouTube、GitHub、别人的笔记)在动态执行内核过程中插桩获取Fetch操作相关的执行状态信息并按照一定的策略(两个Fetch操作读的是同一块虚存;两个读操作相隔时间短;读操作发生在内核模式下;读的目标虚可被其它Ring3线程写)Online/Offline判断Double Fetch Situation的出现,最后人工判断Double Fetch Situation是否是Double Fetch Bug。
- 《Automated detection, exploitation, and elimination of double-fetch bugs using modern CPU features (arXiv’17,AsiaCCS’18)》(包含DECAF和DropIt两个工具,Gossip的笔记)Fuzz执行内核,并启动额外的Monitor线程利用缓存侧信道(如Flush+Reload)频繁刷新目标函数的参数并判断该参数是否被Fetch了(一旦参数被Fetch,就会触发Cache Hit使得访存时间短并被感知),接连的Fetch就说明Double Fetch Situation的出现。之后基于Flush-Reload/Flush+Flush自动化漏洞利用,以确定这个Double Fetch Situation使一个Double Fetch Bug。最后使用Intel TSX让Double Fetch操作包含在同一个Transaction中被原子执行,确保Double Fetch Bug被防御住。
- 《How Double-Fetch Situations turn into Double-Fetch Vulnerabilities: A Study of Double Fetches in the Linux Kernel (USENIX Security '17)》(YouTube)启发式地定义了Double Fetch Bug可能的代码Pattern,使用Coccinelle进行代码Pattern文本比对。
Deadline
前人的工作检查Double Fetch的思路过于启发式,所刻画的代码Pattern过于特例。而Deadline对Double Fetch Bug进行了形式化描述。
识别Double Fetch有两大步操作:
- 第一步,找到代码中连续的两次Fetch,由于对Kernel分析CFG然后寻找Fetch-Pair是一个不现实的路子,作者首先找到一个Fetch并将其标记为第二个Fetch,然后往回看代码中有没有第一个Fetch出现(如果往前看到有函数涉及Fetch的目标用户地址,那么就把该函数Inline展开来查看是否有第一个Fetch)
- 第二步,在两次Fetch之间识别是否有Double Fetch Bug,策略的形式化定义如下
- 两次从用户空间Fetch的内存存在重叠(文中有Overlap的数学描述)
- 两次目标内存存在重叠的Fetch操作之间,有控制依赖(当第一次Fetch结果满足一定条件会触发第二次Fetch)或数据依赖(第一次Fetch的结果用于计算或用于函数调用,之后执行第二次Fetch)(也存在数学描述)
- 无法证明第一次Fetch时的状态和第二次Fetch时的状态一致(也就是说无法确保第一次Fetch的内容和第二次Fetch的一致,一种有效地避免Double Fetch Bug的编程技巧时,将两次Fetch的结果进行比较,若不一致就进行警告)。
下图是理解检测Double Fetch策略的一个例子
Deadline归纳的Patch方法:
- 将第一次Fetch的内容覆盖到第二次Fetch的对应偏移处
- 比对两次Fetch的内容
- 第二次Fetch只Fetch第一次Fetch后剩下的内容
- 先Fetch一个比较大的用户内存,然后再在里面提取需要的内存
Deadline的几个问题:
- 它和前几个工作一样,无法分析Inter-procedure的Double Fetch Bug。
- 其它实现上的问题
杂记
顺带记一下找到的两个博客
https://scubsrgroup.github.io/BinaryDatabase/
https://securitygossip.com/