Commit f3b4a00f authored by Emeel Hakim's avatar Emeel Hakim Committed by Jakub Kicinski
Browse files

net: macsec: fix net device access prior to holding a lock



Currently macsec offload selection update routine accesses
the net device prior to holding the relevant lock.
Fix by holding the lock prior to the device access.

Fixes: dcb780fb ("net: macsec: add nla support for changing the offloading selection")
Reviewed-by: default avatarRaed Salem <raeds@nvidia.com>
Signed-off-by: default avatarEmeel Hakim <ehakim@nvidia.com>
Link: https://lore.kernel.org/r/20221211075532.28099-1-ehakim@nvidia.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 7e68dd7d
Loading
Loading
Loading
Loading
+21 −13
Original line number Diff line number Diff line
@@ -2593,7 +2593,7 @@ static int macsec_upd_offload(struct sk_buff *skb, struct genl_info *info)
	const struct macsec_ops *ops;
	struct macsec_context ctx;
	struct macsec_dev *macsec;
	int ret;
	int ret = 0;

	if (!attrs[MACSEC_ATTR_IFINDEX])
		return -EINVAL;
@@ -2606,28 +2606,36 @@ static int macsec_upd_offload(struct sk_buff *skb, struct genl_info *info)
					macsec_genl_offload_policy, NULL))
		return -EINVAL;

	rtnl_lock();

	dev = get_dev_from_nl(genl_info_net(info), attrs);
	if (IS_ERR(dev))
		return PTR_ERR(dev);
	if (IS_ERR(dev)) {
		ret = PTR_ERR(dev);
		goto out;
	}
	macsec = macsec_priv(dev);

	if (!tb_offload[MACSEC_OFFLOAD_ATTR_TYPE])
		return -EINVAL;
	if (!tb_offload[MACSEC_OFFLOAD_ATTR_TYPE]) {
		ret = -EINVAL;
		goto out;
	}

	offload = nla_get_u8(tb_offload[MACSEC_OFFLOAD_ATTR_TYPE]);
	if (macsec->offload == offload)
		return 0;
		goto out;

	/* Check if the offloading mode is supported by the underlying layers */
	if (offload != MACSEC_OFFLOAD_OFF &&
	    !macsec_check_offload(offload, macsec))
		return -EOPNOTSUPP;
	    !macsec_check_offload(offload, macsec)) {
		ret = -EOPNOTSUPP;
		goto out;
	}

	/* Check if the net device is busy. */
	if (netif_running(dev))
		return -EBUSY;

	rtnl_lock();
	if (netif_running(dev)) {
		ret = -EBUSY;
		goto out;
	}

	prev_offload = macsec->offload;
	macsec->offload = offload;
@@ -2662,7 +2670,7 @@ static int macsec_upd_offload(struct sk_buff *skb, struct genl_info *info)

rollback:
	macsec->offload = prev_offload;

out:
	rtnl_unlock();
	return ret;
}