CVE-2023-53608CVE-2023-53608是Linux内核nilfs2文件系统中存在的一个高危Use-After-Free(UAF)漏洞。该漏洞位于日志段构造函数nilfs_segctor_thread()中,在线程终止过程中与nilfs_segctor_kill_thread()函数之间存在竞争条件(race condition)。具体而言,在nilfs_segctor_thread()函数结束时,会将struct nilfs_sc_info结构体中的sc_task成员赋值为NULL以表示线程已完成,然后通过sc_wait_task等待队列通知nilfs_segctor_kill_thread()。然而,在NULL赋值之后到通知发出之前,nilfs_segctor_kill_thread()可能检测到sc_task为NULL并返回继续执行内存释放操作,导致nilfs_sc_info结构体在线程发出通知前就被释放,从而引发UAF漏洞。该漏洞由KASAN(内核地址消毒器)检测发现,CVSS评分为7.8,属于高危级别。攻击者需要本地低权限访问即可利用此漏洞,可能导致内核崩溃、信息泄露、特权提升等严重后果,影响机密性、完整性和可用性。该漏洞影响多个Linux内核稳定版本,官方已通过多个补丁进行修复。
该漏洞的根本原因是nilfs_segctor_thread()与nilfs_segctor_kill_thread()之间的同步机制存在缺陷。
技术原理:
1. nilfs_segctor_thread()是nilfs2文件系统的日志段构造守护线程,负责处理日志段的写入操作。在线程退出时,它执行以下序列:a) 将sc_task赋值为NULL;b) 通过waitqueue(sc_wait_task)唤醒等待中的nilfs_segctor_kill_thread()。
2. nilfs_segctor_kill_thread()在接收到通知后,会释放nilfs_sc_info结构体及其关联资源。
3. 竞争条件出现在以下场景:当nilfs_segctor_thread()完成NULL赋值后但尚未调用wake_up()通知之前,nilfs_segctor_kill_thread()可能已经通过其他路径检测到sc_task为NULL(例如通过sc_state_lock的检查),并提前返回执行清理逻辑,释放了nilfs_sc_info内存。
4. 之后nilfs_segctor_thread()尝试访问已被释放的nilfs_sc_info结构体(如访问sc_wait_task等待队列),触发UAF。
利用方式:
攻击者可通过本地低权限账户,通过频繁挂载/卸载nilfs2文件系统或触发文件系统操作,强制nilfs_segctor_thread()与nilfs_segctor_kill_thread()并发执行,从而触发竞争条件。成功后可导致内核崩溃(DoS)或进一步利用实现权限提升。
修复方案:
使用struct nilfs_sc_info的sc_state_lock自旋锁保护sc_task的NULL赋值和通知操作,确保原子性。由于nilfs_segctor_kill_thread()在检查sc_task是否为NULL时也持有sc_state_lock锁,从而消除了竞争窗口。