ath6kl: Fix potential memory leak in ath6kl_tx_complete()
authorVasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com>
Tue, 14 Aug 2012 04:40:34 +0000 (10:10 +0530)
committerKalle Valo <kvalo@qca.qualcomm.com>
Wed, 24 Oct 2012 08:49:45 +0000 (11:49 +0300)
We bail out from ath6kl_tx_complete() if any of the sanity
checks on skb and ath6kl_cookie fails. By doing this we
potentially leak few remaining buffers in packet_queue.
Make sure to proceed processing the remaining buffers
as well. This issue is found during code review.

Reported-by: Wang yufeng <yufengw@qca.qualcomm.com>
Signed-off-by: Vasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
drivers/net/wireless/ath/ath6kl/txrx.c

index aab825152b190de9910171ccecf597d77deb1055..740a488ef5049211e9c4bebf2a852c1d1d2356cb 100644 (file)
@@ -698,21 +698,26 @@ void ath6kl_tx_complete(struct htc_target *target,
                list_del(&packet->list);
 
                ath6kl_cookie = (struct ath6kl_cookie *)packet->pkt_cntxt;
-               if (!ath6kl_cookie)
-                       goto fatal;
+               if (WARN_ON_ONCE(!ath6kl_cookie))
+                       continue;
 
                status = packet->status;
                skb = ath6kl_cookie->skb;
                eid = packet->endpoint;
                map_no = ath6kl_cookie->map_no;
 
-               if (!skb || !skb->data)
-                       goto fatal;
+               if (WARN_ON_ONCE(!skb || !skb->data)) {
+                       dev_kfree_skb(skb);
+                       ath6kl_free_cookie(ar, ath6kl_cookie);
+                       continue;
+               }
 
                __skb_queue_tail(&skb_queue, skb);
 
-               if (!status && (packet->act_len != skb->len))
-                       goto fatal;
+               if (WARN_ON_ONCE(!status && (packet->act_len != skb->len))) {
+                       ath6kl_free_cookie(ar, ath6kl_cookie);
+                       continue;
+               }
 
                ar->tx_pending[eid]--;
 
@@ -794,11 +799,6 @@ void ath6kl_tx_complete(struct htc_target *target,
                wake_up(&ar->event_wq);
 
        return;
-
-fatal:
-       WARN_ON(1);
-       spin_unlock_bh(&ar->lock);
-       return;
 }
 
 void ath6kl_tx_data_cleanup(struct ath6kl *ar)