From: Eric Dumazet <eric.dumazet@gmail.com>
To: David Ahern <dsahern@gmail.com>,
Eric Dumazet <eric.dumazet@gmail.com>,
David Ahern <dsahern@kernel.org>,
davem@davemloft.net, jakub.kicinski@netronome.com
Cc: netdev@vger.kernel.org
Subject: Re: [PATCH net] ipv6: Handle race in addrconf_dad_work
Date: Mon, 30 Sep 2019 19:40:37 -0700 [thread overview]
Message-ID: <8a53dcff-729f-aaea-b136-ff997cf43e08@gmail.com> (raw)
In-Reply-To: <57eab627-8cc5-4834-a865-1970a290821a@gmail.com>
On 9/30/19 7:23 PM, David Ahern wrote:
> On 9/30/19 8:01 PM, Eric Dumazet wrote:
>>
>>
>> Do we need to keep the test on IF_READY done later in this function ?
>>
>> If IF_READY can disappear only under RTNL, we might clean this.
>>
>> (unless addrconf_dad_work() releases rtnl and reacquires it)
>
> Unless I am missing something none of the functions called by dad_work
> release the rtnl, but your comment did have me second guessing the locking.
>
> The interesting cases for changing the idev flag are addrconf_notify
> (NETDEV_UP and NETDEV_CHANGE) and addrconf_ifdown (reset the flag). The
> former does not have the idev lock - only rtnl. The latter has both.
> Checking the flag is inconsistent with respect to locks.
>
> As for your suggestion, the 'dead' flag is set only under rtnl in
> addrconf_ifdown and it means the device is getting removed (or IPv6 is
> disabled). Based on that I think the existing:
>
> if (idev->dead || !(idev->if_flags & IF_READY))
> goto out;
>
> can be moved to right after the rtnl_lock in addrconf_dad_work in place
> of the above change, so the end result is:
>
>
> diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
> index 6a576ff92c39..dd3be06d5a06 100644
> --- a/net/ipv6/addrconf.c
> +++ b/net/ipv6/addrconf.c
> @@ -4032,6 +4032,12 @@ static void addrconf_dad_work(struct work_struct *w)
>
> rtnl_lock();
>
> + /* check if device was taken down before this delayed work
> + * function could be canceled
> + */
> + if (idev->dead || !(idev->if_flags & IF_READY))
> + goto out;
> +
> spin_lock_bh(&ifp->lock);
> if (ifp->state == INET6_IFADDR_STATE_PREDAD) {
> action = DAD_BEGIN;
> @@ -4077,11 +4083,6 @@ static void addrconf_dad_work(struct work_struct *w)
> goto out;
>
> write_lock_bh(&idev->lock);
> - if (idev->dead || !(idev->if_flags & IF_READY)) {
> - write_unlock_bh(&idev->lock);
> - goto out;
> - }
> -
> spin_lock(&ifp->lock);
> if (ifp->state == INET6_IFADDR_STATE_DEAD) {
> spin_unlock(&ifp->lock);
>
>
> agree?
>
SGTM, thanks !
prev parent reply other threads:[~2019-10-01 2:40 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-10-01 1:37 [PATCH net] ipv6: Handle race in addrconf_dad_work David Ahern
2019-10-01 2:01 ` Eric Dumazet
2019-10-01 2:23 ` David Ahern
2019-10-01 2:40 ` Eric Dumazet [this message]
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=8a53dcff-729f-aaea-b136-ff997cf43e08@gmail.com \
--to=eric.dumazet@gmail.com \
--cc=davem@davemloft.net \
--cc=dsahern@gmail.com \
--cc=dsahern@kernel.org \
--cc=jakub.kicinski@netronome.com \
--cc=netdev@vger.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.