From: Guillaume Nault <gnault@redhat.com>
To: Tom Parkin <tparkin@katalix.com>
Cc: netdev@vger.kernel.org, jchapman@katalix.com
Subject: Re: [PATCH v2 net-next 1/2] ppp: add PPPIOCBRIDGECHAN and PPPIOCUNBRIDGECHAN ioctls
Date: Thu, 3 Dec 2020 19:01:56 +0100 [thread overview]
Message-ID: <20201203180156.GA2735@linux.home> (raw)
In-Reply-To: <20201203115717.GA12568@katalix.com>
On Thu, Dec 03, 2020 at 11:57:18AM +0000, Tom Parkin wrote:
> On Thu, Dec 03, 2020 at 01:23:18 +0100, Guillaume Nault wrote:
> > On Tue, Dec 01, 2020 at 11:52:49AM +0000, Tom Parkin wrote:
> > > + if (!pchb) {
> > > + write_unlock_bh(&pch->upl);
> > > + return -EINVAL;
> >
> > I'm not sure I'd consider this case as an error.
>
> To be honest I'd probably tend agree with you, but I was seeking to
> maintain consistency with how PPPIOCCONNECT/PPPIOCDISCONN behave. The
> latter returns EINVAL if the channel isn't connected to an interface.
Indeed, that makes sense. I didn't think about that. I was mostly
thinking about the case where ->bridge was concurently reset by another
ppp_unbridge_channels(), which doesn't look like an error to me. But
we can let userspace responsible for properly using the API (or
ignoring EINVAL when they don't).
> If you feel strongly I'm happy to change it but IMO it's better to be
> consistent with existing ioctl calls.
I don't feel strongly about it :).
> > If there's no bridged channel, there's just nothing to do.
> > Furthermore, there might be situations where this is not really an
> > error (see the possible race below).
> >
> > > + }
> > > + RCU_INIT_POINTER(pch->bridge, NULL);
> > > + write_unlock_bh(&pch->upl);
> > > +
> > > + write_lock_bh(&pchb->upl);
> > > + RCU_INIT_POINTER(pchb->bridge, NULL);
> > > + write_unlock_bh(&pchb->upl);
> > > +
> > > + synchronize_rcu();
> > > +
> > > + if (refcount_dec_and_test(&pch->file.refcnt))
> > > + ppp_destroy_channel(pch);
> >
> > I think that we could have a situation where pchb->bridge could be
> > different from pch.
> > If ppp_unbridge_channels() was also called concurrently on pchb, then
> > pchb->bridge might have been already reset. And it might have dropped
> > the reference it had on pch. In this case, we'd erroneously decrement
> > the refcnt again.
> >
> > In theory, pchb->bridge might even have been reassigned to a different
> > channel. So we'd reset pchb->bridge, but without decrementing the
> > refcnt of the channel it pointed to (and again, we'd erroneously
> > decrement pch's refcount instead).
> >
> > So I think we need to save pchb->bridge to a local variable while we
> > hold pchb->upl, and then drop the refcount of that channel, instead of
> > assuming that it's equal to pch.
>
> Ack, yes.
>
> The v1 series protected against this, although by nesting locks :-|
Well, I think the v1 could deadlock in this situation. The RFC was
immune to this problem, as it didn't modify ->bridge on pchb.
> I think in the case that pchb->bridge != pch, we probably want to
> leave pchb alone, so:
>
> 1. Don't unset the pchb->bridge pointer
> 2. Don't drop the pch reference (pchb doesn't hold a reference on pch
> because pchb->bridge != pch)
>
> This is on the assumption that pchb has been reassigned -- in that
> scenario we don't want to mess with pchb at all since it'll break the
> other bridge instance.
Yes you're right.
Thanks!
next prev parent reply other threads:[~2020-12-03 18:03 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-12-01 11:52 [PATCH v2 net-next 0/2] add ppp_generic ioctl(s) to bridge channels Tom Parkin
2020-12-01 11:52 ` [PATCH v2 net-next 1/2] ppp: add PPPIOCBRIDGECHAN and PPPIOCUNBRIDGECHAN ioctls Tom Parkin
2020-12-03 0:23 ` Guillaume Nault
2020-12-03 11:57 ` Tom Parkin
2020-12-03 18:01 ` Guillaume Nault [this message]
2020-12-01 11:52 ` [PATCH v2 net-next 2/2] docs: update ppp_generic.rst to document new ioctls Tom Parkin
2020-12-02 10:34 ` [PATCH v2 net-next 0/2] add ppp_generic ioctl(s) to bridge channels James Chapman
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=20201203180156.GA2735@linux.home \
--to=gnault@redhat.com \
--cc=jchapman@katalix.com \
--cc=netdev@vger.kernel.org \
--cc=tparkin@katalix.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;
as well as URLs for NNTP newsgroup(s).