From 424ea5d784d063260b4657d39dba175f47e548d2 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 19 Feb 2016 22:06:15 +0100 Subject: [PATCH] mt7603: fix double-free in tx status path Signed-off-by: Felix Fietkau --- mt7603.h | 5 +++-- mt7603_mac.c | 35 ++++++++++++++++++++--------------- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/mt7603.h b/mt7603.h index 42fbbb1b..2ded8b6d 100644 --- a/mt7603.h +++ b/mt7603.h @@ -72,8 +72,9 @@ struct mt7603_vif { struct mt7603_sta sta; }; -#define MT7603_CB_DMA_DONE BIT(0) -#define MT7603_CB_TXS_DONE BIT(1) +#define MT7603_CB_DMA_DONE BIT(0) +#define MT7603_CB_TXS_DONE BIT(1) +#define MT7603_CB_TXS_FAILED BIT(2) struct mt7603_cb { struct list_head list; diff --git a/mt7603_mac.c b/mt7603_mac.c index 0fdc2e27..d2ef5557 100644 --- a/mt7603_mac.c +++ b/mt7603_mac.c @@ -615,6 +615,24 @@ mt7603_fill_txs(struct mt7603_dev *dev, struct mt7603_sta *sta, sta->ampdu_acked = 0; } +static void +mt7603_skb_done(struct mt7603_dev *dev, struct sk_buff *skb, u8 flags) +{ + struct mt7603_cb *cb = mt7603_skb_cb(skb); + u8 done = MT7603_CB_DMA_DONE | MT7603_CB_TXS_DONE; + + flags |= cb->flags; + cb->flags = flags; + + if ((flags & done) != done) + return; + + if (flags & MT7603_CB_TXS_FAILED) + ieee80211_free_txskb(mt76_hw(dev), skb); + else + ieee80211_tx_status(mt76_hw(dev), skb); +} + struct sk_buff * mt7603_mac_status_skb(struct mt7603_dev *dev, struct mt7603_sta *sta, int pktid) { @@ -631,27 +649,14 @@ mt7603_mac_status_skb(struct mt7603_dev *dev, struct mt7603_sta *sta, int pktid) if (cb->pktid == pktid) break; - ieee80211_free_txskb(mt76_hw(dev), skb); + mt7603_skb_done(dev, skb, + MT7603_CB_TXS_FAILED | MT7603_CB_TXS_DONE); skb = NULL; } return skb; } -static void -mt7603_skb_done(struct mt7603_dev *dev, struct sk_buff *skb, u8 flags) -{ - struct mt7603_cb *cb = mt7603_skb_cb(skb); - - flags |= cb->flags; - cb->flags = flags; - - if (flags != (MT7603_CB_DMA_DONE | MT7603_CB_TXS_DONE)) - return; - - ieee80211_tx_status(mt76_hw(dev), skb); -} - static bool mt7603_mac_add_txs_skb(struct mt7603_dev *dev, struct mt7603_sta *sta, int pid, __le32 *txs_data)