From: Felix Fietkau <nbd@openwrt.org>
Date: Tue, 18 Nov 2014 22:20:50 +0000 (+0000)
Subject: mac80211: fix a crash bug in minstrel_ht
X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=49aca2431c7432aa976d38a2b342d50602c68c60;p=openwrt%2Fstaging%2Frobimarko.git

mac80211: fix a crash bug in minstrel_ht

Signed-off-by: Felix Fietkau <nbd@openwrt.org>

SVN-Revision: 43298
---

diff --git a/package/kernel/mac80211/patches/319-mac80211-minstrel_ht-fix-a-crash-in-rate-sorting.patch b/package/kernel/mac80211/patches/319-mac80211-minstrel_ht-fix-a-crash-in-rate-sorting.patch
new file mode 100644
index 0000000000..784a973e0e
--- /dev/null
+++ b/package/kernel/mac80211/patches/319-mac80211-minstrel_ht-fix-a-crash-in-rate-sorting.patch
@@ -0,0 +1,47 @@
+From: Felix Fietkau <nbd@openwrt.org>
+Date: Tue, 18 Nov 2014 21:43:25 +0100
+Subject: [PATCH] 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>
+---
+
+--- a/net/mac80211/rc80211_minstrel_ht.c
++++ b/net/mac80211/rc80211_minstrel_ht.c
+@@ -394,19 +394,16 @@ minstrel_ht_sort_best_tp_rates(struct mi
+ 	cur_thr = mi->groups[cur_group].rates[cur_idx].cur_tp;
+ 	cur_prob = mi->groups[cur_group].rates[cur_idx].probability;
+ 
+-	tmp_group = tp_list[j - 1] / MCS_GROUP_RATES;
+-	tmp_idx = tp_list[j - 1] % MCS_GROUP_RATES;
+-	tmp_thr = mi->groups[tmp_group].rates[tmp_idx].cur_tp;
+-	tmp_prob = mi->groups[tmp_group].rates[tmp_idx].probability;
+-
+-	while (j > 0 && (cur_thr > tmp_thr ||
+-	      (cur_thr == tmp_thr && cur_prob > tmp_prob))) {
+-		j--;
++	do {
+ 		tmp_group = tp_list[j - 1] / MCS_GROUP_RATES;
+ 		tmp_idx = tp_list[j - 1] % MCS_GROUP_RATES;
+ 		tmp_thr = mi->groups[tmp_group].rates[tmp_idx].cur_tp;
+ 		tmp_prob = mi->groups[tmp_group].rates[tmp_idx].probability;
+-	}
++		if (cur_thr < tmp_thr ||
++		    (cur_thr == tmp_thr && cur_prob <= tmp_prob))
++			break;
++		j--;
++	} while (j > 0);
+ 
+ 	if (j < MAX_THR_RATES - 1) {
+ 		memmove(&tp_list[j + 1], &tp_list[j], (sizeof(*tp_list) *