aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-06-11 15:11:25 -0400
committerDavid S. Miller <davem@davemloft.net>2014-06-11 15:11:25 -0400
commit9181a6bd18009bf417bc865fd862075c335cc1dd (patch)
treebad4e444da804759fe1d8f91d4a940cdcb4ca1fb
parentd5c4858237fe43c30714f4447ccec87d5fb3fcde (diff)
parent2d3b5b0a90e5370ad13ca98d95519c3e41d2c925 (diff)
Merge branch 'mac802154'
Phoebe Buckheister says: ==================== Recent llsec code introduced a memory leak on decryption failures during rx. This fixes said leak, and optimizes the receive loops for monitor and wpan devices to only deliver skbs to devices that are actually up. Also changes a dev_kfree_skb to kfree_skb when an invalid packet is dropped before being pushed into the stack. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/mac802154/monitor.c3
-rw-r--r--net/mac802154/rx.c11
-rw-r--r--net/mac802154/wpan.c14
3 files changed, 18 insertions, 10 deletions
diff --git a/net/mac802154/monitor.c b/net/mac802154/monitor.c
index 434a26f76a80..a68230e2b25f 100644
--- a/net/mac802154/monitor.c
+++ b/net/mac802154/monitor.c
@@ -70,7 +70,8 @@ void mac802154_monitors_rx(struct mac802154_priv *priv, struct sk_buff *skb)
70 70
71 rcu_read_lock(); 71 rcu_read_lock();
72 list_for_each_entry_rcu(sdata, &priv->slaves, list) { 72 list_for_each_entry_rcu(sdata, &priv->slaves, list) {
73 if (sdata->type != IEEE802154_DEV_MONITOR) 73 if (sdata->type != IEEE802154_DEV_MONITOR ||
74 !netif_running(sdata->dev))
74 continue; 75 continue;
75 76
76 skb2 = skb_clone(skb, GFP_ATOMIC); 77 skb2 = skb_clone(skb, GFP_ATOMIC);
diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c
index 0597b96dc9ba..7f820a108a9c 100644
--- a/net/mac802154/rx.c
+++ b/net/mac802154/rx.c
@@ -64,20 +64,23 @@ mac802154_subif_rx(struct ieee802154_dev *hw, struct sk_buff *skb, u8 lqi)
64 64
65 if (skb->len < 2) { 65 if (skb->len < 2) {
66 pr_debug("got invalid frame\n"); 66 pr_debug("got invalid frame\n");
67 goto out; 67 goto fail;
68 } 68 }
69 crc = crc_ccitt(0, skb->data, skb->len); 69 crc = crc_ccitt(0, skb->data, skb->len);
70 if (crc) { 70 if (crc) {
71 pr_debug("CRC mismatch\n"); 71 pr_debug("CRC mismatch\n");
72 goto out; 72 goto fail;
73 } 73 }
74 skb_trim(skb, skb->len - 2); /* CRC */ 74 skb_trim(skb, skb->len - 2); /* CRC */
75 } 75 }
76 76
77 mac802154_monitors_rx(priv, skb); 77 mac802154_monitors_rx(priv, skb);
78 mac802154_wpans_rx(priv, skb); 78 mac802154_wpans_rx(priv, skb);
79out: 79
80 dev_kfree_skb(skb); 80 return;
81
82fail:
83 kfree_skb(skb);
81} 84}
82 85
83static void mac802154_rx_worker(struct work_struct *work) 86static void mac802154_rx_worker(struct work_struct *work)
diff --git a/net/mac802154/wpan.c b/net/mac802154/wpan.c
index 23bc91cf99c4..3c3069fd6971 100644
--- a/net/mac802154/wpan.c
+++ b/net/mac802154/wpan.c
@@ -472,6 +472,7 @@ mac802154_subif_frame(struct mac802154_sub_if_data *sdata, struct sk_buff *skb,
472 rc = mac802154_llsec_decrypt(&sdata->sec, skb); 472 rc = mac802154_llsec_decrypt(&sdata->sec, skb);
473 if (rc) { 473 if (rc) {
474 pr_debug("decryption failed: %i\n", rc); 474 pr_debug("decryption failed: %i\n", rc);
475 kfree_skb(skb);
475 return NET_RX_DROP; 476 return NET_RX_DROP;
476 } 477 }
477 478
@@ -566,7 +567,6 @@ static int mac802154_parse_frame_start(struct sk_buff *skb,
566void mac802154_wpans_rx(struct mac802154_priv *priv, struct sk_buff *skb) 567void mac802154_wpans_rx(struct mac802154_priv *priv, struct sk_buff *skb)
567{ 568{
568 int ret; 569 int ret;
569 struct sk_buff *sskb;
570 struct mac802154_sub_if_data *sdata; 570 struct mac802154_sub_if_data *sdata;
571 struct ieee802154_hdr hdr; 571 struct ieee802154_hdr hdr;
572 572
@@ -578,12 +578,16 @@ void mac802154_wpans_rx(struct mac802154_priv *priv, struct sk_buff *skb)
578 578
579 rcu_read_lock(); 579 rcu_read_lock();
580 list_for_each_entry_rcu(sdata, &priv->slaves, list) { 580 list_for_each_entry_rcu(sdata, &priv->slaves, list) {
581 if (sdata->type != IEEE802154_DEV_WPAN) 581 if (sdata->type != IEEE802154_DEV_WPAN ||
582 !netif_running(sdata->dev))
582 continue; 583 continue;
583 584
584 sskb = skb_clone(skb, GFP_ATOMIC); 585 mac802154_subif_frame(sdata, skb, &hdr);
585 if (sskb) 586 skb = NULL;
586 mac802154_subif_frame(sdata, sskb, &hdr); 587 break;
587 } 588 }
588 rcu_read_unlock(); 589 rcu_read_unlock();
590
591 if (skb)
592 kfree_skb(skb);
589} 593}