All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dave Chinner <david@fromorbit.com>
To: "Darrick J. Wong" <darrick.wong@oracle.com>
Cc: xfs <linux-xfs@vger.kernel.org>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Salvatore Bonaccorso <carnil@debian.org>,
	Security Officers <security@kernel.org>,
	Debian Security Team <team@security.debian.org>,
	benjamin.moody@gmail.com, Ben Hutchings <benh@debian.org>,
	Christoph Hellwig <hch@infradead.org>
Subject: Re: [PATCH] xfs: fix missing ILOCK unlock when xfs_setattr_nonsize fails due to EDQUOT
Date: Fri, 23 Aug 2019 14:55:20 +1000	[thread overview]
Message-ID: <20190823045520.GH1119@dread.disaster.area> (raw)
In-Reply-To: <20190823035528.GH1037422@magnolia>

On Thu, Aug 22, 2019 at 08:55:28PM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Benjamin Moody reported to Debian that XFS partially wedges when a chgrp
> fails on account of being out of disk quota.  I ran his reproducer
> script:
> 
> # adduser dummy
> # adduser dummy plugdev
> 
> # dd if=/dev/zero bs=1M count=100 of=test.img
> # mkfs.xfs test.img
> # mount -t xfs -o gquota test.img /mnt
> # mkdir -p /mnt/dummy
> # chown -c dummy /mnt/dummy
> # xfs_quota -xc 'limit -g bsoft=100k bhard=100k plugdev' /mnt
> 
> (and then as user dummy)
> 
> $ dd if=/dev/urandom bs=1M count=50 of=/mnt/dummy/foo
> $ chgrp plugdev /mnt/dummy/foo
> 
> and saw:
> 
> ================================================
> WARNING: lock held when returning to user space!
> 5.3.0-rc5 #rc5 Tainted: G        W
> ------------------------------------------------
> chgrp/47006 is leaving the kernel with locks still held!
> 1 lock held by chgrp/47006:
>  #0: 000000006664ea2d (&xfs_nondir_ilock_class){++++}, at: xfs_ilock+0xd2/0x290 [xfs]
> 
> ...which is clearly caused by xfs_setattr_nonsize failing to unlock the
> ILOCK after the xfs_qm_vop_chown_reserve call fails.  Add the missing
> unlock.
> 
> Reported-by: benjamin.moody@gmail.com
> Fixes: 253f4911f297 ("xfs: better xfs_trans_alloc interface")
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/xfs_iops.c |    1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
> index dd4076ae228a..ea614b4ae052 100644
> --- a/fs/xfs/xfs_iops.c
> +++ b/fs/xfs/xfs_iops.c
> @@ -804,6 +804,7 @@ xfs_setattr_nonsize(
>  
>  out_cancel:
>  	xfs_trans_cancel(tp);
> +	xfs_iunlock(ip, XFS_ILOCK_EXCL);
>  out_dqrele:
>  	xfs_qm_dqrele(udqp);
>  	xfs_qm_dqrele(gdqp);

/me goes back an looks at 253f4911f297 ("xfs: better xfs_trans_alloc
interface")

Fmeh. The original patch posting did:

out_unlock:
 	xfs_iunlock(ip, XFS_ILOCK_EXCL);
-out_trans_cancel:
-	xfs_trans_cancel(tp);
+out_dqrele:
 	xfs_qm_dqrele(udqp);
 	xfs_qm_dqrele(gdqp);
 	return error;

Which leaked the transaction. Looks like I screwed up fixing that
up on commit - it no longer leaked the transaction, but leaked the
lock instead. And 3 and half years later someone notices it...

Oh, gawd that code is so grotty! I started saying "maybe we
should..." and then stopped when I realised just how much cleanup
needs to be done to that function...

The above patch fixes the issue, iso consider it:

Reviewed-by: Dave Chinner <dchinner@redhat.com>

-- 
Dave Chinner
david@fromorbit.com

  parent reply	other threads:[~2019-08-23  4:56 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-23  3:55 [PATCH] xfs: fix missing ILOCK unlock when xfs_setattr_nonsize fails due to EDQUOT Darrick J. Wong
2019-08-23  3:57 ` [PATCH] generic: test for failure to unlock inode after chgrp fails with EDQUOT Darrick J. Wong
2019-08-24 23:05   ` Christoph Hellwig
2019-08-23  4:55 ` Dave Chinner [this message]
2019-08-23 16:28 ` [PATCH] xfs: fix missing ILOCK unlock when xfs_setattr_nonsize fails due to EDQUOT Linus Torvalds
2019-08-23 17:15   ` Benjamin Moody
2019-08-23 19:26   ` Salvatore Bonaccorso
2019-08-24 18:22     ` Salvatore Bonaccorso
2019-08-23 19:24 ` Salvatore Bonaccorso
2019-08-24 18:44   ` Linus Torvalds
2019-08-25  3:13     ` Greg KH
2019-08-25 15:45       ` Salvatore Bonaccorso

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190823045520.GH1119@dread.disaster.area \
    --to=david@fromorbit.com \
    --cc=benh@debian.org \
    --cc=benjamin.moody@gmail.com \
    --cc=carnil@debian.org \
    --cc=darrick.wong@oracle.com \
    --cc=hch@infradead.org \
    --cc=linux-xfs@vger.kernel.org \
    --cc=security@kernel.org \
    --cc=team@security.debian.org \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.