840-brcmfmac-avoid-writing-channel-out-of-allocated-arra.patch 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <[email protected]>
  2. Date: Wed, 4 Jan 2017 12:09:41 +0100
  3. Subject: [PATCH] brcmfmac: avoid writing channel out of allocated array
  4. MIME-Version: 1.0
  5. Content-Type: text/plain; charset=UTF-8
  6. Content-Transfer-Encoding: 8bit
  7. Our code was assigning number of channels to the index variable by
  8. default. If firmware reported channel we didn't predict this would
  9. result in using that initial index value and writing out of array. This
  10. never happened so far (we got a complete list of supported channels) but
  11. it means possible memory corruption so we should handle it anyway.
  12. This patch simply detects unexpected channel and ignores it.
  13. As we don't try to create new entry now, it's also safe to drop hw_value
  14. and center_freq assignment. For known channels we have these set anyway.
  15. I decided to fix this issue by assigning NULL or a target channel to the
  16. channel variable. This was one of possible ways, I prefefred this one as
  17. it also avoids using channel[index] over and over.
  18. Fixes: 58de92d2f95e ("brcmfmac: use static superset of channels for wiphy bands")
  19. Signed-off-by: Rafał Miłecki <[email protected]>
  20. Acked-by: Arend van Spriel <[email protected]>
  21. ---
  22. --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
  23. +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
  24. @@ -5913,7 +5913,6 @@ static int brcmf_construct_chaninfo(stru
  25. u32 i, j;
  26. u32 total;
  27. u32 chaninfo;
  28. - u32 index;
  29. pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
  30. @@ -5961,33 +5960,36 @@ static int brcmf_construct_chaninfo(stru
  31. ch.bw == BRCMU_CHAN_BW_80)
  32. continue;
  33. - channel = band->channels;
  34. - index = band->n_channels;
  35. + channel = NULL;
  36. for (j = 0; j < band->n_channels; j++) {
  37. - if (channel[j].hw_value == ch.control_ch_num) {
  38. - index = j;
  39. + if (band->channels[j].hw_value == ch.control_ch_num) {
  40. + channel = &band->channels[j];
  41. break;
  42. }
  43. }
  44. - channel[index].center_freq =
  45. - ieee80211_channel_to_frequency(ch.control_ch_num,
  46. - band->band);
  47. - channel[index].hw_value = ch.control_ch_num;
  48. + if (!channel) {
  49. + /* It seems firmware supports some channel we never
  50. + * considered. Something new in IEEE standard?
  51. + */
  52. + brcmf_err("Ignoring unexpected firmware channel %d\n",
  53. + ch.control_ch_num);
  54. + continue;
  55. + }
  56. /* assuming the chanspecs order is HT20,
  57. * HT40 upper, HT40 lower, and VHT80.
  58. */
  59. if (ch.bw == BRCMU_CHAN_BW_80) {
  60. - channel[index].flags &= ~IEEE80211_CHAN_NO_80MHZ;
  61. + channel->flags &= ~IEEE80211_CHAN_NO_80MHZ;
  62. } else if (ch.bw == BRCMU_CHAN_BW_40) {
  63. - brcmf_update_bw40_channel_flag(&channel[index], &ch);
  64. + brcmf_update_bw40_channel_flag(channel, &ch);
  65. } else {
  66. /* enable the channel and disable other bandwidths
  67. * for now as mentioned order assure they are enabled
  68. * for subsequent chanspecs.
  69. */
  70. - channel[index].flags = IEEE80211_CHAN_NO_HT40 |
  71. - IEEE80211_CHAN_NO_80MHZ;
  72. + channel->flags = IEEE80211_CHAN_NO_HT40 |
  73. + IEEE80211_CHAN_NO_80MHZ;
  74. ch.bw = BRCMU_CHAN_BW_20;
  75. cfg->d11inf.encchspec(&ch);
  76. chaninfo = ch.chspec;
  77. @@ -5995,11 +5997,11 @@ static int brcmf_construct_chaninfo(stru
  78. &chaninfo);
  79. if (!err) {
  80. if (chaninfo & WL_CHAN_RADAR)
  81. - channel[index].flags |=
  82. + channel->flags |=
  83. (IEEE80211_CHAN_RADAR |
  84. IEEE80211_CHAN_NO_IR);
  85. if (chaninfo & WL_CHAN_PASSIVE)
  86. - channel[index].flags |=
  87. + channel->flags |=
  88. IEEE80211_CHAN_NO_IR;
  89. }
  90. }