Skip to content

Commit d5ad6ab

Browse files
nbd168jmberg-intel
authored andcommitted
wifi: mac80211: always free skb on ieee80211_tx_prepare_skb() failure
ieee80211_tx_prepare_skb() has three error paths, but only two of them free the skb. The first error path (ieee80211_tx_prepare() returning TX_DROP) does not free it, while invoke_tx_handlers() failure and the fragmentation check both do. Add kfree_skb() to the first error path so all three are consistent, and remove the now-redundant frees in callers (ath9k, mt76, mac80211_hwsim) to avoid double-free. Document the skb ownership guarantee in the function's kdoc. Signed-off-by: Felix Fietkau <nbd@nbd.name> Link: https://patch.msgid.link/20260314065455.2462900-1-nbd@nbd.name Fixes: 06be6b1 ("mac80211: add ieee80211_tx_prepare_skb() helper function") Signed-off-by: Johannes Berg <johannes.berg@intel.com>
1 parent deb353d commit d5ad6ab

5 files changed

Lines changed: 9 additions & 10 deletions

File tree

drivers/net/wireless/ath/ath9k/channel.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,7 +1006,7 @@ static void ath_scan_send_probe(struct ath_softc *sc,
10061006
skb_set_queue_mapping(skb, IEEE80211_AC_VO);
10071007

10081008
if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, NULL))
1009-
goto error;
1009+
return;
10101010

10111011
txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO];
10121012
if (ath_tx_start(sc->hw, skb, &txctl))
@@ -1119,10 +1119,8 @@ ath_chanctx_send_vif_ps_frame(struct ath_softc *sc, struct ath_vif *avp,
11191119

11201120
skb->priority = 7;
11211121
skb_set_queue_mapping(skb, IEEE80211_AC_VO);
1122-
if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, &sta)) {
1123-
dev_kfree_skb_any(skb);
1122+
if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, &sta))
11241123
return false;
1125-
}
11261124
break;
11271125
default:
11281126
return false;

drivers/net/wireless/mediatek/mt76/scan.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,8 @@ mt76_scan_send_probe(struct mt76_dev *dev, struct cfg80211_ssid *ssid)
6363

6464
rcu_read_lock();
6565

66-
if (!ieee80211_tx_prepare_skb(phy->hw, vif, skb, band, NULL)) {
67-
ieee80211_free_txskb(phy->hw, skb);
66+
if (!ieee80211_tx_prepare_skb(phy->hw, vif, skb, band, NULL))
6867
goto out;
69-
}
7068

7169
info = IEEE80211_SKB_CB(skb);
7270
if (req->no_cck)

drivers/net/wireless/virtual/mac80211_hwsim.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3021,7 +3021,6 @@ static void hw_scan_work(struct work_struct *work)
30213021
hwsim->tmp_chan->band,
30223022
NULL)) {
30233023
rcu_read_unlock();
3024-
kfree_skb(probe);
30253024
continue;
30263025
}
30273026

include/net/mac80211.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7407,7 +7407,9 @@ void ieee80211_report_wowlan_wakeup(struct ieee80211_vif *vif,
74077407
* @band: the band to transmit on
74087408
* @sta: optional pointer to get the station to send the frame to
74097409
*
7410-
* Return: %true if the skb was prepared, %false otherwise
7410+
* Return: %true if the skb was prepared, %false otherwise.
7411+
* On failure, the skb is freed by this function; callers must not
7412+
* free it again.
74117413
*
74127414
* Note: must be called under RCU lock
74137415
*/

net/mac80211/tx.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1899,8 +1899,10 @@ bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw,
18991899
struct ieee80211_tx_data tx;
19001900
struct sk_buff *skb2;
19011901

1902-
if (ieee80211_tx_prepare(sdata, &tx, NULL, skb) == TX_DROP)
1902+
if (ieee80211_tx_prepare(sdata, &tx, NULL, skb) == TX_DROP) {
1903+
kfree_skb(skb);
19031904
return false;
1905+
}
19041906

19051907
info->band = band;
19061908
info->control.vif = vif;

0 commit comments

Comments
 (0)