From 05529c703db3d7a2a1c4a6a09b4f4eb6b0db513b Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Sat, 31 Dec 2011 13:26:46 +0000 Subject: [PATCH] bonding: fix error handling if slave is busy (v2) MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit commit f7d9821a6a9c83450ac35e76d3709e32fd38b76f upstream. If slave device already has a receive handler registered, then the error unwind of bonding device enslave function is broken. The following will leave a pointer to freed memory in the slave device list, causing a later kernel panic. # modprobe dummy # ip li add dummy0-1 link dummy0 type macvlan # modprobe bonding # echo +dummy0 >/sys/class/net/bond0/bonding/slaves The fix is to detach the slave (which removes it from the list) in the unwind path. Signed-off-by: Stephen Hemminger Reviewed-by: Nicolas de Pesloüan Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/bonding/bond_main.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index de3d351ccb6b..ba0e065a63ce 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1839,7 +1839,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) "but new slave device does not support netpoll.\n", bond_dev->name); res = -EBUSY; - goto err_close; + goto err_detach; } } #endif @@ -1848,7 +1848,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) res = bond_create_slave_symlinks(bond_dev, slave_dev); if (res) - goto err_close; + goto err_detach; res = netdev_rx_handler_register(slave_dev, bond_handle_frame, new_slave); @@ -1869,6 +1869,11 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) err_dest_symlinks: bond_destroy_slave_symlinks(bond_dev, slave_dev); +err_detach: + write_lock_bh(&bond->lock); + bond_detach_slave(bond, new_slave); + write_unlock_bh(&bond->lock); + err_close: dev_close(slave_dev); -- 2.34.1