]> git.hungrycats.org Git - linux/commitdiff
macvlan: Fix one possible double free
authorGao Feng <gfree.wind@vip.163.com>
Tue, 26 Dec 2017 13:44:32 +0000 (21:44 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 3 Mar 2018 09:23:26 +0000 (10:23 +0100)
[ Upstream commit d02fd6e7d2933ede6478a15f9e4ce8a93845824e ]

Because the macvlan_uninit would free the macvlan port, so there is one
double free case in macvlan_common_newlink. When the macvlan port is just
created, then register_netdevice or netdev_upper_dev_link failed and they
would invoke macvlan_uninit. Then it would reach the macvlan_port_destroy
which triggers the double free.

Signed-off-by: Gao Feng <gfree.wind@vip.163.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/net/macvlan.c

index 6d55049cd3dcb1c9cf4a2031d50dd6bb4278f178..e8ad4d060da736ea86b1218c232a36d1554c9ef5 100644 (file)
@@ -1377,9 +1377,14 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
        return 0;
 
 unregister_netdev:
+       /* macvlan_uninit would free the macvlan port */
        unregister_netdevice(dev);
+       return err;
 destroy_macvlan_port:
-       if (create)
+       /* the macvlan port may be freed by macvlan_uninit when fail to register.
+        * so we destroy the macvlan port only when it's valid.
+        */
+       if (create && macvlan_port_get_rtnl(dev))
                macvlan_port_destroy(port->dev);
        return err;
 }