mirror of
https://github.com/torvalds/linux.git
synced 2026-09-24 06:24:02 +02:00
wifi: mac80211: set up the TX info early to fix failure paths
The previous commit2c51457d93("wifi: mac80211: free ack status frame on TX header build failure") cleaned up the leak, but still left the code a bit messy and the failed SKB didn't get reported to userspace. Fix this up by initialising skb->cb[] earlier, which allows using ieee80211_free_txskb() and therefore reports it for the failure in ieee80211_build_hdr(), and unifies the ieee80211_skb_resize() failure path with it. Assisted-by: LLM Fixes:c3e7724b6b("mac80211: use ieee80211_free_txskb to fix possible skb leaks") Link: https://patch.msgid.link/20260908122838.201719-22-johannes@sipsolutions.net Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
ae97fff649
commit
50d3d79dc0
|
|
@ -2981,10 +2981,23 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,
|
|||
*/
|
||||
skb = skb_share_check(skb, GFP_ATOMIC);
|
||||
if (unlikely(!skb)) {
|
||||
ret = -ENOMEM;
|
||||
goto free;
|
||||
/* skb_share_check() already freed the skb */
|
||||
if (info_id)
|
||||
ieee80211_remove_ack_skb(local, info_id);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
/* set this up so failure paths can clean up ack skb */
|
||||
info = IEEE80211_SKB_CB(skb);
|
||||
memset(info, 0, sizeof(*info));
|
||||
|
||||
info->flags = info_flags;
|
||||
if (info_id) {
|
||||
info->status_data = info_id;
|
||||
info->status_data_idr = 1;
|
||||
}
|
||||
info->band = band;
|
||||
|
||||
hdr.frame_control = fc;
|
||||
hdr.duration_id = 0;
|
||||
hdr.seq_ctrl = 0;
|
||||
|
|
@ -3023,10 +3036,8 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,
|
|||
head_need += local->tx_headroom;
|
||||
head_need = max_t(int, 0, head_need);
|
||||
if (ieee80211_skb_resize(sdata, skb, head_need, ENCRYPT_DATA)) {
|
||||
ieee80211_free_txskb(&local->hw, skb);
|
||||
skb = NULL;
|
||||
ret = -ENOMEM;
|
||||
goto free;
|
||||
goto free_txskb;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3053,16 +3064,6 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,
|
|||
|
||||
skb_reset_mac_header(skb);
|
||||
|
||||
info = IEEE80211_SKB_CB(skb);
|
||||
memset(info, 0, sizeof(*info));
|
||||
|
||||
info->flags = info_flags;
|
||||
if (info_id) {
|
||||
info->status_data = info_id;
|
||||
info->status_data_idr = 1;
|
||||
}
|
||||
info->band = band;
|
||||
|
||||
if (likely(!cookie)) {
|
||||
ctrl_flags |= u32_encode_bits(link_id,
|
||||
IEEE80211_TX_CTRL_MLO_LINK);
|
||||
|
|
@ -3086,16 +3087,17 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,
|
|||
pre_conf_link_id, link_id);
|
||||
#endif
|
||||
ret = -EINVAL;
|
||||
goto free;
|
||||
goto free_txskb;
|
||||
}
|
||||
}
|
||||
|
||||
info->control.flags = ctrl_flags;
|
||||
|
||||
return skb;
|
||||
free_txskb:
|
||||
ieee80211_free_txskb(&local->hw, skb);
|
||||
return ERR_PTR(ret);
|
||||
free:
|
||||
if (info_id)
|
||||
ieee80211_remove_ack_skb(local, info_id);
|
||||
kfree_skb(skb);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user