diff options
author | Felix Fietkau <nbd@openwrt.org> | 2012-05-12 17:40:53 +0000 |
---|---|---|
committer | Felix Fietkau <nbd@openwrt.org> | 2012-05-12 17:40:53 +0000 |
commit | a8d08175a9aa0d4900c7b2b610d03930fee78705 (patch) | |
tree | f21e761c94f2af26b49846a11eeb0c36ef04478a | |
parent | db771744d5e8fa2f2c7da9b104ab9c9fecac8f2f (diff) | |
download | master-187ad058-a8d08175a9aa0d4900c7b2b610d03930fee78705.tar.gz master-187ad058-a8d08175a9aa0d4900c7b2b610d03930fee78705.tar.bz2 master-187ad058-a8d08175a9aa0d4900c7b2b610d03930fee78705.zip |
ath9k: fix a rare use-after-free bug
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@31690 3c298f89-4303-0410-b956-a3cf2f4a3e73
-rw-r--r-- | package/mac80211/patches/561-ath9k_fix_tid_buffer_free.patch | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/package/mac80211/patches/561-ath9k_fix_tid_buffer_free.patch b/package/mac80211/patches/561-ath9k_fix_tid_buffer_free.patch new file mode 100644 index 0000000000..fd0bfa9f17 --- /dev/null +++ b/package/mac80211/patches/561-ath9k_fix_tid_buffer_free.patch @@ -0,0 +1,67 @@ +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -64,7 +64,8 @@ static void ath_tx_update_baw(struct ath + static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, + struct ath_txq *txq, + struct ath_atx_tid *tid, +- struct sk_buff *skb); ++ struct sk_buff *skb, ++ bool dequeue); + + enum { + MCS_HT20, +@@ -821,7 +822,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_ + fi = get_frame_info(skb); + bf = fi->bf; + if (!fi->bf) +- bf = ath_tx_setup_buffer(sc, txq, tid, skb); ++ bf = ath_tx_setup_buffer(sc, txq, tid, skb, true); + + if (!bf) + continue; +@@ -1737,7 +1738,7 @@ static void ath_tx_send_ampdu(struct ath + return; + } + +- bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb); ++ bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb, false); + if (!bf) + return; + +@@ -1766,7 +1767,7 @@ static void ath_tx_send_normal(struct at + + bf = fi->bf; + if (!bf) +- bf = ath_tx_setup_buffer(sc, txq, tid, skb); ++ bf = ath_tx_setup_buffer(sc, txq, tid, skb, false); + + if (!bf) + return; +@@ -1827,7 +1828,8 @@ u8 ath_txchainmask_reduction(struct ath_ + static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, + struct ath_txq *txq, + struct ath_atx_tid *tid, +- struct sk_buff *skb) ++ struct sk_buff *skb, ++ bool dequeue) + { + struct ath_common *common = ath9k_hw_common(sc->sc_ah); + struct ath_frame_info *fi = get_frame_info(skb); +@@ -1876,6 +1878,8 @@ static struct ath_buf *ath_tx_setup_buff + return bf; + + error: ++ if (dequeue) ++ __skb_unlink(skb, &tid->buf_q); + dev_kfree_skb_any(skb); + return NULL; + } +@@ -1895,7 +1899,7 @@ static void ath_tx_start_dma(struct ath_ + */ + ath_tx_send_ampdu(sc, tid, skb, txctl); + } else { +- bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb); ++ bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb, false); + if (!bf) + return; + |