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

Commit c3b7d0bd authored by Sabrina Dubroca's avatar Sabrina Dubroca Committed by David S. Miller
Browse files

macsec: fix rx_sa refcounting with decrypt callback



The decrypt callback macsec_decrypt_done needs a reference on the rx_sa
and releases it before returning, but macsec_handle_frame already
put that reference after macsec_decrypt returned NULL.

Set rx_sa to NULL when the decrypt callback runs so that
macsec_handle_frame knows it must not release the reference.

Fixes: c09440f7 ("macsec: introduce IEEE 802.1AE driver")
Signed-off-by: default avatarSabrina Dubroca <sd@queasysnail.net>
Acked-by: default avatarHannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 497f358a
Loading
Loading
Loading
Loading
+9 −7
Original line number Diff line number Diff line
@@ -880,12 +880,12 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb,
	macsec_skb_cb(skb)->valid = false;
	skb = skb_share_check(skb, GFP_ATOMIC);
	if (!skb)
		return NULL;
		return ERR_PTR(-ENOMEM);

	req = aead_request_alloc(rx_sa->key.tfm, GFP_ATOMIC);
	if (!req) {
		kfree_skb(skb);
		return NULL;
		return ERR_PTR(-ENOMEM);
	}

	hdr = (struct macsec_eth_header *)skb->data;
@@ -905,7 +905,7 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb,
		skb = skb_unshare(skb, GFP_ATOMIC);
		if (!skb) {
			aead_request_free(req);
			return NULL;
			return ERR_PTR(-ENOMEM);
		}
	} else {
		/* integrity only: all headers + data authenticated */
@@ -921,14 +921,14 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb,
	dev_hold(dev);
	ret = crypto_aead_decrypt(req);
	if (ret == -EINPROGRESS) {
		return NULL;
		return ERR_PTR(ret);
	} else if (ret != 0) {
		/* decryption/authentication failed
		 * 10.6 if validateFrames is disabled, deliver anyway
		 */
		if (ret != -EBADMSG) {
			kfree_skb(skb);
			skb = NULL;
			skb = ERR_PTR(ret);
		}
	} else {
		macsec_skb_cb(skb)->valid = true;
@@ -1146,7 +1146,9 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb)
	    secy->validate_frames != MACSEC_VALIDATE_DISABLED)
		skb = macsec_decrypt(skb, dev, rx_sa, sci, secy);

	if (!skb) {
	if (IS_ERR(skb)) {
		/* the decrypt callback needs the reference */
		if (PTR_ERR(skb) != -EINPROGRESS)
			macsec_rxsa_put(rx_sa);
		rcu_read_unlock();
		*pskb = NULL;