Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 503b54ab authored by Johannes Berg's avatar Johannes Berg Committed by Greg Kroah-Hartman
Browse files

iwlwifi: mvm: fix potential SKB leak on TXQ TX



commit df2378ab0f2a9dd4cf4501268af1902cc4ebacd8 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: 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>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 1e3c082d
Loading
Loading
Loading
Loading
+16 −12
Original line number Diff line number Diff line
@@ -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,9 +849,6 @@ 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);
		}
	} while (atomic_dec_return(&mvmtxq->tx_request));
+2 −2
Original line number Diff line number Diff line
@@ -1508,7 +1508,7 @@ 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,
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,
+2 −2
Original line number Diff line number Diff line
@@ -1203,7 +1203,7 @@ 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,
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);