From: Jeff Layton <jlayton@kernel.org>
To: NeilBrown <neilb@suse.de>
Cc: chuck.lever@oracle.com, linux-nfs@vger.kernel.org
Subject: Re: [PATCH] nfsd: fix potential race in nfs4_find_file
Date: Fri, 06 Jan 2023 07:19:03 -0500 [thread overview]
Message-ID: <be0ef41fc2d62fb11d731754833d68e424a422ee.camel@kernel.org> (raw)
In-Reply-To: <167295993121.13974.8791979932693514625@noble.neil.brown.name>
On Fri, 2023-01-06 at 10:05 +1100, NeilBrown wrote:
> On Thu, 05 Jan 2023, Jeff Layton wrote:
> > Even though there is a WARN_ON_ONCE check, it seems possible for
> > nfs4_find_file to race with the destruction of an fi_deleg_file while
> > trying to take a reference to it.
> >
> > put_deleg_file is done while holding the fi_lock. Take and hold it
> > when dealing with the fi_deleg_file in nfs4_find_file.
> >
> > Signed-off-by: Jeff Layton <jlayton@kernel.org>
> > ---
> > fs/nfsd/nfs4state.c | 16 ++++++++++------
> > 1 file changed, 10 insertions(+), 6 deletions(-)
> >
> > diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
> > index b68238024e49..3df3ae84bd07 100644
> > --- a/fs/nfsd/nfs4state.c
> > +++ b/fs/nfsd/nfs4state.c
> > @@ -6417,23 +6417,27 @@ nfsd4_lookup_stateid(struct nfsd4_compound_state *cstate,
> > static struct nfsd_file *
> > nfs4_find_file(struct nfs4_stid *s, int flags)
> > {
> > + struct nfsd_file *ret = NULL;
> > +
> > if (!s)
> > return NULL;
> >
> > switch (s->sc_type) {
> > case NFS4_DELEG_STID:
> > - if (WARN_ON_ONCE(!s->sc_file->fi_deleg_file))
> > - return NULL;
> > - return nfsd_file_get(s->sc_file->fi_deleg_file);
> > + spin_lock(&s->sc_file->fi_lock);
> > + if (!WARN_ON_ONCE(!s->sc_file->fi_deleg_file))
> > + ret = nfsd_file_get(s->sc_file->fi_deleg_file);
> > + spin_unlock(&s->sc_file->fi_lock);
> > + break;
>
> As an nfsd_file is freed with rcu, we don't need the spinlock.
>
> rcu_read_lock()
> ret = rcu_dereference(s->sc_file->fi_deleg_file);
> if (ret)
> ret = nfsd_file_get(ret);
> rcu_read_unlock();
>
> You could even put the NULL test in nfsd_file_get() and have:
>
> rcu_read_lock()l;
> ret = nfsd_file_get(rcu_dereference(s->sc_file->fi_deleg_file));
> rcu_read_unlock();
>
> but that might not be a win.
>
> I agree with Chuck that the WARNing isn't helpful.
>
> NeilBrown
>
Ok, I took a look at this.
To do it right, we'd need to annotate the fi_deleg_file field with
__rcu. That means we'd need to clean up a bunch of existing
fi_deleg_file accesses to properly use rcu_dereference_protected.
This is probably worthwhile stuff to do, but it's a larger patch series
and will touch a bunch of unrelated delegation handling. At this point,
I think I'd rather just keep the spinlocking here since that should be
safe. Cleaning up delegation handling is a longer-term project that I'd
rather table for now.
I will remove the WARN_ON_ONCE though, and I think allowing
nfsd_file_get to accept a NULL pointer is probably a good thing too.
I'll resend a new series in a bit.
>
> > case NFS4_OPEN_STID:
> > case NFS4_LOCK_STID:
> > if (flags & RD_STATE)
> > - return find_readable_file(s->sc_file);
> > + ret = find_readable_file(s->sc_file);
> > else
> > - return find_writeable_file(s->sc_file);
> > + ret = find_writeable_file(s->sc_file);
> > }
> >
> > - return NULL;
> > + return ret;
> > }
> >
> > static __be32
> > --
> > 2.39.0
> >
> >
--
Jeff Layton <jlayton@kernel.org>
next prev parent reply other threads:[~2023-01-06 12:19 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-01-05 12:18 [PATCH] nfsd: fix potential race in nfs4_find_file Jeff Layton
2023-01-05 14:46 ` Chuck Lever III
2023-01-05 20:43 ` Jeff Layton
2023-01-05 21:36 ` Chuck Lever III
2023-01-05 23:05 ` NeilBrown
2023-01-06 11:58 ` Jeff Layton
2023-01-06 12:19 ` Jeff Layton [this message]
2023-01-07 10:39 ` NeilBrown
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=be0ef41fc2d62fb11d731754833d68e424a422ee.camel@kernel.org \
--to=jlayton@kernel.org \
--cc=chuck.lever@oracle.com \
--cc=linux-nfs@vger.kernel.org \
--cc=neilb@suse.de \
/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.