CVE-2025-68358CVE-2025-68358是Linux内核中Btrfs文件系统的一个中等严重性安全漏洞,源于btrfs_clear_space_info_full()函数中对位域(bitfield)的非原子读写操作。该漏洞存在于btrfs_space_info结构的full、chunk_alloc和flush三个位域字段中,由于编译器生成的读-改-写(read-modify-write)序列不是原子操作,在多线程并发场景下可能导致数据竞争。当一个线程正在清除full标志时,另一个线程可能同时修改flush标志,导致数据结构状态不一致,破坏系统不变量。这种竞态条件可能导致系统进入死锁状态,进程永久阻塞在ticket机制上无法恢复。该漏洞需要本地低权限访问即可触发,无需用户交互。
漏洞根源在于btrfs_space_info结构使用了位域定义三个标志位(full、chunk_alloc、flush),它们共享同一个底层字(word)。根据内存屏障规范,位域操作不是原子的,编译器会生成非原子的读-改-写序列。在btrfs_clear_space_info_full()函数中,遍历space_infos列表并写入found->full=0时没有加锁保护。假设场景:T1线程执行btrfs_commit_transaction调用btrfs_clear_space_info_full()将full置0,T2线程同时执行do_async_reclaim_data_space()在持有锁的情况下将flush置0。由于位域操作的非原子性,T1读取到flush=1后写入full=0时,可能覆盖T2对flush的修改,导致flush标志错误地保持为1。这破坏了flush标志的不变量(flush为0表示无工作排队或运行),使后续分配请求添加到tickets队列但因检测到flush=1而不触发工作队列,最终导致ticket永久阻塞。分析汇编代码确认:设置flush位为0使用指令'andb $0xfb,0x60(%rbx)',设置full位为0使用'andb $0xfe,-0x20(%rax)',均为读-改-写操作。修复方案是将三个位域成员改为bool类型以确保原子性写入。