{"id":28981,"date":"2026-09-25T20:31:38","date_gmt":"2026-09-25T12:31:38","guid":{"rendered":"https:\/\/www.54iter.cn\/?vuln=cve-2026-97549"},"modified":"2026-09-25T20:31:38","modified_gmt":"2026-09-25T12:31:38","slug":"cve-2026-97549","status":"publish","type":"vuln","link":"https:\/\/www.54iter.cn\/?vuln=cve-2026-97549","title":{"rendered":"CVE-2026-97549 &#8211; In the Linux kernel, the following vulnerability has been resolved:\n\nxfs: fix under-reserv"},"content":{"rendered":"<p>In the Linux kernel, the following vulnerability has been resolved:<\/p>\n<p>xfs: fix under-reservation of blocks when repairing sf directories<\/p>\n<p>Whilst running QA on XFS for-next as of 7.3-rc2 with MKFS_OPTIONS=&#8221;-n<br \/>\nsize=8192&#8243;, I observed the following (trimmed) dmesg splat:<\/p>\n<p> XFS: Assertion failed: args-&gt;total &gt;= dp-&gt;i_nblocks &#8211; nblks, file: fs\/xfs\/libxfs\/xfs_da_btree.c, line: 2387<br \/>\n WARNING: fs\/xfs\/xfs_message.c:104 at assfail+0x46\/0x4a [xfs], CPU#0: xfs_scrub\/1426511<br \/>\n CPU: 0 UID: 0 PID: 1426511 Comm: xfs_scrub Tainted: G        W           7.3.0-rc2-djwx #rc2 PREEMPT(lazy)  6e418570b606a39783b0e7e7b30dc407b965f9e8<br \/>\n Tainted: [W]=WARN<br \/>\n RIP: 0010:assfail+0x46\/0x4a [xfs]<br \/>\n RSP: 0018:ffffc900010d7890 EFLAGS: 00010246<br \/>\n RAX: 0000000000000000 RBX: 0000000000000000 RCX: 00000000ffffffd1<br \/>\n RDX: 0000000000000000 RSI: 0000000000000021 RDI: ffffffffa059fd38<br \/>\n RBP: 0000000000000002 R08: 0000000000000000 R09: 0000000000000000<br \/>\n R10: 000000000000000a R11: 000000007fffffff R12: ffffc900010d7940<br \/>\n R13: ffff888368d8f980 R14: ffffc900010d7a48 R15: ffffc900010d78d0<br \/>\n FS:  00007f445c5ce680(0000) GS:ffff8884a97ea000(0000) knlGS:0000000000000000<br \/>\n CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033<br \/>\n CR2: 00007f443803b9a8 CR3: 0000000107a4b000 CR4: 00000000003506f0<br \/>\n Call Trace:<\/p>\n<p>  xfs_da_grow_inode_int+0x2e0\/0x300 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c]<br \/>\n  xfs_dir2_grow_inode+0x6e\/0x150 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c]<br \/>\n  xfs_dir2_sf_to_block+0x149\/0x870 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c]<br \/>\n  xrep_dir_swap_prep+0xe2\/0x110 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c]<br \/>\n  xrep_dir_swap+0xfb\/0x2f0 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c]<br \/>\n  xrep_dir_rebuild_tree+0x99\/0x100 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c]<br \/>\n  xrep_directory+0x83\/0x1c0 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c]<br \/>\n  xrep_attempt+0x4f\/0x1e0 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c]<br \/>\n  xfs_scrub_metadata+0x393\/0x5b0 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c]<br \/>\n  xfs_ioc_scrubv_metadata+0x306\/0x570 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c]<br \/>\n  xfs_file_ioctl+0xa4f\/0x1150 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c]<br \/>\n  __x64_sys_ioctl+0x76\/0xc0<br \/>\n  do_syscall_64+0x7a\/0x3b0<br \/>\n  entry_SYSCALL_64_after_hwframe+0x4b\/0x53<\/p>\n<p>This is a consequence of commit 0fe77e57588b98, which added the<br \/>\nfollowing assertion to xfs_da_grow_inode_int:<\/p>\n<p> ASSERT(args-&gt;total &gt;= dp-&gt;i_nblocks &#8211; nblks);<\/p>\n<p>Tracing this back to xrep_dir_swap_prep, I noticed that the xfs_da_args<br \/>\nobject that&#8217;s passed to xfs_dir2_sf_to_block sets args-&gt;total to 1.<br \/>\nThis is incorrect because mkfs set the directory block size to 8k and<br \/>\nthe filesystem block size to 4k.  In other words, args-&gt;total should be<br \/>\n2 here, not 1.<\/p>\n<p>Dave Chinner tripped over the same problem with the same branch through<br \/>\na different channel &#8212; his test setup set the fs block size to 1k, in<br \/>\nwhich case the directory block size is still set to 4k.  Here,<br \/>\nargs-&gt;total should be 4.<\/p>\n<p>Changing the assignment of args-&gt;total to sc-&gt;mp-&gt;m_dir_geo-&gt;fsbcount<br \/>\nmakes the assertion go away, but that isn&#8217;t a complete fix.  In<br \/>\nxrep_tempexch_estimate, we also incorrectly assume that a shortform<br \/>\nconversion requires 1 fsblock when it should be m_dir_geo-&gt;fsbcount.<br \/>\nWithout that, we can under-reserve space in the transaction and cause a<br \/>\nfilesystem shutdown.<\/p>\n<p>Note that the xfs_dabuf_nfsb helper will compute the correct value for<br \/>\ndirectories and xattr, so we use that instead of open-coding the logic.<br \/>\nAlso fix xrep_xattr_swap_prep to assign args-&gt;total via xfs_dabuf_nfsb<br \/>\nto avoid one logic bomb if we ever support multi-fsblock attrs.<\/p>\n<p>Tripped-by: 0fe77e57588b98 (&#8220;xfs: assert the reservation covers each da fork growth&#8221;)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the Linux kernel, the following vulnerability has been resolved:<\/p>\n<p>xfs: fix under-reservation of blocks when repairing sf directories<\/p>\n<p>Whilst running QA on XFS for-next as of 7.3-rc2 with MKFS_OPTIO<\/p>\n","protected":false},"template":"","meta":[],"categories":[],"tags":[],"class_list":["post-28981","vuln","type-vuln","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=\/wp\/v2\/vuln\/28981","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=\/wp\/v2\/vuln"}],"about":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=\/wp\/v2\/types\/vuln"}],"wp:attachment":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=28981"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.54iter.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=28981"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.54iter.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=28981"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}