| From f63ee308d00f86a66b802cceffd2172d984a95d0 Mon Sep 17 00:00:00 2001 |
| From: Johannes Berg <johannes.berg@intel.com> |
| Date: Mon, 2 Jan 2017 11:19:29 +0100 |
| Subject: [PATCH] mac80211: initialize fast-xmit 'info' later |
| |
| commit 35f432a03e41d3bf08c51ede917f94e2288fbe8c upstream. |
| |
| In ieee80211_xmit_fast(), 'info' is initialized to point to the skb |
| that's passed in, but that skb may later be replaced by a clone (if |
| it was shared), leading to an invalid pointer. |
| |
| This can lead to use-after-free and also later crashes since the |
| real SKB's info->hw_queue doesn't get initialized properly. |
| |
| Fix this by assigning info only later, when it's needed, after the |
| skb replacement (may have) happened. |
| |
| Cc: stable@vger.kernel.org |
| Reported-by: Ben Greear <greearb@candelatech.com> |
| Signed-off-by: Johannes Berg <johannes.berg@intel.com> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c |
| index 18b285e06bc8..f6c805135708 100644 |
| --- a/net/mac80211/tx.c |
| +++ b/net/mac80211/tx.c |
| @@ -3194,7 +3194,7 @@ static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, |
| int extra_head = fast_tx->hdr_len - (ETH_HLEN - 2); |
| int hw_headroom = sdata->local->hw.extra_tx_headroom; |
| struct ethhdr eth; |
| - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
| + struct ieee80211_tx_info *info; |
| struct ieee80211_hdr *hdr = (void *)fast_tx->hdr; |
| struct ieee80211_tx_data tx; |
| ieee80211_tx_result r; |
| @@ -3260,6 +3260,7 @@ static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, |
| memcpy(skb->data + fast_tx->da_offs, eth.h_dest, ETH_ALEN); |
| memcpy(skb->data + fast_tx->sa_offs, eth.h_source, ETH_ALEN); |
| |
| + info = IEEE80211_SKB_CB(skb); |
| memset(info, 0, sizeof(*info)); |
| info->band = fast_tx->band; |
| info->control.vif = &sdata->vif; |
| -- |
| 2.10.1 |
| |