Commit df2378ab authored by Johannes Berg's avatar Johannes Berg Committed by Luca Coelho

iwlwifi: mvm: fix potential SKB leak on TXQ TX

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: default avatarJohannes Berg <johannes.berg@intel.com>
Fixes: cfbc6c4c ("iwlwifi: mvm: support mac80211 TXQs model")
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
parent b9f726c9
...@@ -755,6 +755,20 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) ...@@ -755,6 +755,20 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
return ret; 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, static void iwl_mvm_mac_tx(struct ieee80211_hw *hw,
struct ieee80211_tx_control *control, struct ieee80211_tx_control *control,
struct sk_buff *skb) struct sk_buff *skb)
...@@ -798,14 +812,7 @@ static void iwl_mvm_mac_tx(struct ieee80211_hw *hw, ...@@ -798,14 +812,7 @@ static void iwl_mvm_mac_tx(struct ieee80211_hw *hw,
} }
} }
if (sta) { iwl_mvm_tx_skb(mvm, skb, sta);
if (iwl_mvm_tx_skb(mvm, skb, sta))
goto drop;
return;
}
if (iwl_mvm_tx_skb_non_sta(mvm, skb))
goto drop;
return; return;
drop: drop:
ieee80211_free_txskb(hw, skb); ieee80211_free_txskb(hw, skb);
...@@ -855,10 +862,7 @@ void iwl_mvm_mac_itxq_xmit(struct ieee80211_hw *hw, struct ieee80211_txq *txq) ...@@ -855,10 +862,7 @@ void iwl_mvm_mac_itxq_xmit(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
break; break;
} }
if (!txq->sta) iwl_mvm_tx_skb(mvm, skb, txq->sta);
iwl_mvm_tx_skb_non_sta(mvm, skb);
else
iwl_mvm_tx_skb(mvm, skb, txq->sta);
} }
} while (atomic_dec_return(&mvmtxq->tx_request)); } while (atomic_dec_return(&mvmtxq->tx_request));
rcu_read_unlock(); rcu_read_unlock();
......
...@@ -1508,8 +1508,8 @@ int __must_check iwl_mvm_send_cmd_status(struct iwl_mvm *mvm, ...@@ -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, int __must_check iwl_mvm_send_cmd_pdu_status(struct iwl_mvm *mvm, u32 id,
u16 len, const void *data, u16 len, const void *data,
u32 *status); u32 *status);
int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb, int iwl_mvm_tx_skb_sta(struct iwl_mvm *mvm, struct sk_buff *skb,
struct ieee80211_sta *sta); struct ieee80211_sta *sta);
int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb); 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, void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,
struct iwl_tx_cmd *tx_cmd, struct iwl_tx_cmd *tx_cmd,
......
...@@ -1201,8 +1201,8 @@ static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb, ...@@ -1201,8 +1201,8 @@ static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb,
return -1; return -1;
} }
int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb, int iwl_mvm_tx_skb_sta(struct iwl_mvm *mvm, struct sk_buff *skb,
struct ieee80211_sta *sta) struct ieee80211_sta *sta)
{ {
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
struct ieee80211_tx_info info; struct ieee80211_tx_info info;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment