Skip to content

Commit 51eb3da

Browse files
ryderlee1110pull[bot]
authored andcommitted
wifi: mac80211: check skb_shared in ieee80211_8023_xmit()
Add a missing skb_shared check into 802.3 path to prevent potential use-after-free from happening. This also uses skb_share_check() instead of open-coding in tx path. Signed-off-by: Ryder Lee <ryder.lee@mediatek.com> Link: https://lore.kernel.org/r/e7a73aaf7742b17e43421c56625646dfc5c4d2cb.1653571902.git.ryder.lee@mediatek.com Signed-off-by: Johannes Berg <johannes.berg@intel.com>
1 parent 58212d7 commit 51eb3da

File tree

1 file changed

+13
-23
lines changed

1 file changed

+13
-23
lines changed

net/mac80211/tx.c

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2818,19 +2818,10 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,
28182818
/*
28192819
* If the skb is shared we need to obtain our own copy.
28202820
*/
2821-
if (skb_shared(skb)) {
2822-
struct sk_buff *tmp_skb = skb;
2823-
2824-
/* can't happen -- skb is a clone if info_id != 0 */
2825-
WARN_ON(info_id);
2826-
2827-
skb = skb_clone(skb, GFP_ATOMIC);
2828-
kfree_skb(tmp_skb);
2829-
2830-
if (!skb) {
2831-
ret = -ENOMEM;
2832-
goto free;
2833-
}
2821+
skb = skb_share_check(skb, GFP_ATOMIC);
2822+
if (unlikely(!skb)) {
2823+
ret = -ENOMEM;
2824+
goto free;
28342825
}
28352826

28362827
hdr.frame_control = fc;
@@ -3539,15 +3530,9 @@ static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata,
35393530

35403531
/* after this point (skb is modified) we cannot return false */
35413532

3542-
if (skb_shared(skb)) {
3543-
struct sk_buff *tmp_skb = skb;
3544-
3545-
skb = skb_clone(skb, GFP_ATOMIC);
3546-
kfree_skb(tmp_skb);
3547-
3548-
if (!skb)
3549-
return true;
3550-
}
3533+
skb = skb_share_check(skb, GFP_ATOMIC);
3534+
if (unlikely(!skb))
3535+
return true;
35513536

35523537
if ((hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) &&
35533538
ieee80211_amsdu_aggregate(sdata, sta, fast_tx, skb))
@@ -4437,7 +4422,7 @@ static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata,
44374422
struct net_device *dev, struct sta_info *sta,
44384423
struct ieee80211_key *key, struct sk_buff *skb)
44394424
{
4440-
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
4425+
struct ieee80211_tx_info *info;
44414426
struct ieee80211_local *local = sdata->local;
44424427
struct tid_ampdu_tx *tid_tx;
44434428
u8 tid;
@@ -4452,6 +4437,11 @@ static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata,
44524437
test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state))
44534438
goto out_free;
44544439

4440+
skb = skb_share_check(skb, GFP_ATOMIC);
4441+
if (unlikely(!skb))
4442+
return;
4443+
4444+
info = IEEE80211_SKB_CB(skb);
44554445
memset(info, 0, sizeof(*info));
44564446

44574447
ieee80211_aggr_check(sdata, sta, skb);

0 commit comments

Comments
 (0)