xfs_quota: handle wrapped id from GETNEXTQUOTA
diff mbox

Message ID ce6f019b-e851-eef0-17aa-b98e3a563de4@sandeen.net
State Accepted
Headers show

Commit Message

Eric Sandeen Dec. 17, 2016, 12:13 a.m. UTC
The GETNEXTQUOTA interface in the kernel had a bug
(at least in xfs) where if we pass in UINT_MAX as the
ID, it incremented, warpped, and returned 0 for the next
id.  This would cause userspace to start querying
again at zero, and an xfs_quota "report" command would
loop forever.  This occurred if a quota ID near
UINT max existed, and later offsets within the block
wrapped the xfs_dqid_t.

This will also be fixed in the kernel, but we should also
catch this in userspace, and stop the loop if it happens.

Signed-off-by: Eric Sandeen <sandeen@redhat.com>
---


--
To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Christoph Hellwig Dec. 19, 2016, 10:26 a.m. UTC | #1
On Fri, Dec 16, 2016 at 06:13:53PM -0600, Eric Sandeen wrote:
> The GETNEXTQUOTA interface in the kernel had a bug
> (at least in xfs) where if we pass in UINT_MAX as the
> ID, it incremented, warpped, and returned 0 for the next
> id.  This would cause userspace to start querying
> again at zero, and an xfs_quota "report" command would
> loop forever.  This occurred if a quota ID near
> UINT max existed, and later offsets within the block
> wrapped the xfs_dqid_t.
> 
> This will also be fixed in the kernel, but we should also
> catch this in userspace, and stop the loop if it happens.
> 
> Signed-off-by: Eric Sandeen <sandeen@redhat.com>

Looks fine,

Reviewed-by: Christoph Hellwig <hch@lst.de>
--
To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch
diff mbox

diff --git a/quota/report.c b/quota/report.c
index 604f50d..bcf4a15 100644
--- a/quota/report.c
+++ b/quota/report.c
@@ -101,6 +101,10 @@  dump_file(
 	if (oid)
 		*oid = d.d_id;
 
+	/* Did kernelspace wrap? */
+	if (*oid < id)
+		return 0;
+
 	if (!d.d_blk_softlimit && !d.d_blk_hardlimit &&
 	    !d.d_ino_softlimit && !d.d_ino_hardlimit &&
 	    !d.d_rtb_softlimit && !d.d_rtb_hardlimit)
@@ -360,6 +360,10 @@  report_mount(
 	if (oid)
 		*oid = d.d_id;
 
+	/* Did kernelspace wrap? */
+	if (*oid < id)
+		return 0;
+
 	if (flags & TERSE_FLAG) {
 		count = 0;
 		if ((form & XFS_BLOCK_QUOTA) && d.d_bcount)