From: Veaceslav Falico Date: Fri, 10 Jan 2014 10:59:43 +0000 (+0100) Subject: bonding: fix bond_3ad_set_carrier() RCU usage X-Git-Tag: v3.14-rc1~94^2~202^2~2 X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=commitdiff_plain;h=c1bc9644ecd1f663f918d42b33b41a508683b0ee;p=linux.git bonding: fix bond_3ad_set_carrier() RCU usage Currently, its usage is just plainly wrong. It first gets a slave under RCU, and, after releasing the RCU lock, continues to use it - whilst it can be freed. Fix this by ensuring that bond_3ad_set_carrier() holds RCU till it uses its slave (or its agg). Fixes: be79bd048ab ("bonding: add RCU for bond_3ad_state_machine_handler()") CC: dingtianhong@huawei.com CC: Jay Vosburgh CC: Andy Gospodarek Signed-off-by: Veaceslav Falico Signed-off-by: David S. Miller --- diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 29db1caee764..da0d7c54d352 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c @@ -2327,32 +2327,32 @@ int bond_3ad_set_carrier(struct bonding *bond) { struct aggregator *active; struct slave *first_slave; + int ret = 1; rcu_read_lock(); first_slave = bond_first_slave_rcu(bond); - rcu_read_unlock(); - if (!first_slave) - return 0; + if (!first_slave) { + ret = 0; + goto out; + } active = __get_active_agg(&(SLAVE_AD_INFO(first_slave).aggregator)); if (active) { /* are enough slaves available to consider link up? */ if (active->num_of_ports < bond->params.min_links) { if (netif_carrier_ok(bond->dev)) { netif_carrier_off(bond->dev); - return 1; + goto out; } } else if (!netif_carrier_ok(bond->dev)) { netif_carrier_on(bond->dev); - return 1; + goto out; } - return 0; - } - - if (netif_carrier_ok(bond->dev)) { + } else if (netif_carrier_ok(bond->dev)) { netif_carrier_off(bond->dev); - return 1; } - return 0; +out: + rcu_read_unlock(); + return ret; } /**