From: Jeff Layton <jlayton@redhat.com>
To: Vasily Averin <vvs@virtuozzo.com>,
linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org
Cc: "J. Bruce Fields" <bfields@fieldses.org>,
Scott Mayhew <smayhew@redhat.com>
Subject: Re: [PATCH 1/2] NFSD: notifiers registration cleanup
Date: Wed, 21 Sep 2016 09:20:10 -0400 [thread overview]
Message-ID: <1474464010.32518.3.camel@redhat.com> (raw)
In-Reply-To: <6bce434f-4798-42bf-8d4f-e1f33ceb8ad6@virtuozzo.com>
On Wed, 2016-09-21 at 15:33 +0300, Vasily Averin wrote:
> By design notifier can be registered once only,
> however nfsd registers the same inetaddr notifiers per net-namespace.
> When this happen it corrupts list of notifiers,
> as result some notifiers can be not called on proper event,
> traverse on list can be cycled forever,
> and second unregister can access already freed memory.
>
> fixes: 36684996 ("nfsd: Register callbacks on the inetaddr_chain and inet6addr_chain")
> > Signed-off-by: Vasily Averin <vvs@virtuozzo.com>
> ---
> fs/nfsd/nfssvc.c | 17 +++++++++++++----
> 1 file changed, 13 insertions(+), 4 deletions(-)
>
> diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
> index 45007ac..7f8914f 100644
> --- a/fs/nfsd/nfssvc.c
> +++ b/fs/nfsd/nfssvc.c
> @@ -366,14 +366,20 @@ static struct notifier_block nfsd_inet6addr_notifier = {
> };
> #endif
>
> +static atomic_t nfsd_notifier_refcount = ATOMIC_INIT(0);
> +
> static void nfsd_last_thread(struct svc_serv *serv, struct net *net)
> {
> > struct nfsd_net *nn = net_generic(net, nfsd_net_id);
>
> > - unregister_inetaddr_notifier(&nfsd_inetaddr_notifier);
> > + /* check if the notifier still has clients */
> > + if (atomic_dec_return(&nfsd_notifier_refcount) == 0) {
> > + unregister_inetaddr_notifier(&nfsd_inetaddr_notifier);
> #if IS_ENABLED(CONFIG_IPV6)
> > - unregister_inet6addr_notifier(&nfsd_inet6addr_notifier);
> > + unregister_inet6addr_notifier(&nfsd_inet6addr_notifier);
> #endif
> > + }
> +
> > /*
> > * write_ports can create the server without actually starting
> > * any threads--if we get shut down before any threads are
> @@ -488,10 +494,13 @@ int nfsd_create_serv(struct net *net)
> > }
>
> > set_max_drc();
> > - register_inetaddr_notifier(&nfsd_inetaddr_notifier);
> > + /* check if the notifier is already set */
> > + if (atomic_inc_return(&nfsd_notifier_refcount) == 1) {
> > + register_inetaddr_notifier(&nfsd_inetaddr_notifier);
> #if IS_ENABLED(CONFIG_IPV6)
> > - register_inet6addr_notifier(&nfsd_inet6addr_notifier);
> > + register_inet6addr_notifier(&nfsd_inet6addr_notifier);
> #endif
> > + }
> > > do_gettimeofday(&nn->nfssvc_boot); /* record boot time */
> > return 0;
> }
Good catch. I'm not very fond of the refcounting this here but it
should
serve the purpose and I don't have anything better to suggest. FWIW, I
think the nfsd_mutex is held during all of these operations so we
probably don't need atomics for the refcount.
--
Jeff Layton <jlayton@redhat.com>
next prev parent reply other threads:[~2016-09-21 13:20 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-09-21 12:33 [PATCH 1/2] NFSD: notifiers registration cleanup Vasily Averin
2016-09-21 13:20 ` Jeff Layton [this message]
2016-09-22 8:35 ` Vasily Averin
2016-09-22 16:15 ` J. Bruce Fields
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=1474464010.32518.3.camel@redhat.com \
--to=jlayton@redhat.com \
--cc=bfields@fieldses.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-nfs@vger.kernel.org \
--cc=smayhew@redhat.com \
--cc=vvs@virtuozzo.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 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.