123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <[email protected]>
- 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 <[email protected]>
- Acked-by: Arend van Spriel <[email protected]>
- ---
- --- 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;
- }
- }
|