The da-node verifier can accept an attribute node count that only fits a larger directory block. Inactivation bypasses the lookup path's geometry check, so __xfs_da3_node_remove() can read and write beyond the attribute buffer. For a v5 filesystem with 4 KiB blocks and 64 KiB directory blocks, count 8184 causes a 65464-byte memmove. Reject counts above mp->m_attr_geo->node_ents before removing entries. This also bounds subsequent removals, since the count only decreases. Fixes: b854e1c4eff3 ("xfs: close crash window in attr dabtree inactivation") Cc: stable@vger.kernel.org Signed-off-by: Shengzhuo Wei --- fs/xfs/xfs_attr_inactive.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/fs/xfs/xfs_attr_inactive.c b/fs/xfs/xfs_attr_inactive.c index a5b69c0fbfd05..b8230fa458fff 100644 --- a/fs/xfs/xfs_attr_inactive.c +++ b/fs/xfs/xfs_attr_inactive.c @@ -153,6 +153,14 @@ xfs_attr3_node_inactive( } xfs_da3_node_hdr_from_disk(mp, &ichdr, bp->b_addr); + + if (ichdr.count > mp->m_attr_geo->node_ents) { + xfs_buf_mark_corrupt(bp); + xfs_trans_brelse(*trans, bp); + xfs_dirattr_mark_sick(dp, XFS_ATTR_FORK); + return -EFSCORRUPTED; + } + parent_blkno = xfs_buf_daddr(bp); if (!ichdr.count) { xfs_trans_brelse(*trans, bp); -- 2.47.3