Skip to content

Commit

Permalink
ath9k_htc: properly set MAC address and BSSID mask
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Mathy Vanhoef authored and John W. Linville committed Dec 17, 2013
1 parent b6a1580 commit 657eb17
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 10 deletions.
25 changes: 17 additions & 8 deletions drivers/net/wireless/ath/ath9k/htc_drv_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,21 +127,26 @@ static void ath9k_htc_bssid_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
struct ath9k_vif_iter_data *iter_data = data;
int i;

for (i = 0; i < ETH_ALEN; i++)
iter_data->mask[i] &= ~(iter_data->hw_macaddr[i] ^ mac[i]);
if (iter_data->hw_macaddr != NULL) {
for (i = 0; i < ETH_ALEN; i++)
iter_data->mask[i] &= ~(iter_data->hw_macaddr[i] ^ mac[i]);
} else {
iter_data->hw_macaddr = mac;
}
}

static void ath9k_htc_set_bssid_mask(struct ath9k_htc_priv *priv,
static void ath9k_htc_set_mac_bssid_mask(struct ath9k_htc_priv *priv,
struct ieee80211_vif *vif)
{
struct ath_common *common = ath9k_hw_common(priv->ah);
struct ath9k_vif_iter_data iter_data;

/*
* Use the hardware MAC address as reference, the hardware uses it
* together with the BSSID mask when matching addresses.
* Pick the MAC address of the first interface as the new hardware
* MAC address. The hardware will use it together with the BSSID mask
* when matching addresses.
*/
iter_data.hw_macaddr = common->macaddr;
iter_data.hw_macaddr = NULL;
memset(&iter_data.mask, 0xff, ETH_ALEN);

if (vif)
Expand All @@ -153,6 +158,10 @@ static void ath9k_htc_set_bssid_mask(struct ath9k_htc_priv *priv,
ath9k_htc_bssid_iter, &iter_data);

memcpy(common->bssidmask, iter_data.mask, ETH_ALEN);

if (iter_data.hw_macaddr)
memcpy(common->macaddr, iter_data.hw_macaddr, ETH_ALEN);

ath_hw_setbssidmask(common);
}

Expand Down Expand Up @@ -1063,7 +1072,7 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw,
goto out;
}

ath9k_htc_set_bssid_mask(priv, vif);
ath9k_htc_set_mac_bssid_mask(priv, vif);

priv->vif_slot |= (1 << avp->index);
priv->nvifs++;
Expand Down Expand Up @@ -1128,7 +1137,7 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,

ath9k_htc_set_opmode(priv);

ath9k_htc_set_bssid_mask(priv, vif);
ath9k_htc_set_mac_bssid_mask(priv, vif);

/*
* Stop ANI only if there are no associated station interfaces.
Expand Down
5 changes: 3 additions & 2 deletions drivers/net/wireless/ath/ath9k/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -965,8 +965,9 @@ void ath9k_calculate_iter_data(struct ieee80211_hw *hw,
struct ath_common *common = ath9k_hw_common(ah);

/*
* Use the hardware MAC address as reference, the hardware uses it
* together with the BSSID mask when matching addresses.
* Pick the MAC address of the first interface as the new hardware
* MAC address. The hardware will use it together with the BSSID mask
* when matching addresses.
*/
memset(iter_data, 0, sizeof(*iter_data));
memset(&iter_data->mask, 0xff, ETH_ALEN);
Expand Down

0 comments on commit 657eb17

Please sign in to comment.