aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2014-11-18 16:35:31 -0500
committerJohannes Berg <johannes.berg@intel.com>2014-11-18 16:39:16 -0500
commit280ba51d60be6f4ca3347eaa60783314f38df72e (patch)
tree4b6f66ce8187b59e755f02f14ffd5d488b6084df /net
parent4f031fa9f188b2b0641ac20087d9e16bcfb4e49d (diff)
mac80211: minstrel_ht: fix a crash in rate sorting
The commit 5935839ad73583781b8bbe8d91412f6826e218a4 "mac80211: improve minstrel_ht rate sorting by throughput & probability" introduced a crash on rate sorting that occurs when the rate added to the sorting array is faster than all the previous rates. Due to an off-by-one error, it reads the rate index from tp_list[-1], which contains uninitialized stack garbage, and then uses the resulting index for accessing the group rate stats, leading to a crash if the garbage value is big enough. Cc: Thomas Huehn <thomas@net.t-labs.tu-berlin.de> Reported-by: Jouni Malinen <j@w1.fi> Signed-off-by: Felix Fietkau <nbd@openwrt.org> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/rc80211_minstrel_ht.c15
1 files changed, 6 insertions, 9 deletions
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index df90ce2db00c..408fd8ab4eef 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -252,19 +252,16 @@ minstrel_ht_sort_best_tp_rates(struct minstrel_ht_sta *mi, u8 index,
252 cur_thr = mi->groups[cur_group].rates[cur_idx].cur_tp; 252 cur_thr = mi->groups[cur_group].rates[cur_idx].cur_tp;
253 cur_prob = mi->groups[cur_group].rates[cur_idx].probability; 253 cur_prob = mi->groups[cur_group].rates[cur_idx].probability;
254 254
255 tmp_group = tp_list[j - 1] / MCS_GROUP_RATES; 255 do {
256 tmp_idx = tp_list[j - 1] % MCS_GROUP_RATES;
257 tmp_thr = mi->groups[tmp_group].rates[tmp_idx].cur_tp;
258 tmp_prob = mi->groups[tmp_group].rates[tmp_idx].probability;
259
260 while (j > 0 && (cur_thr > tmp_thr ||
261 (cur_thr == tmp_thr && cur_prob > tmp_prob))) {
262 j--;
263 tmp_group = tp_list[j - 1] / MCS_GROUP_RATES; 256 tmp_group = tp_list[j - 1] / MCS_GROUP_RATES;
264 tmp_idx = tp_list[j - 1] % MCS_GROUP_RATES; 257 tmp_idx = tp_list[j - 1] % MCS_GROUP_RATES;
265 tmp_thr = mi->groups[tmp_group].rates[tmp_idx].cur_tp; 258 tmp_thr = mi->groups[tmp_group].rates[tmp_idx].cur_tp;
266 tmp_prob = mi->groups[tmp_group].rates[tmp_idx].probability; 259 tmp_prob = mi->groups[tmp_group].rates[tmp_idx].probability;
267 } 260 if (cur_thr < tmp_thr ||
261 (cur_thr == tmp_thr && cur_prob <= tmp_prob))
262 break;
263 j--;
264 } while (j > 0);
268 265
269 if (j < MAX_THR_RATES - 1) { 266 if (j < MAX_THR_RATES - 1) {
270 memmove(&tp_list[j + 1], &tp_list[j], (sizeof(*tp_list) * 267 memmove(&tp_list[j + 1], &tp_list[j], (sizeof(*tp_list) *