public inbox for linux-nfs@vger.kernel.org
 help / color / mirror / Atom feed
From: Jeff Layton <jlayton@kernel.org>
To: Li Lingfeng <lilingfeng3@huawei.com>,
	chuck.lever@oracle.com, neilb@suse.de, 	okorniev@redhat.com,
	Dai.Ngo@oracle.com, tom@talpey.com
Cc: linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org,
	 yukuai1@huaweicloud.com, houtao1@huawei.com,
	yi.zhang@huawei.com,  yangerkun@huawei.com,
	lilingfeng@huaweicloud.com
Subject: Re: [PATCH] nfsd: free nfsd_file by gc after adding it to lru list
Date: Tue, 14 Jan 2025 14:39:44 -0500	[thread overview]
Message-ID: <a32d4eefe27757de6ad8761e8de740e8d0968561.camel@kernel.org> (raw)
In-Reply-To: <8864761c99553a7f18adc13e98b4ef6255da1d9e.camel@kernel.org>

On Tue, 2025-01-14 at 14:27 -0500, Jeff Layton wrote:
> On Mon, 2025-01-13 at 10:59 +0800, Li Lingfeng wrote:
> > In nfsd_file_put, after inserting the nfsd_file into the nfsd_file_lru
> > list, gc may be triggered in another thread and immediately release this
> > nfsd_file, which will lead to a UAF when accessing this nfsd_file again.
> > 
> > All the places where unhash is done will also perform lru_remove, so there
> > is no need to do lru_remove separately here. After inserting the nfsd_file
> > into the nfsd_file_lru list, it can be released by relying on gc.
> > 
> > Fixes: 4a0e73e635e3 ("NFSD: Leave open files out of the filecache LRU")
> > Signed-off-by: Li Lingfeng <lilingfeng3@huawei.com>
> > ---
> >  fs/nfsd/filecache.c | 12 ++----------
> >  1 file changed, 2 insertions(+), 10 deletions(-)
> > 
> > diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c
> > index a1cdba42c4fa..37b65cb1579a 100644
> > --- a/fs/nfsd/filecache.c
> > +++ b/fs/nfsd/filecache.c
> > @@ -372,18 +372,10 @@ nfsd_file_put(struct nfsd_file *nf)
> >  		/* Try to add it to the LRU.  If that fails, decrement. */
> >  		if (nfsd_file_lru_add(nf)) {
> >  			/* If it's still hashed, we're done */
> > -			if (test_bit(NFSD_FILE_HASHED, &nf->nf_flags)) {
> > +			if (list_lru_count(&nfsd_file_lru))
> >  				nfsd_file_schedule_laundrette();
> > -				return;
> > -			}
> >  
> > -			/*
> > -			 * We're racing with unhashing, so try to remove it from
> > -			 * the LRU. If removal fails, then someone else already
> > -			 * has our reference.
> > -			 */
> > -			if (!nfsd_file_lru_remove(nf))
> > -				return;
> > +			return;
> >  		}
> >  	}
> >  	if (refcount_dec_and_test(&nf->nf_ref))
> 
> I think this looks OK. Filecache bugs are particularly nasty though, so
> let's run this through a nice long testing cycle.
> 
> Reviewed-by: Jeff Layton <jlayton@kernel.org>

Actually, I take it back. This is problematic in another way.

In this case, we're racing with another task that is unhashing the
object, but we've put it on the LRU ourselves. What guarantee do we
have that the unhashing and removal from the LRU didn't occur before
this task called nfsd_file_lru_add()? That's why we attempt to remove
it here -- we can't rely on the task that unhashed it to do so at that
point.

What might be best is to take and hold the rcu_read_lock() before doing
the nfsd_file_lru_add, and just release it after we do these racy
checks. That should make it safe to access the object.

Thoughts?
-- 
Jeff Layton <jlayton@kernel.org>

  reply	other threads:[~2025-01-14 19:39 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-01-13  2:59 [PATCH] nfsd: free nfsd_file by gc after adding it to lru list Li Lingfeng
2025-01-13 14:07 ` Chuck Lever
2025-01-14  1:54   ` Li Lingfeng
2025-01-14 19:17     ` Chuck Lever
2025-01-14 19:27 ` Jeff Layton
2025-01-14 19:39   ` Jeff Layton [this message]
2025-01-15 15:03     ` Chuck Lever
2025-01-15 15:27       ` Jeff Layton
2025-01-22  1:33         ` Li Lingfeng
2025-01-21 20:50       ` Jeff Layton
2025-01-22  1:15         ` NeilBrown
2025-01-22  1:43           ` Li Lingfeng
2025-01-22  2:21             ` Li Lingfeng
2025-01-22  3:48           ` NeilBrown
2025-01-22  7:31             ` Li Lingfeng
2025-01-22 12:31             ` Jeff Layton
2025-01-14 19:40 ` cel

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=a32d4eefe27757de6ad8761e8de740e8d0968561.camel@kernel.org \
    --to=jlayton@kernel.org \
    --cc=Dai.Ngo@oracle.com \
    --cc=chuck.lever@oracle.com \
    --cc=houtao1@huawei.com \
    --cc=lilingfeng3@huawei.com \
    --cc=lilingfeng@huaweicloud.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-nfs@vger.kernel.org \
    --cc=neilb@suse.de \
    --cc=okorniev@redhat.com \
    --cc=tom@talpey.com \
    --cc=yangerkun@huawei.com \
    --cc=yi.zhang@huawei.com \
    --cc=yukuai1@huaweicloud.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