CVE-2026-92500 in Linux
摘要
由 VulDB • 2026-09-17
在 Linux 内核中,已修复以下漏洞:
ext4: 使用 fsdata 跟踪内联数据写入状态并修复竞态条件
write_end 处理程序不再检查实时 inode 状态(`ext4_has_inline_data(inode)` 和 `ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA)`),而是利用地址空间操作的 `fsdata` 参数,显式传递由 `write_begin` 准备的写入状态。
并发线程(如 `ext4_page_mkwrite()`)可能在 `write_begin` 和 `write_end` 之间将内联数据转换为 extent。如果发生这种情况,`write_end` 处理程序之前会错过内联 `write_end` 路径,而落入基于 extent 的 `write_end` 逻辑中。然而,由于在 `write_begin` 期间从未分配块缓冲区(block buffers),这会导致空指针解引用或数据丢失,因为 `folio_buffers(folio)` 为 NULL。
将 `EXT4_WRITE_DATA_INLINE (4)` 定义为位标志(Bit 2),将 fsdata 视为按位标志而非互斥枚举,以保持写入路径状态的独立性。通过 fsdata 通信此状态: 1) 当成功准备内联写入时,`ext4_write_begin()` 和 `ext4_da_write_begin()` 通过按位或运算在 *fsdata* 中设置 `EXT4_WRITE_DATA_INLINE` 位。 2) 在进入时,`ext4_write_begin()` 清除 `EXT4_WRITE_DATA_INLINE` 位,以安全处理 VFS 重试(其中 `generic_perform_write()` 在其重试跳转时会绕过 fsdata 初始化)。 3) `write_end` 处理程序执行按位与运算,检查是否设置了 `EXT4_WRITE_DATA_INLINE` 位,并相应地调用内联写入结束辅助函数。
此外,在缓冲写入期间,`ext4_write_inline_data_end()` 在准备写入后获取 xattr 锁。如果在 `write_end` 处理程序检查状态之后但在 `ext4_write_inline_data_end()` 获取 xattr 写锁之前,并发页面错误(`ext4_page_mkwrite()`)将内联数据转换为 extent,则后续检查将通过 `BUG_ON(!ext4_has_inline_data(inode))` 触发内核恐慌。
为了保持 git 历史记录的完整性和二分查找的清晰度,在此同一提交中,用优雅的错误处理重试路径替换了 `ext4_write_inline_data_end()` 中的 `BUG_ON` 检查。如果在锁定 xattr 后内联数据被清除,我们将安全地释放所有资源(释放 iloc.bh、解锁/释放 folio、停止活动的事务句柄),并返回 0(VFS 重试),以便让通用写入路径安全地重试该操作。
If you want to get best quality of vulnerability data, you may have to visit VulDB.