hsr: fix a memory leak in hsr_del_port()
authorCong Wang <xiyou.wangcong@gmail.com>
Thu, 4 Jul 2019 00:21:12 +0000 (17:21 -0700)
committerDavid S. Miller <davem@davemloft.net>
Fri, 5 Jul 2019 22:22:27 +0000 (15:22 -0700)
hsr_del_port() should release all the resources allocated
in hsr_add_port().

As a consequence of this change, hsr_for_each_port() is no
longer safe to work with hsr_del_port(), switch to
list_for_each_entry_safe() as we always hold RTNL lock.

Cc: Arvid Brodin <arvid.brodin@alten.se>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/hsr/hsr_device.c
net/hsr/hsr_slave.c

index 15c7206..f48b6a2 100644 (file)
@@ -351,13 +351,14 @@ static void hsr_dev_destroy(struct net_device *hsr_dev)
 {
        struct hsr_priv *hsr;
        struct hsr_port *port;
+       struct hsr_port *tmp;
 
        hsr = netdev_priv(hsr_dev);
 
        hsr_debugfs_term(hsr);
 
        rtnl_lock();
-       hsr_for_each_port(hsr, port)
+       list_for_each_entry_safe(port, tmp, &hsr->ports, port_list)
                hsr_del_port(port);
        rtnl_unlock();
 
@@ -428,6 +429,7 @@ int hsr_dev_finalize(struct net_device *hsr_dev, struct net_device *slave[2],
 {
        struct hsr_priv *hsr;
        struct hsr_port *port;
+       struct hsr_port *tmp;
        int res;
 
        hsr = netdev_priv(hsr_dev);
@@ -492,7 +494,7 @@ int hsr_dev_finalize(struct net_device *hsr_dev, struct net_device *slave[2],
        return 0;
 
 fail:
-       hsr_for_each_port(hsr, port)
+       list_for_each_entry_safe(port, tmp, &hsr->ports, port_list)
                hsr_del_port(port);
 err_add_port:
        hsr_del_node(&hsr->self_node_db);
index 88b6705..ee56129 100644 (file)
@@ -193,4 +193,5 @@ void hsr_del_port(struct hsr_port *port)
 
        if (port != master)
                dev_put(port->dev);
+       kfree(port);
 }