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

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