summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2010-07-07 19:42:09 +0200
committerGreg Kroah-Hartman <gregkh@suse.de>2010-08-10 11:09:18 -0700
commitcaaec883ca2702445d84ff3ee94fe149aeaa95fe (patch)
tree441b444e84d147c7a204de24e56feba344c384c4
parenta9328d5065468169355a70246bb8ea41d9fc25ef (diff)
downloadlwn-caaec883ca2702445d84ff3ee94fe149aeaa95fe.tar.gz
lwn-caaec883ca2702445d84ff3ee94fe149aeaa95fe.zip
ath9k: fix a buffer leak in A-MPDU completion
commit 73e194639d90594d06d0c10019c0ab4638869135 upstream. When ath_tx_complete_aggr() is called, it's responsible for returning all buffers in the linked list. This was not done when the STA lookup failed, leading to a race condition that could leak a few buffers when a STA just disconnected. Fix this by immediately returning all buffers to the free list in this case. Signed-off-by: Felix Fietkau <nbd@openwrt.org> Signed-off-by: John W. Linville <linville@tuxdriver.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 2b305ff204f1..191794ec7eb3 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -329,6 +329,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0;
bool rc_update = true;
struct ieee80211_tx_rate rates[4];
+ unsigned long flags;
skb = bf->bf_mpdu;
hdr = (struct ieee80211_hdr *)skb->data;
@@ -344,6 +345,10 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
sta = ieee80211_find_sta_by_hw(hw, hdr->addr1);
if (!sta) {
rcu_read_unlock();
+
+ spin_lock_irqsave(&sc->tx.txbuflock, flags);
+ list_splice_tail_init(bf_q, &sc->tx.txbuf);
+ spin_unlock_irqrestore(&sc->tx.txbuflock, flags);
return;
}