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

Commit 5c5038dc authored by nikolay@redhat.com's avatar nikolay@redhat.com Committed by David S. Miller
Browse files

bonding: fix store_arp_validate race with mode change



We need to protect store_arp_validate via rtnl because it can race with
mode changing and we can end up having arp_validate set in a mode
different from active-backup.

Signed-off-by: default avatarNikolay Aleksandrov <nikolay@redhat.com>
Acked-by: default avatarVeaceslav Falico <vfalico@redhat.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 8112b1fe
Loading
Loading
Loading
Loading
+10 −4
Original line number Original line Diff line number Diff line
@@ -419,27 +419,33 @@ static ssize_t bonding_store_arp_validate(struct device *d,
					  struct device_attribute *attr,
					  struct device_attribute *attr,
					  const char *buf, size_t count)
					  const char *buf, size_t count)
{
{
	int new_value;
	int new_value, ret = count;
	struct bonding *bond = to_bond(d);
	struct bonding *bond = to_bond(d);


	if (!rtnl_trylock())
		return restart_syscall();
	new_value = bond_parse_parm(buf, arp_validate_tbl);
	new_value = bond_parse_parm(buf, arp_validate_tbl);
	if (new_value < 0) {
	if (new_value < 0) {
		pr_err("%s: Ignoring invalid arp_validate value %s\n",
		pr_err("%s: Ignoring invalid arp_validate value %s\n",
		       bond->dev->name, buf);
		       bond->dev->name, buf);
		return -EINVAL;
		ret = -EINVAL;
		goto out;
	}
	}
	if (new_value && (bond->params.mode != BOND_MODE_ACTIVEBACKUP)) {
	if (new_value && (bond->params.mode != BOND_MODE_ACTIVEBACKUP)) {
		pr_err("%s: arp_validate only supported in active-backup mode.\n",
		pr_err("%s: arp_validate only supported in active-backup mode.\n",
		       bond->dev->name);
		       bond->dev->name);
		return -EINVAL;
		ret = -EINVAL;
		goto out;
	}
	}
	pr_info("%s: setting arp_validate to %s (%d).\n",
	pr_info("%s: setting arp_validate to %s (%d).\n",
		bond->dev->name, arp_validate_tbl[new_value].modename,
		bond->dev->name, arp_validate_tbl[new_value].modename,
		new_value);
		new_value);


	bond->params.arp_validate = new_value;
	bond->params.arp_validate = new_value;
out:
	rtnl_unlock();


	return count;
	return ret;
}
}


static DEVICE_ATTR(arp_validate, S_IRUGO | S_IWUSR, bonding_show_arp_validate,
static DEVICE_ATTR(arp_validate, S_IRUGO | S_IWUSR, bonding_show_arp_validate,