CVE-2026-43118Linux内核中的btrfs文件系统存在一个安全漏洞,该问题源于日志回放机制中的逻辑缺陷。当记录inode的存在(例如由于新建名称或记录目录条目)时,系统会将日志中inode项的生成号设置为0,意在告知日志回放函数保留子卷树中的i_size。然而,如果inode已在当前事务中记录过或创建于旧事务且大小为0,随后因硬链接或重命名再次记录时,会记录i_size为0且生成号为0。在日志回放时,系统检测到生成号为0,错误地跳过了将i_size从旧值更新为0的操作。这导致在断电恢复后,本应被截断的文件保留了原始数据大小,造成文件系统状态不一致。
该漏洞的核心在于btrfs文件系统日志功能的`overwrite_item()`函数处理逻辑。正常情况下,当仅记录inode存在(LOG_INODE_EXISTS)而不记录数据范围时,系统将生成号设为0,以指示回放过程不应覆盖子卷树中的i_size。但在特定场景下:首先创建文件并写入数据(如64K),同步后将其截断为0并fsync;接着创建硬链接或重命名并fsync目录。此时,inode被再次以“存在模式”记录,携带i_size=0和generation=0。当系统崩溃重启进行日志回放时,`overwrite_item()`发现日志项的generation为0,误判需保留子卷树中的旧i_size(64K),从而忽略了日志中记录的i_size(0)。这导致文件恢复后大小错误,破坏了文件系统的一致性。修复方案修改了`fill_inode_item()`,确保如果inode在当前事务中已记录过i_size,则记录真实生成号;对于旧事务的inode,则从提交根中获取正确的i_size,以确保回放逻辑能正确更新文件大小。