Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c1bc9644 authored by Veaceslav Falico's avatar Veaceslav Falico Committed by David S. Miller
Browse files

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: be79bd04 ("bonding: add RCU for bond_3ad_state_machine_handler()")
CC: dingtianhong@huawei.com
CC: Jay Vosburgh <fubar@us.ibm.com>
CC: Andy Gospodarek <andy@greyhouse.net>
Signed-off-by: default avatarVeaceslav Falico <vfalico@redhat.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 853dc21b
Loading
Loading
Loading
Loading
+11 −11
Original line number Diff line number Diff line
@@ -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;
		}
		return 0;
			goto out;
		}

	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;
}

/**