[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAJieiUg-dSWkC2WjxWMTC-NmxhTdUVUtd5mFDbWJdGVoJpzVyg@mail.gmail.com>
Date: Mon, 17 Dec 2018 07:15:24 -0800
From: Roopa Prabhu <roopa@...ulusnetworks.com>
To: Petr Machata <petrm@...lanox.com>
Cc: netdev <netdev@...r.kernel.org>,
David Miller <davem@...emloft.net>,
Ido Schimmel <idosch@...lanox.com>
Subject: Re: [PATCH net 2/5] vxlan: Don't double-free default FDB entry in __vxlan_dev_create()
On Mon, Dec 17, 2018 at 6:58 AM Petr Machata <petrm@...lanox.com> wrote:
>
> When a failure occurs in rtnl_configure_link(), the current code
> calls unregister_netdevice() to roll back the earlier call to
> register_netdevice(), and jumps to errout, which calls
> vxlan_fdb_destroy().
>
> However unregister_netdevice() calls transitively ndo_uninit(),
> which is vxlan_uninit(), and that already takes care of deleting
> the default FDB entry by calling vxlan_fdb_delete_default().
> Since the entry added earlier in __vxlan_dev_create() is exactly
> the default entry, the cleanup code in the errout block always
> leads to double free and thus a panic.
>
> Fix by skipping the rollback code and just returning.
I trust your test case that pointed to a potential issue..., but can
we add a comment there on
why there is an fdb add but no destroy in the roll back code ?. Also,
the destroy code from uninit path does
look for an entry being present before attempting a destroy, its
unclear to me yet why that ends up doing a double free ?
>
> Fixes: 0241b836732f ("vxlan: fix default fdb entry netlink notify ordering during netdev create")
> Signed-off-by: Petr Machata <petrm@...lanox.com>
> ---
> drivers/net/vxlan.c | 15 ++++++++-------
> 1 file changed, 8 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
> index c9956c08edf5..139741617b90 100644
> --- a/drivers/net/vxlan.c
> +++ b/drivers/net/vxlan.c
> @@ -3282,14 +3282,15 @@ static int __vxlan_dev_create(struct net *net, struct net_device *dev,
> }
>
> err = register_netdevice(dev);
> - if (err)
> - goto errout;
> + if (err) {
> + if (f)
> + vxlan_fdb_destroy(vxlan, f, false);
> + return err;
> + }
>
> err = rtnl_configure_link(dev, NULL);
> - if (err) {
> - unregister_netdevice(dev);
> + if (err)
> goto errout;
> - }
>
> /* notify default fdb entry */
> if (f)
> @@ -3298,8 +3299,8 @@ static int __vxlan_dev_create(struct net *net, struct net_device *dev,
> list_add(&vxlan->next, &vn->vxlan_list);
> return 0;
> errout:
> - if (f)
> - vxlan_fdb_destroy(vxlan, f, false);
> + unregister_netdevice(dev);
> + /* the all_zeros_mac entry was deleted at vxlan_uninit */
> return err;
> }
>
> --
> 2.4.11
>
Powered by blists - more mailing lists