xfs: validate v5 feature fields

[ Upstream commit f0f5f658065a5af09126ec892e4c383540a1c77f ]

We don't check that the v4 feature flags taht v5 requires to be set
are actually set anywhere. Do this check when we see that the
filesystem is a v5 filesystem.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Leah Rumancik <leah.rumancik@gmail.com>
Acked-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Dave Chinner 2023-02-14 13:25:29 -08:00 committed by Greg Kroah-Hartman
parent ea0ce7c136
commit 5f0e21a4a8

View File

@ -30,6 +30,47 @@
* Physical superblock buffer manipulations. Shared with libxfs in userspace.
*/
/*
* Check that all the V4 feature bits that the V5 filesystem format requires are
* correctly set.
*/
static bool
xfs_sb_validate_v5_features(
struct xfs_sb *sbp)
{
/* We must not have any unknown V4 feature bits set */
if (sbp->sb_versionnum & ~XFS_SB_VERSION_OKBITS)
return false;
/*
* The CRC bit is considered an invalid V4 flag, so we have to add it
* manually to the OKBITS mask.
*/
if (sbp->sb_features2 & ~(XFS_SB_VERSION2_OKBITS |
XFS_SB_VERSION2_CRCBIT))
return false;
/* Now check all the required V4 feature flags are set. */
#define V5_VERS_FLAGS (XFS_SB_VERSION_NLINKBIT | \
XFS_SB_VERSION_ALIGNBIT | \
XFS_SB_VERSION_LOGV2BIT | \
XFS_SB_VERSION_EXTFLGBIT | \
XFS_SB_VERSION_DIRV2BIT | \
XFS_SB_VERSION_MOREBITSBIT)
#define V5_FEAT_FLAGS (XFS_SB_VERSION2_LAZYSBCOUNTBIT | \
XFS_SB_VERSION2_ATTR2BIT | \
XFS_SB_VERSION2_PROJID32BIT | \
XFS_SB_VERSION2_CRCBIT)
if ((sbp->sb_versionnum & V5_VERS_FLAGS) != V5_VERS_FLAGS)
return false;
if ((sbp->sb_features2 & V5_FEAT_FLAGS) != V5_FEAT_FLAGS)
return false;
return true;
}
/*
* We support all XFS versions newer than a v4 superblock with V2 directories.
*/
@ -37,9 +78,19 @@ bool
xfs_sb_good_version(
struct xfs_sb *sbp)
{
/* all v5 filesystems are supported */
/*
* All v5 filesystems are supported, but we must check that all the
* required v4 feature flags are enabled correctly as the code checks
* those flags and not for v5 support.
*/
if (xfs_sb_is_v5(sbp))
return true;
return xfs_sb_validate_v5_features(sbp);
/* We must not have any unknown v4 feature bits set */
if ((sbp->sb_versionnum & ~XFS_SB_VERSION_OKBITS) ||
((sbp->sb_versionnum & XFS_SB_VERSION_MOREBITSBIT) &&
(sbp->sb_features2 & ~XFS_SB_VERSION2_OKBITS)))
return false;
/* versions prior to v4 are not supported */
if (XFS_SB_VERSION_NUM(sbp) < XFS_SB_VERSION_4)
@ -51,12 +102,6 @@ xfs_sb_good_version(
if (!(sbp->sb_versionnum & XFS_SB_VERSION_EXTFLGBIT))
return false;
/* And must not have any unknown v4 feature bits set */
if ((sbp->sb_versionnum & ~XFS_SB_VERSION_OKBITS) ||
((sbp->sb_versionnum & XFS_SB_VERSION_MOREBITSBIT) &&
(sbp->sb_features2 & ~XFS_SB_VERSION2_OKBITS)))
return false;
/* It's a supported v4 filesystem */
return true;
}
@ -264,12 +309,15 @@ xfs_validate_sb_common(
bool has_dalign;
if (!xfs_verify_magic(bp, dsb->sb_magicnum)) {
xfs_warn(mp, "bad magic number");
xfs_warn(mp,
"Superblock has bad magic number 0x%x. Not an XFS filesystem?",
be32_to_cpu(dsb->sb_magicnum));
return -EWRONGFS;
}
if (!xfs_sb_good_version(sbp)) {
xfs_warn(mp, "bad version");
xfs_warn(mp,
"Superblock has unknown features enabled or corrupted feature masks.");
return -EWRONGFS;
}