mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-29 15:42:46 +00:00
iwlwifi: mvm: fix potential SKB leak on TXQ TX
commitdf2378ab0f
upstream. When we transmit after TXQ dequeue, we aren't paying attention to the return value of the transmit functions, leading to a potential SKB leak. Refactor the code a bit (and rename ..._tx to ..._tx_sta) to check for this happening. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Fixes:cfbc6c4c5b
("iwlwifi: mvm: support mac80211 TXQs model") Signed-off-by: Luca Coelho <luciano.coelho@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
1e3c082df3
commit
503b54ab96
3 changed files with 20 additions and 16 deletions
|
@ -742,6 +742,20 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
|
||||
struct ieee80211_sta *sta)
|
||||
{
|
||||
if (likely(sta)) {
|
||||
if (likely(iwl_mvm_tx_skb_sta(mvm, skb, sta) == 0))
|
||||
return;
|
||||
} else {
|
||||
if (likely(iwl_mvm_tx_skb_non_sta(mvm, skb) == 0))
|
||||
return;
|
||||
}
|
||||
|
||||
ieee80211_free_txskb(mvm->hw, skb);
|
||||
}
|
||||
|
||||
static void iwl_mvm_mac_tx(struct ieee80211_hw *hw,
|
||||
struct ieee80211_tx_control *control,
|
||||
struct sk_buff *skb)
|
||||
|
@ -785,14 +799,7 @@ static void iwl_mvm_mac_tx(struct ieee80211_hw *hw,
|
|||
}
|
||||
}
|
||||
|
||||
if (sta) {
|
||||
if (iwl_mvm_tx_skb(mvm, skb, sta))
|
||||
goto drop;
|
||||
return;
|
||||
}
|
||||
|
||||
if (iwl_mvm_tx_skb_non_sta(mvm, skb))
|
||||
goto drop;
|
||||
iwl_mvm_tx_skb(mvm, skb, sta);
|
||||
return;
|
||||
drop:
|
||||
ieee80211_free_txskb(hw, skb);
|
||||
|
@ -842,10 +849,7 @@ void iwl_mvm_mac_itxq_xmit(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
|
|||
break;
|
||||
}
|
||||
|
||||
if (!txq->sta)
|
||||
iwl_mvm_tx_skb_non_sta(mvm, skb);
|
||||
else
|
||||
iwl_mvm_tx_skb(mvm, skb, txq->sta);
|
||||
iwl_mvm_tx_skb(mvm, skb, txq->sta);
|
||||
}
|
||||
} while (atomic_dec_return(&mvmtxq->tx_request));
|
||||
rcu_read_unlock();
|
||||
|
|
|
@ -1508,8 +1508,8 @@ int __must_check iwl_mvm_send_cmd_status(struct iwl_mvm *mvm,
|
|||
int __must_check iwl_mvm_send_cmd_pdu_status(struct iwl_mvm *mvm, u32 id,
|
||||
u16 len, const void *data,
|
||||
u32 *status);
|
||||
int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
|
||||
struct ieee80211_sta *sta);
|
||||
int iwl_mvm_tx_skb_sta(struct iwl_mvm *mvm, struct sk_buff *skb,
|
||||
struct ieee80211_sta *sta);
|
||||
int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb);
|
||||
void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,
|
||||
struct iwl_tx_cmd *tx_cmd,
|
||||
|
|
|
@ -1203,8 +1203,8 @@ static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb,
|
|||
return -1;
|
||||
}
|
||||
|
||||
int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
|
||||
struct ieee80211_sta *sta)
|
||||
int iwl_mvm_tx_skb_sta(struct iwl_mvm *mvm, struct sk_buff *skb,
|
||||
struct ieee80211_sta *sta)
|
||||
{
|
||||
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
|
||||
struct ieee80211_tx_info info;
|
||||
|
|
Loading…
Reference in a new issue