ath9k: fix a potential buffer leak
authorFelix Fietkau <nbd@openwrt.org>
Fri, 2 Jul 2010 16:11:18 +0000 (16:11 +0000)
committerFelix Fietkau <nbd@openwrt.org>
Fri, 2 Jul 2010 16:11:18 +0000 (16:11 +0000)
SVN-Revision: 22048

package/mac80211/patches/560-ath9k_buffer_leak.patch [new file with mode: 0644]

diff --git a/package/mac80211/patches/560-ath9k_buffer_leak.patch b/package/mac80211/patches/560-ath9k_buffer_leak.patch
new file mode 100644 (file)
index 0000000..aa1f033
--- /dev/null
@@ -0,0 +1,68 @@
+--- a/drivers/net/wireless/ath/ath9k/xmit.c
++++ b/drivers/net/wireless/ath/ath9k/xmit.c
+@@ -2430,37 +2430,37 @@ void ath_tx_node_init(struct ath_softc *
+ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
+ {
+-      int i;
+-      struct ath_atx_ac *ac, *ac_tmp;
+-      struct ath_atx_tid *tid, *tid_tmp;
++      struct ath_atx_ac *ac;
++      struct ath_atx_tid *tid;
+       struct ath_txq *txq;
++      int i, tidno;
+-      for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+-              if (ATH_TXQ_SETUP(sc, i)) {
+-                      txq = &sc->tx.txq[i];
+-
+-                      spin_lock_bh(&txq->axq_lock);
+-
+-                      list_for_each_entry_safe(ac,
+-                                      ac_tmp, &txq->axq_acq, list) {
+-                              tid = list_first_entry(&ac->tid_q,
+-                                              struct ath_atx_tid, list);
+-                              if (tid && tid->an != an)
+-                                      continue;
+-                              list_del(&ac->list);
+-                              ac->sched = false;
+-
+-                              list_for_each_entry_safe(tid,
+-                                              tid_tmp, &ac->tid_q, list) {
+-                                      list_del(&tid->list);
+-                                      tid->sched = false;
+-                                      ath_tid_drain(sc, txq, tid);
+-                                      tid->state &= ~AGGR_ADDBA_COMPLETE;
+-                                      tid->state &= ~AGGR_CLEANUP;
+-                              }
+-                      }
++      for (tidno = 0, tid = &an->tid[tidno];
++           tidno < WME_NUM_TID; tidno++, tid++) {
++              i = tid->ac->qnum;
+-                      spin_unlock_bh(&txq->axq_lock);
++              if (!ATH_TXQ_SETUP(sc, i))
++                      continue;
++
++              txq = &sc->tx.txq[i];
++              ac = tid->ac;
++
++              spin_lock_bh(&txq->axq_lock);
++
++              if (tid->sched) {
++                      list_del(&tid->list);
++                      tid->sched = false;
+               }
++
++              if (ac->sched) {
++                      list_del(&ac->list);
++                      tid->ac->sched = false;
++              }
++
++              ath_tid_drain(sc, txq, tid);
++              tid->state &= ~AGGR_ADDBA_COMPLETE;
++              tid->state &= ~AGGR_CLEANUP;
++
++              spin_unlock_bh(&txq->axq_lock);
+       }
+ }