ath9k: fix a rare use-after-free bug
[openwrt/svn-archive/archive.git] / package / mac80211 / patches / 561-ath9k_fix_tid_buffer_free.patch
1 --- a/drivers/net/wireless/ath/ath9k/xmit.c
2 +++ b/drivers/net/wireless/ath/ath9k/xmit.c
3 @@ -64,7 +64,8 @@ static void ath_tx_update_baw(struct ath
4 static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
5 struct ath_txq *txq,
6 struct ath_atx_tid *tid,
7 - struct sk_buff *skb);
8 + struct sk_buff *skb,
9 + bool dequeue);
10
11 enum {
12 MCS_HT20,
13 @@ -821,7 +822,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_
14 fi = get_frame_info(skb);
15 bf = fi->bf;
16 if (!fi->bf)
17 - bf = ath_tx_setup_buffer(sc, txq, tid, skb);
18 + bf = ath_tx_setup_buffer(sc, txq, tid, skb, true);
19
20 if (!bf)
21 continue;
22 @@ -1737,7 +1738,7 @@ static void ath_tx_send_ampdu(struct ath
23 return;
24 }
25
26 - bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb);
27 + bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb, false);
28 if (!bf)
29 return;
30
31 @@ -1766,7 +1767,7 @@ static void ath_tx_send_normal(struct at
32
33 bf = fi->bf;
34 if (!bf)
35 - bf = ath_tx_setup_buffer(sc, txq, tid, skb);
36 + bf = ath_tx_setup_buffer(sc, txq, tid, skb, false);
37
38 if (!bf)
39 return;
40 @@ -1827,7 +1828,8 @@ u8 ath_txchainmask_reduction(struct ath_
41 static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
42 struct ath_txq *txq,
43 struct ath_atx_tid *tid,
44 - struct sk_buff *skb)
45 + struct sk_buff *skb,
46 + bool dequeue)
47 {
48 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
49 struct ath_frame_info *fi = get_frame_info(skb);
50 @@ -1876,6 +1878,8 @@ static struct ath_buf *ath_tx_setup_buff
51 return bf;
52
53 error:
54 + if (dequeue)
55 + __skb_unlink(skb, &tid->buf_q);
56 dev_kfree_skb_any(skb);
57 return NULL;
58 }
59 @@ -1895,7 +1899,7 @@ static void ath_tx_start_dma(struct ath_
60 */
61 ath_tx_send_ampdu(sc, tid, skb, txctl);
62 } else {
63 - bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb);
64 + bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb, false);
65 if (!bf)
66 return;
67