From: Guillaume Nault <gnault@redhat.com>
To: Mirsad Goran Todorovac <mirsad.todorovac@alu.unizg.hr>
Cc: netdev@vger.kernel.org, "David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Shuah Khan <shuah@kernel.org>,
linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org
Subject: Re: POSSIBLE BUG: selftests/net/fcnal-test.sh: [FAIL] in vrf "bind - ns-B IPv6 LLA" test
Date: Tue, 6 Jun 2023 21:27:36 +0200 [thread overview]
Message-ID: <ZH+IqBNan5nAFMZZ@debian> (raw)
In-Reply-To: <174c6928-3498-8fb0-9f83-b01fa346a221@alu.unizg.hr>
On Tue, Jun 06, 2023 at 09:17:24PM +0200, Mirsad Goran Todorovac wrote:
> On 6/6/23 20:50, Guillaume Nault wrote:
> > On Tue, Jun 06, 2023 at 04:28:02PM +0200, Mirsad Todorovac wrote:
> > > On 6/6/23 16:11, Guillaume Nault wrote:
> > > > On Tue, Jun 06, 2023 at 03:57:35PM +0200, Mirsad Todorovac wrote:
> > > > > + if (oif) {
> > > > > + rcu_read_lock();
> > > > > + dev = dev_get_by_index_rcu(net, oif);
> > > > > + rcu_read_unlock();
> > > >
> > > > You can't assume '*dev' is still valid after rcu_read_unlock() unless
> > > > you hold a reference on it.
> > > >
> > > > > + rtnl_lock();
> > > > > + mdev = netdev_master_upper_dev_get(dev);
> > > > > + rtnl_unlock();
> > > >
> > > > Because of that, 'dev' might have already disappeared at the time
> > > > netdev_master_upper_dev_get() is called. So it may dereference an
> > > > invalid pointer here.
> > >
> > > Good point, thanks. I didn't expect those to change.
> > >
> > > This can be fixed, provided that RCU and RTNL locks can be nested:
> >
> > Well, yes and no. You can call rcu_read_{lock,unlock}() while under the
> > rtnl protection, but not the other way around.
> >
> > > rcu_read_lock();
> > > if (oif) {
> > > dev = dev_get_by_index_rcu(net, oif);
> > > rtnl_lock();
> > > mdev = netdev_master_upper_dev_get(dev);
> > > rtnl_unlock();
> > > }
> >
> > This is invalid: rtnl_lock() uses a mutex, so it can sleep and that's
> > forbidden inside an RCU critical section.
>
> Obviously, that's bad. Mea culpa.
>
> > > if (sk->sk_bound_dev_if) {
> > > bdev = dev_get_by_index_rcu(net, sk->sk_bound_dev_if);
> > > }
> > >
> > > addr_type = ipv6_addr_type(daddr);
> > > if ((__ipv6_addr_needs_scope_id(addr_type) && !oif) ||
> > > (addr_type & IPV6_ADDR_MAPPED) ||
> > > (oif && sk->sk_bound_dev_if && oif != sk->sk_bound_dev_if &&
> > > !(mdev && sk->sk_bound_dev_if && bdev && mdev == bdev))) {
> > > rcu_read_unlock();
> > > return -EINVAL;
> > > }
> > > rcu_read_unlock();
> > >
> > > But again this is still probably not race-free (bdev might also disappear before
> > > the mdev == bdev test), even if it passed fcnal-test.sh, there is much duplication
> > > of code, so your one-line solution is obviously by far better. :-)
> >
> > The real problem is choosing the right function for getting the master
> > device. In particular netdev_master_upper_dev_get() was a bad choice.
> > It forces you to take the rtnl, which is unnatural here and obliges you
> > to add extra code, while all this shouldn't be necessary in the first
> > place.
>
> Thank you for the additional insight. I had poor luck with Googling on
> these.
>
> I made a blunder after blunder. But it was insightful and brainstorming.
> Good exercise for my little grey cells.
>
> However, learning without making any errors appears to be simply a lot
> of blunt memorising. :-/
>
> It's good to be in an environment when one can learn from errors.
>
> :-)
I'm happy you found this useful.
> Regards,
> Mirsad
>
next prev parent reply other threads:[~2023-06-06 19:28 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-05-24 12:17 POSSIBLE BUG: selftests/net/fcnal-test.sh: [FAIL] in vrf "bind - ns-B IPv6 LLA" test Mirsad Todorovac
2023-05-31 18:11 ` Guillaume Nault
2023-06-02 12:35 ` Mirsad Goran Todorovac
2023-06-06 6:24 ` Mirsad Goran Todorovac
2023-06-06 13:46 ` Guillaume Nault
2023-06-06 13:57 ` Mirsad Todorovac
2023-06-06 14:11 ` Guillaume Nault
2023-06-06 14:28 ` Mirsad Todorovac
2023-06-06 18:50 ` Guillaume Nault
2023-06-06 19:17 ` Mirsad Goran Todorovac
2023-06-06 19:27 ` Guillaume Nault [this message]
2023-06-06 18:07 ` POSSIBLE BUG: selftests/net/fcnal-test.sh: [FAIL][FIX TESTED] " Mirsad Goran Todorovac
2023-06-06 18:57 ` Guillaume Nault
2023-06-06 22:04 ` Mirsad Goran Todorovac
2023-06-07 16:51 ` Guillaume Nault
2023-06-08 5:37 ` Mirsad Goran Todorovac
2023-06-09 16:13 ` Guillaume Nault
2023-06-10 18:04 ` Mirsad Goran Todorovac
2023-06-14 8:47 ` Guillaume Nault
2023-06-15 20:10 ` Mirsad Goran Todorovac
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=ZH+IqBNan5nAFMZZ@debian \
--to=gnault@redhat.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=mirsad.todorovac@alu.unizg.hr \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=shuah@kernel.org \
/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.