]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: improve ondisk dquot flags checking
authorDarrick J. Wong <darrick.wong@oracle.com>
Tue, 15 Sep 2020 19:50:35 +0000 (15:50 -0400)
committerEric Sandeen <sandeen@sandeen.net>
Tue, 15 Sep 2020 19:50:35 +0000 (15:50 -0400)
Source kernel commit: a990f7a84edc9941956ea3c1dfb89733c80f9ad0

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>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
db/check.c
libxfs/xfs_dquot_buf.c
libxfs/xfs_format.h

index 9479a697231165afe5b0f806c00d39c091063441..7b81c74fec7f74f2e9daae1362b3c934dffd0b61 100644 (file)
@@ -3509,7 +3509,7 @@ process_quota(
                                error++;
                                continue;
                        }
-                       if (dqb->dd_diskdq.d_flags != exp_flags) {
+                       if (dqb->dd_diskdq.d_flags & ~XFS_DQTYPE_ANY) {
                                if (scicb)
                                        dbprintf(_("bad flags %#x for %s dqblk "
                                                 "%lld entry %d id %u\n"),
@@ -3518,6 +3518,17 @@ process_quota(
                                error++;
                                continue;
                        }
+                       if ((dqb->dd_diskdq.d_flags & XFS_DQTYPE_REC_MASK)
+                                                               != exp_flags) {
+                               if (scicb)
+                                       dbprintf(_("wrong type %#x for %s dqblk "
+                                                "%lld entry %d id %u\n"),
+                                               dqb->dd_diskdq.d_flags &
+                                                       XFS_DQTYPE_REC_MASK, s,
+                                               (xfs_fileoff_t)qbno, i, dqid);
+                               error++;
+                               continue;
+                       }
                        if (be32_to_cpu(dqb->dd_diskdq.d_id) != dqid) {
                                if (scicb)
                                        dbprintf(_("bad id %u for %s dqblk %lld "
index 431b06fcedfbfa2babbcf48e4dacc6a8634b2b8e..11ae9ffad393577094b502bec9501a8b682040bc 100644 (file)
@@ -37,6 +37,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
@@ -57,9 +59,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 820b0223516c9ad08a11d16943b3b69cc47265e2..bd0d933039c3aa4287ccb6ea230ffa0f550d799f 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