| From 78f18df4b323d2ac14d6c82e2fc3c8dc4556bccc Mon Sep 17 00:00:00 2001 |
| From: Felix Fietkau <nbd@openwrt.org> |
| Date: Mon, 10 Dec 2012 17:40:21 +0100 |
| Subject: b43: fix tx path skb leaks |
| |
| From: Felix Fietkau <nbd@openwrt.org> |
| |
| commit 78f18df4b323d2ac14d6c82e2fc3c8dc4556bccc upstream. |
| |
| 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> |
| Signed-off-by: John W. Linville <linville@tuxdriver.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/net/wireless/b43/dma.c | 7 +++++-- |
| drivers/net/wireless/b43/main.c | 12 ++++++++---- |
| drivers/net/wireless/b43/pio.c | 4 ++-- |
| 3 files changed, 15 insertions(+), 8 deletions(-) |
| |
| --- a/drivers/net/wireless/b43/dma.c |
| +++ b/drivers/net/wireless/b43/dma.c |
| @@ -409,7 +409,10 @@ static inline |
| struct b43_dmadesc_meta *meta) |
| { |
| if (meta->skb) { |
| - dev_kfree_skb_any(meta->skb); |
| + if (ring->tx) |
| + ieee80211_free_txskb(ring->dev->wl->hw, meta->skb); |
| + else |
| + dev_kfree_skb_any(meta->skb); |
| meta->skb = NULL; |
| } |
| } |
| @@ -1454,7 +1457,7 @@ int b43_dma_tx(struct b43_wldev *dev, st |
| if (unlikely(err == -ENOKEY)) { |
| /* Drop this packet, as we don't have the encryption key |
| * anymore and must not transmit it unencrypted. */ |
| - dev_kfree_skb_any(skb); |
| + ieee80211_free_txskb(dev->wl->hw, skb); |
| err = 0; |
| goto out; |
| } |
| --- 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_stru |
| break; |
| } |
| if (unlikely(err)) |
| - dev_kfree_skb(skb); /* Drop it */ |
| + ieee80211_free_txskb(wl->hw, skb); |
| err = 0; |
| } |
| |
| @@ -3419,7 +3419,7 @@ static void b43_op_tx(struct ieee80211_h |
| |
| if (unlikely(skb->len < 2 + 2 + 6)) { |
| /* Too short, this can't be a valid frame. */ |
| - dev_kfree_skb_any(skb); |
| + ieee80211_free_txskb(hw, skb); |
| return; |
| } |
| B43_WARN_ON(skb_shinfo(skb)->nr_frags); |
| @@ -4229,8 +4229,12 @@ redo: |
| |
| /* Drain all TX queues. */ |
| for (queue_num = 0; queue_num < B43_QOS_QUEUE_NUM; queue_num++) { |
| - while (skb_queue_len(&wl->tx_queue[queue_num])) |
| - dev_kfree_skb(skb_dequeue(&wl->tx_queue[queue_num])); |
| + while (skb_queue_len(&wl->tx_queue[queue_num])) { |
| + struct sk_buff *skb; |
| + |
| + skb = skb_dequeue(&wl->tx_queue[queue_num]); |
| + ieee80211_free_txskb(wl->hw, skb); |
| + } |
| } |
| |
| b43_mac_suspend(dev); |
| --- 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(st |
| for (i = 0; i < ARRAY_SIZE(q->packets); i++) { |
| pack = &(q->packets[i]); |
| if (pack->skb) { |
| - dev_kfree_skb_any(pack->skb); |
| + ieee80211_free_txskb(q->dev->wl->hw, pack->skb); |
| pack->skb = NULL; |
| } |
| } |
| @@ -552,7 +552,7 @@ int b43_pio_tx(struct b43_wldev *dev, st |
| if (unlikely(err == -ENOKEY)) { |
| /* Drop this packet, as we don't have the encryption key |
| * anymore and must not transmit it unencrypted. */ |
| - dev_kfree_skb_any(skb); |
| + ieee80211_free_txskb(dev->wl->hw, skb); |
| err = 0; |
| goto out; |
| } |