Commit 20a85461 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'macsec-config-issues'

Sabrina Dubroca says:

====================
macsec: fix config issues

The patch adding netlink support for XPN (commit 48ef50fa
("macsec: Netlink support of XPN cipher suites (IEEE 802.1AEbw)"))
introduced several issues, including a kernel panic reported at [1].

Reproducing those bugs with upstream iproute is limited, since iproute
doesn't currently support XPN. I'm also working on this.

[1] https://bugzilla.kernel.org/show_bug.cgi?id=208315


====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 1aaa62c4 c630d1fe
Loading
Loading
Loading
Loading
+19 −10
Original line number Diff line number Diff line
@@ -243,6 +243,7 @@ static struct macsec_cb *macsec_skb_cb(struct sk_buff *skb)
#define DEFAULT_SEND_SCI true
#define DEFAULT_ENCRYPT false
#define DEFAULT_ENCODING_SA 0
#define MACSEC_XPN_MAX_REPLAY_WINDOW (((1 << 30) - 1))

static bool send_sci(const struct macsec_secy *secy)
{
@@ -1697,7 +1698,7 @@ static bool validate_add_rxsa(struct nlattr **attrs)
		return false;

	if (attrs[MACSEC_SA_ATTR_PN] &&
	    *(u64 *)nla_data(attrs[MACSEC_SA_ATTR_PN]) == 0)
	    nla_get_u64(attrs[MACSEC_SA_ATTR_PN]) == 0)
		return false;

	if (attrs[MACSEC_SA_ATTR_ACTIVE]) {
@@ -1753,7 +1754,8 @@ static int macsec_add_rxsa(struct sk_buff *skb, struct genl_info *info)
	}

	pn_len = secy->xpn ? MACSEC_XPN_PN_LEN : MACSEC_DEFAULT_PN_LEN;
	if (nla_len(tb_sa[MACSEC_SA_ATTR_PN]) != pn_len) {
	if (tb_sa[MACSEC_SA_ATTR_PN] &&
	    nla_len(tb_sa[MACSEC_SA_ATTR_PN]) != pn_len) {
		pr_notice("macsec: nl: add_rxsa: bad pn length: %d != %d\n",
			  nla_len(tb_sa[MACSEC_SA_ATTR_PN]), pn_len);
		rtnl_unlock();
@@ -1769,7 +1771,7 @@ static int macsec_add_rxsa(struct sk_buff *skb, struct genl_info *info)
		if (nla_len(tb_sa[MACSEC_SA_ATTR_SALT]) != MACSEC_SALT_LEN) {
			pr_notice("macsec: nl: add_rxsa: bad salt length: %d != %d\n",
				  nla_len(tb_sa[MACSEC_SA_ATTR_SALT]),
				  MACSEC_SA_ATTR_SALT);
				  MACSEC_SALT_LEN);
			rtnl_unlock();
			return -EINVAL;
		}
@@ -1939,7 +1941,7 @@ static bool validate_add_txsa(struct nlattr **attrs)
	if (nla_get_u8(attrs[MACSEC_SA_ATTR_AN]) >= MACSEC_NUM_AN)
		return false;

	if (nla_get_u32(attrs[MACSEC_SA_ATTR_PN]) == 0)
	if (nla_get_u64(attrs[MACSEC_SA_ATTR_PN]) == 0)
		return false;

	if (attrs[MACSEC_SA_ATTR_ACTIVE]) {
@@ -2011,7 +2013,7 @@ static int macsec_add_txsa(struct sk_buff *skb, struct genl_info *info)
		if (nla_len(tb_sa[MACSEC_SA_ATTR_SALT]) != MACSEC_SALT_LEN) {
			pr_notice("macsec: nl: add_txsa: bad salt length: %d != %d\n",
				  nla_len(tb_sa[MACSEC_SA_ATTR_SALT]),
				  MACSEC_SA_ATTR_SALT);
				  MACSEC_SALT_LEN);
			rtnl_unlock();
			return -EINVAL;
		}
@@ -2293,7 +2295,7 @@ static bool validate_upd_sa(struct nlattr **attrs)
	if (nla_get_u8(attrs[MACSEC_SA_ATTR_AN]) >= MACSEC_NUM_AN)
		return false;

	if (attrs[MACSEC_SA_ATTR_PN] && nla_get_u32(attrs[MACSEC_SA_ATTR_PN]) == 0)
	if (attrs[MACSEC_SA_ATTR_PN] && nla_get_u64(attrs[MACSEC_SA_ATTR_PN]) == 0)
		return false;

	if (attrs[MACSEC_SA_ATTR_ACTIVE]) {
@@ -3745,9 +3747,6 @@ static int macsec_changelink_common(struct net_device *dev,
		secy->operational = tx_sa && tx_sa->active;
	}

	if (data[IFLA_MACSEC_WINDOW])
		secy->replay_window = nla_get_u32(data[IFLA_MACSEC_WINDOW]);

	if (data[IFLA_MACSEC_ENCRYPT])
		tx_sc->encrypt = !!nla_get_u8(data[IFLA_MACSEC_ENCRYPT]);

@@ -3793,6 +3792,16 @@ static int macsec_changelink_common(struct net_device *dev,
		}
	}

	if (data[IFLA_MACSEC_WINDOW]) {
		secy->replay_window = nla_get_u32(data[IFLA_MACSEC_WINDOW]);

		/* IEEE 802.1AEbw-2013 10.7.8 - maximum replay window
		 * for XPN cipher suites */
		if (secy->xpn &&
		    secy->replay_window > MACSEC_XPN_MAX_REPLAY_WINDOW)
			return -EINVAL;
	}

	return 0;
}

@@ -3822,7 +3831,7 @@ static int macsec_changelink(struct net_device *dev, struct nlattr *tb[],

	ret = macsec_changelink_common(dev, data);
	if (ret)
		return ret;
		goto cleanup;

	/* If h/w offloading is available, propagate to the device */
	if (macsec_is_offloaded(macsec)) {