xfs: validate v5 feature fields
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>
This commit is contained in:
parent
dd0d2f9755
commit
f0f5f65806
@ -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;
|
||||
}
|
||||
@ -267,12 +312,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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user