xfs: improve ondisk dquot flags checking
authorDarrick J. Wong <darrick.wong@oracle.com>
Thu, 16 Jul 2020 01:39:51 +0000 (18:39 -0700)
committerDarrick J. Wong <darrick.wong@oracle.com>
Wed, 29 Jul 2020 03:24:14 +0000 (20:24 -0700)
Create an XFS_DQTYPE_ANY mask for ondisk dquots flags, and use that to
ensure that we never accept any garbage flags when we're loading dquots.
While we're at it, restructure the quota type flag checking to use the
proper masking.

Note that I plan to add y2038 support soon, which will require a new
xfs_dqtype_t flag for extended timestamp support, hence all the work to
make the type masking work correctly.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
fs/xfs/libxfs/xfs_dquot_buf.c
fs/xfs/libxfs/xfs_format.h

index 75c164ed141cb0d26998189d7ec1855f087542d8..39d64fbc6b87d0348dddc1730d2e5db6650ef327 100644 (file)
@@ -39,6 +39,8 @@ xfs_dquot_verify(
        struct xfs_disk_dquot   *ddq,
        xfs_dqid_t              id)     /* used only during quotacheck */
 {
+       __u8                    ddq_type;
+
        /*
         * We can encounter an uninitialized dquot buffer for 2 reasons:
         * 1. If we crash while deleting the quotainode(s), and those blks got
@@ -59,9 +61,12 @@ xfs_dquot_verify(
        if (ddq->d_version != XFS_DQUOT_VERSION)
                return __this_address;
 
-       if (ddq->d_flags != XFS_DQTYPE_USER &&
-           ddq->d_flags != XFS_DQTYPE_PROJ &&
-           ddq->d_flags != XFS_DQTYPE_GROUP)
+       if (ddq->d_flags & ~XFS_DQTYPE_ANY)
+               return __this_address;
+       ddq_type = ddq->d_flags & XFS_DQTYPE_REC_MASK;
+       if (ddq_type != XFS_DQTYPE_USER &&
+           ddq_type != XFS_DQTYPE_PROJ &&
+           ddq_type != XFS_DQTYPE_GROUP)
                return __this_address;
 
        if (id != -1 && id != be32_to_cpu(ddq->d_id))
index 0fa969f6202c9c4608376e42f552d483a690208e..29564bd32befd0d513df9cb68f2b72802ccdd805 100644 (file)
@@ -1158,6 +1158,8 @@ static inline void xfs_dinode_put_rdev(struct xfs_dinode *dip, xfs_dev_t rdev)
                                 XFS_DQTYPE_PROJ | \
                                 XFS_DQTYPE_GROUP)
 
+#define XFS_DQTYPE_ANY         (XFS_DQTYPE_REC_MASK)
+
 /*
  * This is the main portion of the on-disk representation of quota information
  * for a user.  We pad this with some more expansion room to construct the on