Commit 973975b7 authored by Darrick J. Wong's avatar Darrick J. Wong
Browse files

xfs: validate ag btree levels using the precomputed values



Use the AG btree height limits that we precomputed into the xfs_mount to
validate the AG headers instead of using XFS_BTREE_MAXLEVELS.

Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
parent f53acfac
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -2906,13 +2906,13 @@ xfs_agf_verify(

	if (be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]) < 1 ||
	    be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]) < 1 ||
	    be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]) > XFS_BTREE_MAXLEVELS ||
	    be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]) > XFS_BTREE_MAXLEVELS)
	    be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]) > mp->m_ag_maxlevels ||
	    be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]) > mp->m_ag_maxlevels)
		return __this_address;

	if (xfs_sb_version_hasrmapbt(&mp->m_sb) &&
	    (be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]) < 1 ||
	     be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]) > XFS_BTREE_MAXLEVELS))
	     be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]) > mp->m_rmap_maxlevels))
		return __this_address;

	if (xfs_sb_version_hasrmapbt(&mp->m_sb) &&
@@ -2939,7 +2939,7 @@ xfs_agf_verify(

	if (xfs_sb_version_hasreflink(&mp->m_sb) &&
	    (be32_to_cpu(agf->agf_refcount_level) < 1 ||
	     be32_to_cpu(agf->agf_refcount_level) > XFS_BTREE_MAXLEVELS))
	     be32_to_cpu(agf->agf_refcount_level) > mp->m_refc_maxlevels))
		return __this_address;

	return NULL;
+2 −2
Original line number Diff line number Diff line
@@ -2535,12 +2535,12 @@ xfs_agi_verify(
		return __this_address;

	if (be32_to_cpu(agi->agi_level) < 1 ||
	    be32_to_cpu(agi->agi_level) > XFS_BTREE_MAXLEVELS)
	    be32_to_cpu(agi->agi_level) > M_IGEO(mp)->inobt_maxlevels)
		return __this_address;

	if (xfs_sb_version_hasfinobt(&mp->m_sb) &&
	    (be32_to_cpu(agi->agi_free_level) < 1 ||
	     be32_to_cpu(agi->agi_free_level) > XFS_BTREE_MAXLEVELS))
	     be32_to_cpu(agi->agi_free_level) > M_IGEO(mp)->inobt_maxlevels))
		return __this_address;

	/*
+1 −1
Original line number Diff line number Diff line
@@ -195,7 +195,7 @@ xfs_iformat_btree(
		     XFS_BMDR_SPACE_CALC(nrecs) >
					XFS_DFORK_SIZE(dip, mp, whichfork) ||
		     ifp->if_nextents > ip->i_d.di_nblocks) ||
		     level == 0 || level > XFS_BTREE_MAXLEVELS) {
		     level == 0 || level > XFS_BM_MAXLEVELS(mp, whichfork)) {
		xfs_warn(mp, "corrupt inode %Lu (btree).",
					(unsigned long long) ip->i_ino);
		xfs_inode_verifier_error(ip, -EFSCORRUPTED,