CVE-2018-18281—linux内核中关于TLB漏洞的分析
字数 2266 2025-08-06 08:35:16
Linux内核TLB漏洞(CVE-2018-18281)分析与利用教学文档
一、漏洞概述
CVE-2018-18281是Linux内核中一个关于TLB(Translation Lookaside Buffer)处理不当导致的漏洞,由Project Zero的Jann Horn在2019年1月17日发现并报告。该漏洞存在于内存管理子系统中的页表移动操作中,可能导致TLB失效不及时,从而引发安全风险。
二、基础知识
1. 内核抢占模型
Linux内核支持三种抢占模型:
- CONFIG_PREEMPT_NONE:无强迫抢占(服务器配置)
- CONFIG_PREEMPT_VOLUNTARY:自愿内核抢占(桌面配置)
- CONFIG_PREEMPT:内核可抢占(低延迟桌面配置)
Pixel 2使用CONFIG_PREEMPT配置,这意味着内核代码可以在执行期间的任何时候中断,包括进程持有互斥锁、信号量和位于RCU读端临界区时(取决于内核配置)。
2. 调度相关函数
sched_setaffinity:设置进程运行的CPU核心sched_setscheduler:设置进程调度策略和参数
调度策略分为:
- 普通调度策略:SCHED_NORMAL、SCHED_BATCH
- 实时调度策略:SCHED_FIFO、SCHED_RR、SCHED_DEADLINE
- 空闲调度策略:SCHED_IDLE
3. 页分配器
Linux页分配器基于buddy分配器实现,关键概念:
-
区域(Zone):
- ZONE_DMA:为DMA设备保留的内存
- ZONE_NORMAL:内核直接映射的内存
-
迁移类型(Migration Type):
- MIGRATE_UNMOVABLE:不可移动分配(如kmalloc)
- MIGRATE_MOVABLE:可移动分配(如用户空间内存)
- MIGRATE_RECLAIMABLE:可回收分配
- MIGRATE_CMA:为DMA预留的连续内存
-
冷热页:
- 冷页:不在高速缓存中
- 热页:仍在高速缓存中
- 通过per-cpu-pageset(pcp)管理
4. TLB和分页结构缓存
- TLB:缓存最后一级页表条目,加速地址转换
- 分页结构缓存:
- Intel:Paging-Structure Caches
- ARM:Intermediate table walk caches
- 存储非最后一级页表条目的副本
TLB失效通用模式:
- 从页表中删除条目但保持物理页引用
- 对所有相关CPU核心执行TLB刷新
- 删除物理页上的引用
三、漏洞原理
1. 内存管理锁机制
mmap_sem:保护VMA(Virtual Memory Area)- 页表锁:保护页表访问
2. mremap操作流程
mremap函数通过mremap_to->move_vma->move_page_tables->move_ptes移动页表,其中move_ptes函数的逻辑:
- 获取旧页表和新页表锁
- 刷新旧的TLB条目
- 对于每个非空条目:
- 原子性读取并清除页表条目
- 如果条目为Dirty,设置force_flush标志
- 将条目写入新页表
- 解锁新页表
- 根据force_flush决定是否执行TLB刷新
- 解锁旧页表
3. 漏洞点
问题在于:
- 新页表解锁后,旧页表解锁前,另一个进程可能删除页
- TLB刷新可能延迟到
move_page_tables函数中执行 - 这导致在页被释放后,旧TLB条目可能仍然有效
四、漏洞利用
1. 攻击准备
- 选择目标页:如
/system/lib64/libandroid_runtime.so中的com_android_internal_os_Zygote_nativeForkAndSpecialize函数页 - 从页缓存中删除目标页:
- 使用
fallocate制造内存压力 - 通过
mincore检查页是否在缓存中 - 使用
MADV_RANDOM映射文件其他页防止预读
- 使用
2. 利用步骤
- 分配具有文件背景的页并映射(映射1)
- 触发mremap/ftruncate竞争:
- 设置mremap进程为SCHED_IDLE优先级
- 与正常优先级进程运行在同一CPU核心
- 通过管道控制抢占时机
- 监控
/proc/<pid>/status中的VmPTE确定写入时机
- 从目标页开始读取,导致内核重新分配已释放页
- 通过映射1轮询页内容,直到包含目标页
- 通过旧TLB反复覆盖目标页
3. Shellcode设计
利用zygote进程的CAP_SYS_ADMIN能力:
- 读取SELinux上下文
- 使用
sethostname结果覆盖主机名
五、补丁分析
主要修复:
- 将对
flush_tlb_range的调用移到新页表解锁之前 - 确保在释放页表引用前完成TLB刷新
六、防御建议
- 及时更新内核补丁
- 限制关键进程的调度优先级
- 监控异常的内存访问模式
- 考虑使用硬件支持的TLB失效机制
七、参考资料
- Memory Management with Huge Pages
- ARM64系统调用表(https://github.com/retme7/arm64_syscall_nr)
- Rowhammer防御相关研究
本教学文档详细分析了CVE-2018-18281漏洞的原理、利用方法及防御措施,涵盖了从基础知识到实际利用的全过程。理解此漏洞需要对Linux内存管理、TLB机制和调度系统有深入认识。