From: Long Li <leo.lilong@huawei.com>
To: "Darrick J. Wong" <djwong@kernel.org>
Cc: <chandanbabu@kernel.org>, <linux-xfs@vger.kernel.org>,
<david@fromorbit.com>, <yi.zhang@huawei.com>,
<houtao1@huawei.com>, <yangerkun@huawei.com>
Subject: Re: [PATCH 4/5] xfs: fix a UAF when dquot item push
Date: Sat, 24 Aug 2024 10:03:37 +0800 [thread overview]
Message-ID: <20240824015849.GA3833553@ceph-admin> (raw)
In-Reply-To: <20240823172038.GH865349@frogsfrogsfrogs>
On Fri, Aug 23, 2024 at 10:20:38AM -0700, Darrick J. Wong wrote:
> On Fri, Aug 23, 2024 at 07:04:38PM +0800, Long Li wrote:
> > If errors are encountered while pushing a dquot log item, the dquot dirty
> > flag is cleared. Without the protection of dqlock and dqflock locks, the
> > dquot reclaim thread may free the dquot. Accessing the log item in xfsaild
> > after this can trigger a UAF.
> >
> > CPU0 CPU1
> > push item reclaim dquot
> > ----------------------- -----------------------
> > xfsaild_push_item
> > xfs_qm_dquot_logitem_push(lip)
> > xfs_dqlock_nowait(dqp)
> > xfs_dqflock_nowait(dqp)
> > spin_unlock(&lip->li_ailp->ail_lock)
> > xfs_qm_dqflush(dqp, &bp)
> > <encountered some errors>
> > xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE)
> > dqp->q_flags &= ~XFS_DQFLAG_DIRTY
> > <dquot is not diry>
> > xfs_trans_ail_delete(lip, 0)
> > xfs_dqfunlock(dqp)
> > spin_lock(&lip->li_ailp->ail_lock)
> > xfs_dqunlock(dqp)
> > xfs_qm_shrink_scan
> > list_lru_shrink_walk
> > xfs_qm_dquot_isolate
> > xfs_dqlock_nowait(dqp)
> > xfs_dqfunlock(dqp)
> > //dquot is clean, not flush it
> > xfs_dqfunlock(dqp)
> > dqp->q_flags |= XFS_DQFLAG_FREEING
> > xfs_dqunlock(dqp)
> > //add dquot to dispose list
> > //free dquot in dispose list
> > xfs_qm_dqfree_one(dqp)
> > trace_xfs_ail_xxx(lip) //UAF
> >
> > Fix this by returning XFS_ITEM_UNSAFE in xfs_qm_dquot_logitem_push() when
> > dquot flush encounters errors (excluding EAGAIN error), ensuring xfsaild
> > does not access the log item after it is pushed.
> >
> > Fixes: 9e4c109ac822 ("xfs: add AIL pushing tracepoints")
> > Signed-off-by: Long Li <leo.lilong@huawei.com>
> > ---
> > fs/xfs/xfs_dquot_item.c | 10 +++++++++-
> > 1 file changed, 9 insertions(+), 1 deletion(-)
> >
> > diff --git a/fs/xfs/xfs_dquot_item.c b/fs/xfs/xfs_dquot_item.c
> > index 7d19091215b0..afc7ad91ddef 100644
> > --- a/fs/xfs/xfs_dquot_item.c
> > +++ b/fs/xfs/xfs_dquot_item.c
> > @@ -160,8 +160,16 @@ xfs_qm_dquot_logitem_push(
> > if (!xfs_buf_delwri_queue(bp, buffer_list))
> > rval = XFS_ITEM_FLUSHING;
> > xfs_buf_relse(bp);
> > - } else if (error == -EAGAIN)
> > + } else if (error == -EAGAIN) {
> > rval = XFS_ITEM_LOCKED;
> > + } else {
> > + /*
> > + * The dirty flag has been cleared; the dquot may be reclaimed
> > + * after unlock. It's unsafe to access the item after it has
> > + * been pushed.
> > + */
> > + rval = XFS_ITEM_UNSAFE;
> > + }
> >
> > spin_lock(&lip->li_ailp->ail_lock);
>
> Um, didn't we just establish that lip could have been freed? Why is it
> safe to continue accessing the AIL through the lip here?
>
> --D
>
We are still within the dqlock context here, and the dquot will only be
released after the dqlock is released. In contrast, during the inode item
push, the inode log item may be released within xfs_iflush_cluster() - this
is where the two cases differ. However, for the sake of code consistency,
should we also avoid accessing the AIL through lip here?
Thanks,
Long Li
next prev parent reply other threads:[~2024-08-24 1:54 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-08-23 11:04 [PATCH 0/5] xfs: fix and cleanups for log item push Long Li
2024-08-23 11:04 ` [PATCH 1/5] xfs: remove redundant set null for ip->i_itemp Long Li
2024-08-23 16:37 ` Darrick J. Wong
2024-08-25 4:52 ` Christoph Hellwig
2024-08-23 11:04 ` [PATCH 2/5] xfs: ensuere deleting item from AIL after shutdown in dquot flush Long Li
2024-08-23 17:00 ` Darrick J. Wong
2024-08-24 3:08 ` Long Li
2024-08-27 9:40 ` Dave Chinner
2024-08-31 13:45 ` Long Li
2024-08-23 11:04 ` [PATCH 3/5] xfs: add XFS_ITEM_UNSAFE for log item push return result Long Li
2024-08-23 17:17 ` Darrick J. Wong
2024-08-24 3:30 ` Long Li
2024-08-27 9:44 ` Dave Chinner
2024-08-24 3:34 ` Christoph Hellwig
2024-08-27 9:41 ` Long Li
2024-08-27 10:00 ` Dave Chinner
2024-08-27 12:30 ` Christoph Hellwig
2024-08-27 21:52 ` Dave Chinner
2024-08-28 4:23 ` Christoph Hellwig
2024-08-29 10:16 ` Dave Chinner
2024-08-23 11:04 ` [PATCH 4/5] xfs: fix a UAF when dquot item push Long Li
2024-08-23 17:20 ` Darrick J. Wong
2024-08-24 2:03 ` Long Li [this message]
2024-08-23 11:04 ` [PATCH 5/5] xfs: fix a UAF when inode " Long Li
2024-08-23 17:22 ` Darrick J. Wong
2024-08-27 8:14 ` Long Li
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=20240824015849.GA3833553@ceph-admin \
--to=leo.lilong@huawei.com \
--cc=chandanbabu@kernel.org \
--cc=david@fromorbit.com \
--cc=djwong@kernel.org \
--cc=houtao1@huawei.com \
--cc=linux-xfs@vger.kernel.org \
--cc=yangerkun@huawei.com \
--cc=yi.zhang@huawei.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox