diff options
Diffstat (limited to 'package/kernel/mac80211/patches/840-brcmfmac-avoid-writing-channel-out-of-allocated-arra.patch')
-rw-r--r-- | package/kernel/mac80211/patches/840-brcmfmac-avoid-writing-channel-out-of-allocated-arra.patch | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/package/kernel/mac80211/patches/840-brcmfmac-avoid-writing-channel-out-of-allocated-arra.patch b/package/kernel/mac80211/patches/840-brcmfmac-avoid-writing-channel-out-of-allocated-arra.patch new file mode 100644 index 0000000000..8456a1364c --- /dev/null +++ b/package/kernel/mac80211/patches/840-brcmfmac-avoid-writing-channel-out-of-allocated-arra.patch @@ -0,0 +1,100 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> +Date: Wed, 4 Jan 2017 12:09:41 +0100 +Subject: [PATCH] brcmfmac: avoid writing channel out of allocated array +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Our code was assigning number of channels to the index variable by +default. If firmware reported channel we didn't predict this would +result in using that initial index value and writing out of array. This +never happened so far (we got a complete list of supported channels) but +it means possible memory corruption so we should handle it anyway. + +This patch simply detects unexpected channel and ignores it. + +As we don't try to create new entry now, it's also safe to drop hw_value +and center_freq assignment. For known channels we have these set anyway. + +I decided to fix this issue by assigning NULL or a target channel to the +channel variable. This was one of possible ways, I prefefred this one as +it also avoids using channel[index] over and over. + +Fixes: 58de92d2f95e ("brcmfmac: use static superset of channels for wiphy bands") +Signed-off-by: Rafał Miłecki <rafal@milecki.pl> +Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com> +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -5913,7 +5913,6 @@ static int brcmf_construct_chaninfo(stru + u32 i, j; + u32 total; + u32 chaninfo; +- u32 index; + + pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL); + +@@ -5961,33 +5960,36 @@ static int brcmf_construct_chaninfo(stru + ch.bw == BRCMU_CHAN_BW_80) + continue; + +- channel = band->channels; +- index = band->n_channels; ++ channel = NULL; + for (j = 0; j < band->n_channels; j++) { +- if (channel[j].hw_value == ch.control_ch_num) { +- index = j; ++ if (band->channels[j].hw_value == ch.control_ch_num) { ++ channel = &band->channels[j]; + break; + } + } +- channel[index].center_freq = +- ieee80211_channel_to_frequency(ch.control_ch_num, +- band->band); +- channel[index].hw_value = ch.control_ch_num; ++ if (!channel) { ++ /* It seems firmware supports some channel we never ++ * considered. Something new in IEEE standard? ++ */ ++ brcmf_err("Ignoring unexpected firmware channel %d\n", ++ ch.control_ch_num); ++ continue; ++ } + + /* assuming the chanspecs order is HT20, + * HT40 upper, HT40 lower, and VHT80. + */ + if (ch.bw == BRCMU_CHAN_BW_80) { +- channel[index].flags &= ~IEEE80211_CHAN_NO_80MHZ; ++ channel->flags &= ~IEEE80211_CHAN_NO_80MHZ; + } else if (ch.bw == BRCMU_CHAN_BW_40) { +- brcmf_update_bw40_channel_flag(&channel[index], &ch); ++ brcmf_update_bw40_channel_flag(channel, &ch); + } else { + /* enable the channel and disable other bandwidths + * for now as mentioned order assure they are enabled + * for subsequent chanspecs. + */ +- channel[index].flags = IEEE80211_CHAN_NO_HT40 | +- IEEE80211_CHAN_NO_80MHZ; ++ channel->flags = IEEE80211_CHAN_NO_HT40 | ++ IEEE80211_CHAN_NO_80MHZ; + ch.bw = BRCMU_CHAN_BW_20; + cfg->d11inf.encchspec(&ch); + chaninfo = ch.chspec; +@@ -5995,11 +5997,11 @@ static int brcmf_construct_chaninfo(stru + &chaninfo); + if (!err) { + if (chaninfo & WL_CHAN_RADAR) +- channel[index].flags |= ++ channel->flags |= + (IEEE80211_CHAN_RADAR | + IEEE80211_CHAN_NO_IR); + if (chaninfo & WL_CHAN_PASSIVE) +- channel[index].flags |= ++ channel->flags |= + IEEE80211_CHAN_NO_IR; + } + } |