Skip to content

Commit

Permalink
mac80211: reject setting masked mac addresses
Browse files Browse the repository at this point in the history
If a driver registers an address mask we should ensure that no
interface gets an address assigned that isn't covered by the
registered address mask. This prevents invalid configurations
from reaching the device and causing problems.

Signed-off-by: Helmut Schaa <helmut.schaa@googlemail.com>
[change function flow to reduce indentation, fix locking]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
  • Loading branch information
Helmut Schaa authored and Johannes Berg committed Nov 28, 2012
1 parent 0624760 commit 478622e
Showing 1 changed file with 45 additions and 0 deletions.
45 changes: 45 additions & 0 deletions net/mac80211/iface.c
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,47 @@ static int ieee80211_change_mtu(struct net_device *dev, int new_mtu)
return 0;
}

static int ieee80211_verify_mac(struct ieee80211_local *local, u8 *addr)
{
struct ieee80211_sub_if_data *sdata;
u64 new, mask, tmp;
u8 *m;
int ret = 0;

if (is_zero_ether_addr(local->hw.wiphy->addr_mask))
return 0;

m = addr;
new = ((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) |
((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) |
((u64)m[4] << 1*8) | ((u64)m[5] << 0*8);

m = local->hw.wiphy->addr_mask;
mask = ((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) |
((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) |
((u64)m[4] << 1*8) | ((u64)m[5] << 0*8);


mutex_lock(&local->iflist_mtx);
list_for_each_entry(sdata, &local->interfaces, list) {
if (sdata->vif.type == NL80211_IFTYPE_MONITOR)
continue;

m = sdata->vif.addr;
tmp = ((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) |
((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) |
((u64)m[4] << 1*8) | ((u64)m[5] << 0*8);

if ((new & ~mask) != (tmp & ~mask)) {
ret = -EINVAL;
break;
}
}
mutex_unlock(&local->iflist_mtx);

return ret;
}

static int ieee80211_change_mac(struct net_device *dev, void *addr)
{
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
Expand All @@ -232,6 +273,10 @@ static int ieee80211_change_mac(struct net_device *dev, void *addr)
if (ieee80211_sdata_running(sdata))
return -EBUSY;

ret = ieee80211_verify_mac(sdata->local, sa->sa_data);
if (ret)
return ret;

ret = eth_mac_addr(dev, sa);

if (ret == 0)
Expand Down

0 comments on commit 478622e

Please sign in to comment.