Blame SOURCES/xfsprogs-5.9.0-xfs-improve-ondisk-dquot-flags-checking.patch

5d5cbe
From 28518f7782310951019d6d28f2a6e9f9fc6e4a1c Mon Sep 17 00:00:00 2001
5d5cbe
From: "Darrick J. Wong" <darrick.wong@oracle.com>
5d5cbe
Date: Tue, 15 Sep 2020 15:50:35 -0400
5d5cbe
Subject: [PATCH] xfs: improve ondisk dquot flags checking
5d5cbe
5d5cbe
Source kernel commit: a990f7a84edc9941956ea3c1dfb89733c80f9ad0
5d5cbe
5d5cbe
Create an XFS_DQTYPE_ANY mask for ondisk dquots flags, and use that to
5d5cbe
ensure that we never accept any garbage flags when we're loading dquots.
5d5cbe
While we're at it, restructure the quota type flag checking to use the
5d5cbe
proper masking.
5d5cbe
5d5cbe
Note that I plan to add y2038 support soon, which will require a new
5d5cbe
xfs_dqtype_t flag for extended timestamp support, hence all the work to
5d5cbe
make the type masking work correctly.
5d5cbe
5d5cbe
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
5d5cbe
Reviewed-by: Dave Chinner <dchinner@redhat.com>
5d5cbe
Reviewed-by: Christoph Hellwig <hch@lst.de>
5d5cbe
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
5d5cbe
---
5d5cbe
5d5cbe
NOTES: I did not backport the type-vs-flags split, so some of the
5d5cbe
naming convenstions are different here.
5d5cbe
5d5cbe
diff --git a/db/check.c b/db/check.c
5d5cbe
index c3dae20..27f6639 100644
5d5cbe
--- a/db/check.c
5d5cbe
+++ b/db/check.c
5d5cbe
@@ -3452,7 +3452,7 @@ process_quota(
5d5cbe
 				error++;
5d5cbe
 				continue;
5d5cbe
 			}
5d5cbe
-			if (dqb->dd_diskdq.d_flags != exp_flags) {
5d5cbe
+			if (dqb->dd_diskdq.d_flags & ~XFS_DQTYPE_ANY) {
5d5cbe
 				if (scicb)
5d5cbe
 					dbprintf(_("bad flags %#x for %s dqblk "
5d5cbe
 						 "%lld entry %d id %u\n"),
5d5cbe
@@ -3461,6 +3461,17 @@ process_quota(
5d5cbe
 				error++;
5d5cbe
 				continue;
5d5cbe
 			}
5d5cbe
+			if ((dqb->dd_diskdq.d_flags & XFS_DQ_ALLTYPES)
5d5cbe
+								!= exp_flags) {
5d5cbe
+				if (scicb)
5d5cbe
+					dbprintf(_("wrong type %#x for %s dqblk "
5d5cbe
+						 "%lld entry %d id %u\n"),
5d5cbe
+						dqb->dd_diskdq.d_flags &
5d5cbe
+							XFS_DQ_ALLTYPES, s,
5d5cbe
+						(xfs_fileoff_t)qbno, i, dqid);
5d5cbe
+				error++;
5d5cbe
+				continue;
5d5cbe
+			}
5d5cbe
 			if (be32_to_cpu(dqb->dd_diskdq.d_id) != dqid) {
5d5cbe
 				if (scicb)
5d5cbe
 					dbprintf(_("bad id %u for %s dqblk %lld "
5d5cbe
diff --git a/libxfs/xfs_dquot_buf.c b/libxfs/xfs_dquot_buf.c
5d5cbe
index a3e8ba1..324f528 100644
5d5cbe
--- a/libxfs/xfs_dquot_buf.c
5d5cbe
+++ b/libxfs/xfs_dquot_buf.c
5d5cbe
@@ -39,6 +39,8 @@ xfs_dquot_verify(
5d5cbe
 	xfs_disk_dquot_t *ddq,
5d5cbe
 	xfs_dqid_t	 id)	  /* used only during quotacheck */
5d5cbe
 {
5d5cbe
+	__u8			ddq_type;
5d5cbe
+
5d5cbe
 	/*
5d5cbe
 	 * We can encounter an uninitialized dquot buffer for 2 reasons:
5d5cbe
 	 * 1. If we crash while deleting the quotainode(s), and those blks got
5d5cbe
@@ -59,9 +61,12 @@ xfs_dquot_verify(
5d5cbe
 	if (ddq->d_version != XFS_DQUOT_VERSION)
5d5cbe
 		return __this_address;
5d5cbe
 
5d5cbe
-	if (ddq->d_flags != XFS_DQ_USER &&
5d5cbe
-	    ddq->d_flags != XFS_DQ_PROJ &&
5d5cbe
-	    ddq->d_flags != XFS_DQ_GROUP)
5d5cbe
+	if (ddq->d_flags & ~XFS_DQTYPE_ANY)
5d5cbe
+		return __this_address;
5d5cbe
+	ddq_type = ddq->d_flags & XFS_DQ_ALLTYPES;
5d5cbe
+	if (ddq_type != XFS_DQ_USER &&
5d5cbe
+	    ddq_type != XFS_DQ_PROJ &&
5d5cbe
+	    ddq_type != XFS_DQ_GROUP)
5d5cbe
 		return __this_address;
5d5cbe
 
5d5cbe
 	if (id != -1 && id != be32_to_cpu(ddq->d_id))
5d5cbe
diff --git a/libxfs/xfs_quota_defs.h b/libxfs/xfs_quota_defs.h
5d5cbe
index afe1ea0..c69dba4 100644
5d5cbe
--- a/libxfs/xfs_quota_defs.h
5d5cbe
+++ b/libxfs/xfs_quota_defs.h
5d5cbe
@@ -31,6 +31,8 @@ typedef uint16_t	xfs_qwarncnt_t;
5d5cbe
 
5d5cbe
 #define XFS_DQ_ALLTYPES		(XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP)
5d5cbe
 
5d5cbe
+#define XFS_DQTYPE_ANY		(XFS_DQ_ALLTYPES)
5d5cbe
+
5d5cbe
 #define XFS_DQ_FLAGS \
5d5cbe
 	{ XFS_DQ_USER,		"USER" }, \
5d5cbe
 	{ XFS_DQ_PROJ,		"PROJ" }, \