Skip to content
/ linux Public

Commit 06e769d

Browse files
nbd168gregkh
authored andcommitted
wifi: mac80211: always free skb on ieee80211_tx_prepare_skb() failure
[ Upstream commit d5ad6ab ] 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> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 46c670f commit 06e769d

File tree

5 files changed

+9
-10
lines changed

5 files changed

+9
-10
lines changed

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
@@ -7289,7 +7289,9 @@ void ieee80211_report_wowlan_wakeup(struct ieee80211_vif *vif,
72897289
* @band: the band to transmit on
72907290
* @sta: optional pointer to get the station to send the frame to
72917291
*
7292-
* Return: %true if the skb was prepared, %false otherwise
7292+
* Return: %true if the skb was prepared, %false otherwise.
7293+
* On failure, the skb is freed by this function; callers must not
7294+
* free it again.
72937295
*
72947296
* Note: must be called under RCU lock
72957297
*/

net/mac80211/tx.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1896,8 +1896,10 @@ bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw,
18961896
struct ieee80211_tx_data tx;
18971897
struct sk_buff *skb2;
18981898

1899-
if (ieee80211_tx_prepare(sdata, &tx, NULL, skb) == TX_DROP)
1899+
if (ieee80211_tx_prepare(sdata, &tx, NULL, skb) == TX_DROP) {
1900+
kfree_skb(skb);
19001901
return false;
1902+
}
19011903

19021904
info->band = band;
19031905
info->control.vif = vif;

0 commit comments

Comments
 (0)