diff options
author | Sabrina Dubroca <sd@queasysnail.net> | 2016-07-29 09:37:53 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-07-31 00:11:08 -0400 |
commit | c78ebe1df01f4ef3fb07be1359bc34df6708d99c (patch) | |
tree | be33ee0b1d42e22cb638a1941abf6f2c8d2c694e | |
parent | 122e9b71273f9d99ed90d51709674bc69c175fa0 (diff) |
macsec: fix reference counting on RXSC in macsec_handle_frame
Currently, we lookup the RXSC without taking a reference on it. The
RXSA holds a reference on the RXSC, but the SA and SC could still both
disappear before we take a reference on the SA.
Take a reference on the RXSC in macsec_handle_frame.
Fixes: c09440f7dcb3 ("macsec: introduce IEEE 802.1AE driver")
Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/macsec.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c index 2d0beb1b801c..718cf98023ff 100644 --- a/drivers/net/macsec.c +++ b/drivers/net/macsec.c | |||
@@ -863,6 +863,7 @@ static void macsec_decrypt_done(struct crypto_async_request *base, int err) | |||
863 | struct net_device *dev = skb->dev; | 863 | struct net_device *dev = skb->dev; |
864 | struct macsec_dev *macsec = macsec_priv(dev); | 864 | struct macsec_dev *macsec = macsec_priv(dev); |
865 | struct macsec_rx_sa *rx_sa = macsec_skb_cb(skb)->rx_sa; | 865 | struct macsec_rx_sa *rx_sa = macsec_skb_cb(skb)->rx_sa; |
866 | struct macsec_rx_sc *rx_sc = rx_sa->sc; | ||
866 | int len, ret; | 867 | int len, ret; |
867 | u32 pn; | 868 | u32 pn; |
868 | 869 | ||
@@ -891,6 +892,7 @@ static void macsec_decrypt_done(struct crypto_async_request *base, int err) | |||
891 | 892 | ||
892 | out: | 893 | out: |
893 | macsec_rxsa_put(rx_sa); | 894 | macsec_rxsa_put(rx_sa); |
895 | macsec_rxsc_put(rx_sc); | ||
894 | dev_put(dev); | 896 | dev_put(dev); |
895 | } | 897 | } |
896 | 898 | ||
@@ -1106,6 +1108,7 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb) | |||
1106 | 1108 | ||
1107 | list_for_each_entry_rcu(macsec, &rxd->secys, secys) { | 1109 | list_for_each_entry_rcu(macsec, &rxd->secys, secys) { |
1108 | struct macsec_rx_sc *sc = find_rx_sc(&macsec->secy, sci); | 1110 | struct macsec_rx_sc *sc = find_rx_sc(&macsec->secy, sci); |
1111 | sc = sc ? macsec_rxsc_get(sc) : NULL; | ||
1109 | 1112 | ||
1110 | if (sc) { | 1113 | if (sc) { |
1111 | secy = &macsec->secy; | 1114 | secy = &macsec->secy; |
@@ -1180,8 +1183,10 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb) | |||
1180 | 1183 | ||
1181 | if (IS_ERR(skb)) { | 1184 | if (IS_ERR(skb)) { |
1182 | /* the decrypt callback needs the reference */ | 1185 | /* the decrypt callback needs the reference */ |
1183 | if (PTR_ERR(skb) != -EINPROGRESS) | 1186 | if (PTR_ERR(skb) != -EINPROGRESS) { |
1184 | macsec_rxsa_put(rx_sa); | 1187 | macsec_rxsa_put(rx_sa); |
1188 | macsec_rxsc_put(rx_sc); | ||
1189 | } | ||
1185 | rcu_read_unlock(); | 1190 | rcu_read_unlock(); |
1186 | *pskb = NULL; | 1191 | *pskb = NULL; |
1187 | return RX_HANDLER_CONSUMED; | 1192 | return RX_HANDLER_CONSUMED; |
@@ -1197,6 +1202,7 @@ deliver: | |||
1197 | 1202 | ||
1198 | if (rx_sa) | 1203 | if (rx_sa) |
1199 | macsec_rxsa_put(rx_sa); | 1204 | macsec_rxsa_put(rx_sa); |
1205 | macsec_rxsc_put(rx_sc); | ||
1200 | 1206 | ||
1201 | ret = gro_cells_receive(&macsec->gro_cells, skb); | 1207 | ret = gro_cells_receive(&macsec->gro_cells, skb); |
1202 | if (ret == NET_RX_SUCCESS) | 1208 | if (ret == NET_RX_SUCCESS) |
@@ -1212,6 +1218,7 @@ deliver: | |||
1212 | drop: | 1218 | drop: |
1213 | macsec_rxsa_put(rx_sa); | 1219 | macsec_rxsa_put(rx_sa); |
1214 | drop_nosa: | 1220 | drop_nosa: |
1221 | macsec_rxsc_put(rx_sc); | ||
1215 | rcu_read_unlock(); | 1222 | rcu_read_unlock(); |
1216 | drop_direct: | 1223 | drop_direct: |
1217 | kfree_skb(skb); | 1224 | kfree_skb(skb); |