aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMathy Vanhoef <vanhoefm@gmail.com>2013-11-28 06:21:45 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-01-09 15:24:22 -0500
commitd5985f143875f7d4dc718fa664b70666667877d9 (patch)
treef83ff1848f63bd3d2583943d387f3235b7c9ff63
parent12bc42c524f045e914b0ee0cfb3eab33646e1acf (diff)
ath9k_htc: properly set MAC address and BSSID mask
commit 657eb17d87852c42b55c4b06d5425baa08b2ddb3 upstream. Pick the MAC address of the first virtual interface as the new hardware MAC address. Set BSSID mask according to this MAC address. This fixes CVE-2013-4579. Signed-off-by: Mathy Vanhoef <vanhoefm@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c25
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c5
2 files changed, 20 insertions, 10 deletions
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index 62f1b7636c92..21e7edc7207c 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -145,21 +145,26 @@ static void ath9k_htc_bssid_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
145 struct ath9k_vif_iter_data *iter_data = data; 145 struct ath9k_vif_iter_data *iter_data = data;
146 int i; 146 int i;
147 147
148 for (i = 0; i < ETH_ALEN; i++) 148 if (iter_data->hw_macaddr != NULL) {
149 iter_data->mask[i] &= ~(iter_data->hw_macaddr[i] ^ mac[i]); 149 for (i = 0; i < ETH_ALEN; i++)
150 iter_data->mask[i] &= ~(iter_data->hw_macaddr[i] ^ mac[i]);
151 } else {
152 iter_data->hw_macaddr = mac;
153 }
150} 154}
151 155
152static void ath9k_htc_set_bssid_mask(struct ath9k_htc_priv *priv, 156static void ath9k_htc_set_mac_bssid_mask(struct ath9k_htc_priv *priv,
153 struct ieee80211_vif *vif) 157 struct ieee80211_vif *vif)
154{ 158{
155 struct ath_common *common = ath9k_hw_common(priv->ah); 159 struct ath_common *common = ath9k_hw_common(priv->ah);
156 struct ath9k_vif_iter_data iter_data; 160 struct ath9k_vif_iter_data iter_data;
157 161
158 /* 162 /*
159 * Use the hardware MAC address as reference, the hardware uses it 163 * Pick the MAC address of the first interface as the new hardware
160 * together with the BSSID mask when matching addresses. 164 * MAC address. The hardware will use it together with the BSSID mask
165 * when matching addresses.
161 */ 166 */
162 iter_data.hw_macaddr = common->macaddr; 167 iter_data.hw_macaddr = NULL;
163 memset(&iter_data.mask, 0xff, ETH_ALEN); 168 memset(&iter_data.mask, 0xff, ETH_ALEN);
164 169
165 if (vif) 170 if (vif)
@@ -171,6 +176,10 @@ static void ath9k_htc_set_bssid_mask(struct ath9k_htc_priv *priv,
171 ath9k_htc_bssid_iter, &iter_data); 176 ath9k_htc_bssid_iter, &iter_data);
172 177
173 memcpy(common->bssidmask, iter_data.mask, ETH_ALEN); 178 memcpy(common->bssidmask, iter_data.mask, ETH_ALEN);
179
180 if (iter_data.hw_macaddr)
181 memcpy(common->macaddr, iter_data.hw_macaddr, ETH_ALEN);
182
174 ath_hw_setbssidmask(common); 183 ath_hw_setbssidmask(common);
175} 184}
176 185
@@ -1076,7 +1085,7 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw,
1076 goto out; 1085 goto out;
1077 } 1086 }
1078 1087
1079 ath9k_htc_set_bssid_mask(priv, vif); 1088 ath9k_htc_set_mac_bssid_mask(priv, vif);
1080 1089
1081 priv->vif_slot |= (1 << avp->index); 1090 priv->vif_slot |= (1 << avp->index);
1082 priv->nvifs++; 1091 priv->nvifs++;
@@ -1139,7 +1148,7 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
1139 1148
1140 ath9k_htc_set_opmode(priv); 1149 ath9k_htc_set_opmode(priv);
1141 1150
1142 ath9k_htc_set_bssid_mask(priv, vif); 1151 ath9k_htc_set_mac_bssid_mask(priv, vif);
1143 1152
1144 /* 1153 /*
1145 * Stop ANI only if there are no associated station interfaces. 1154 * Stop ANI only if there are no associated station interfaces.
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index a8fee08479ef..82a1b5b16b62 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -889,8 +889,9 @@ void ath9k_calculate_iter_data(struct ieee80211_hw *hw,
889 struct ath_common *common = ath9k_hw_common(ah); 889 struct ath_common *common = ath9k_hw_common(ah);
890 890
891 /* 891 /*
892 * Use the hardware MAC address as reference, the hardware uses it 892 * Pick the MAC address of the first interface as the new hardware
893 * together with the BSSID mask when matching addresses. 893 * MAC address. The hardware will use it together with the BSSID mask
894 * when matching addresses.
894 */ 895 */
895 memset(iter_data, 0, sizeof(*iter_data)); 896 memset(iter_data, 0, sizeof(*iter_data));
896 memset(&iter_data->mask, 0xff, ETH_ALEN); 897 memset(&iter_data->mask, 0xff, ETH_ALEN);