diff options
author | Felix Fietkau <nbd@openwrt.org> | 2012-12-10 11:40:21 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-12-10 15:49:59 -0500 |
commit | 78f18df4b323d2ac14d6c82e2fc3c8dc4556bccc (patch) | |
tree | e34db528fb48b4e4f1d6d5adc9f07994c95380af /drivers/net/wireless | |
parent | 596ab5ec3bf10a22be30d7cb1d903a4b83fd607c (diff) |
b43: fix tx path skb leaks
ieee80211_free_txskb() needs to be used instead of dev_kfree_skb_any for
tx packets passed to the driver from mac80211
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Cc: stable@vger.kernel.org
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/b43/dma.c | 7 | ||||
-rw-r--r-- | drivers/net/wireless/b43/main.c | 12 | ||||
-rw-r--r-- | drivers/net/wireless/b43/pio.c | 4 |
3 files changed, 15 insertions, 8 deletions
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index 777cd74921d7..38bc5a7997ff 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c | |||
@@ -409,7 +409,10 @@ static inline | |||
409 | struct b43_dmadesc_meta *meta) | 409 | struct b43_dmadesc_meta *meta) |
410 | { | 410 | { |
411 | if (meta->skb) { | 411 | if (meta->skb) { |
412 | dev_kfree_skb_any(meta->skb); | 412 | if (ring->tx) |
413 | ieee80211_free_txskb(ring->dev->wl->hw, meta->skb); | ||
414 | else | ||
415 | dev_kfree_skb_any(meta->skb); | ||
413 | meta->skb = NULL; | 416 | meta->skb = NULL; |
414 | } | 417 | } |
415 | } | 418 | } |
@@ -1454,7 +1457,7 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb) | |||
1454 | if (unlikely(err == -ENOKEY)) { | 1457 | if (unlikely(err == -ENOKEY)) { |
1455 | /* Drop this packet, as we don't have the encryption key | 1458 | /* Drop this packet, as we don't have the encryption key |
1456 | * anymore and must not transmit it unencrypted. */ | 1459 | * anymore and must not transmit it unencrypted. */ |
1457 | dev_kfree_skb_any(skb); | 1460 | ieee80211_free_txskb(dev->wl->hw, skb); |
1458 | err = 0; | 1461 | err = 0; |
1459 | goto out; | 1462 | goto out; |
1460 | } | 1463 | } |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index ddd6a4f78097..16ab280359bd 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -3397,7 +3397,7 @@ static void b43_tx_work(struct work_struct *work) | |||
3397 | break; | 3397 | break; |
3398 | } | 3398 | } |
3399 | if (unlikely(err)) | 3399 | if (unlikely(err)) |
3400 | dev_kfree_skb(skb); /* Drop it */ | 3400 | ieee80211_free_txskb(wl->hw, skb); |
3401 | err = 0; | 3401 | err = 0; |
3402 | } | 3402 | } |
3403 | 3403 | ||
@@ -3419,7 +3419,7 @@ static void b43_op_tx(struct ieee80211_hw *hw, | |||
3419 | 3419 | ||
3420 | if (unlikely(skb->len < 2 + 2 + 6)) { | 3420 | if (unlikely(skb->len < 2 + 2 + 6)) { |
3421 | /* Too short, this can't be a valid frame. */ | 3421 | /* Too short, this can't be a valid frame. */ |
3422 | dev_kfree_skb_any(skb); | 3422 | ieee80211_free_txskb(hw, skb); |
3423 | return; | 3423 | return; |
3424 | } | 3424 | } |
3425 | B43_WARN_ON(skb_shinfo(skb)->nr_frags); | 3425 | B43_WARN_ON(skb_shinfo(skb)->nr_frags); |
@@ -4229,8 +4229,12 @@ redo: | |||
4229 | 4229 | ||
4230 | /* Drain all TX queues. */ | 4230 | /* Drain all TX queues. */ |
4231 | for (queue_num = 0; queue_num < B43_QOS_QUEUE_NUM; queue_num++) { | 4231 | for (queue_num = 0; queue_num < B43_QOS_QUEUE_NUM; queue_num++) { |
4232 | while (skb_queue_len(&wl->tx_queue[queue_num])) | 4232 | while (skb_queue_len(&wl->tx_queue[queue_num])) { |
4233 | dev_kfree_skb(skb_dequeue(&wl->tx_queue[queue_num])); | 4233 | struct sk_buff *skb; |
4234 | |||
4235 | skb = skb_dequeue(&wl->tx_queue[queue_num]); | ||
4236 | ieee80211_free_txskb(wl->hw, skb); | ||
4237 | } | ||
4234 | } | 4238 | } |
4235 | 4239 | ||
4236 | b43_mac_suspend(dev); | 4240 | b43_mac_suspend(dev); |
diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c index 3533ab86bd36..a73ff8c9deb5 100644 --- a/drivers/net/wireless/b43/pio.c +++ b/drivers/net/wireless/b43/pio.c | |||
@@ -196,7 +196,7 @@ static void b43_pio_cancel_tx_packets(struct b43_pio_txqueue *q) | |||
196 | for (i = 0; i < ARRAY_SIZE(q->packets); i++) { | 196 | for (i = 0; i < ARRAY_SIZE(q->packets); i++) { |
197 | pack = &(q->packets[i]); | 197 | pack = &(q->packets[i]); |
198 | if (pack->skb) { | 198 | if (pack->skb) { |
199 | dev_kfree_skb_any(pack->skb); | 199 | ieee80211_free_txskb(q->dev->wl->hw, pack->skb); |
200 | pack->skb = NULL; | 200 | pack->skb = NULL; |
201 | } | 201 | } |
202 | } | 202 | } |
@@ -552,7 +552,7 @@ int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb) | |||
552 | if (unlikely(err == -ENOKEY)) { | 552 | if (unlikely(err == -ENOKEY)) { |
553 | /* Drop this packet, as we don't have the encryption key | 553 | /* Drop this packet, as we don't have the encryption key |
554 | * anymore and must not transmit it unencrypted. */ | 554 | * anymore and must not transmit it unencrypted. */ |
555 | dev_kfree_skb_any(skb); | 555 | ieee80211_free_txskb(dev->wl->hw, skb); |
556 | err = 0; | 556 | err = 0; |
557 | goto out; | 557 | goto out; |
558 | } | 558 | } |