mirror of
https://github.com/adulau/aha.git
synced 2024-12-28 19:56:18 +00:00
cfg80211: validate station settings
When I disallowed interfering with stations on non-AP interfaces, I not only forget mesh but also managed interfaces which need this for the authorized flag. Let's actually validate everything properly. This fixes an nl80211 regression introduced by the interfering, under which wpa_supplicant -Dnl80211 could not properly connect. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
9a5e8bbc8f
commit
a97f4424fb
1 changed files with 78 additions and 16 deletions
|
@ -1687,14 +1687,52 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
|
||||||
if (err)
|
if (err)
|
||||||
goto out_rtnl;
|
goto out_rtnl;
|
||||||
|
|
||||||
if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
|
err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, ¶ms.vlan);
|
||||||
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
|
if (err)
|
||||||
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) {
|
|
||||||
err = -EINVAL;
|
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
/* validate settings */
|
||||||
|
err = 0;
|
||||||
|
|
||||||
|
switch (dev->ieee80211_ptr->iftype) {
|
||||||
|
case NL80211_IFTYPE_AP:
|
||||||
|
case NL80211_IFTYPE_AP_VLAN:
|
||||||
|
/* disallow mesh-specific things */
|
||||||
|
if (params.plink_action)
|
||||||
|
err = -EINVAL;
|
||||||
|
break;
|
||||||
|
case NL80211_IFTYPE_STATION:
|
||||||
|
/* disallow everything but AUTHORIZED flag */
|
||||||
|
if (params.plink_action)
|
||||||
|
err = -EINVAL;
|
||||||
|
if (params.vlan)
|
||||||
|
err = -EINVAL;
|
||||||
|
if (params.supported_rates)
|
||||||
|
err = -EINVAL;
|
||||||
|
if (params.ht_capa)
|
||||||
|
err = -EINVAL;
|
||||||
|
if (params.listen_interval >= 0)
|
||||||
|
err = -EINVAL;
|
||||||
|
if (params.sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED))
|
||||||
|
err = -EINVAL;
|
||||||
|
break;
|
||||||
|
case NL80211_IFTYPE_MESH_POINT:
|
||||||
|
/* disallow things mesh doesn't support */
|
||||||
|
if (params.vlan)
|
||||||
|
err = -EINVAL;
|
||||||
|
if (params.ht_capa)
|
||||||
|
err = -EINVAL;
|
||||||
|
if (params.listen_interval >= 0)
|
||||||
|
err = -EINVAL;
|
||||||
|
if (params.supported_rates)
|
||||||
|
err = -EINVAL;
|
||||||
|
if (params.sta_flags_mask)
|
||||||
|
err = -EINVAL;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
err = -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, ¶ms.vlan);
|
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
@ -1729,9 +1767,6 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
|
||||||
if (!info->attrs[NL80211_ATTR_MAC])
|
if (!info->attrs[NL80211_ATTR_MAC])
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (!info->attrs[NL80211_ATTR_STA_AID])
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (!info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
|
if (!info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
@ -1746,9 +1781,11 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
|
||||||
params.listen_interval =
|
params.listen_interval =
|
||||||
nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
|
nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
|
||||||
|
|
||||||
params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
|
if (info->attrs[NL80211_ATTR_STA_AID]) {
|
||||||
if (!params.aid || params.aid > IEEE80211_MAX_AID)
|
params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
|
||||||
return -EINVAL;
|
if (!params.aid || params.aid > IEEE80211_MAX_AID)
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
|
if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
|
||||||
params.ht_capa =
|
params.ht_capa =
|
||||||
|
@ -1763,14 +1800,39 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
|
||||||
if (err)
|
if (err)
|
||||||
goto out_rtnl;
|
goto out_rtnl;
|
||||||
|
|
||||||
if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
|
err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, ¶ms.vlan);
|
||||||
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
|
if (err)
|
||||||
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) {
|
|
||||||
err = -EINVAL;
|
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
/* validate settings */
|
||||||
|
err = 0;
|
||||||
|
|
||||||
|
switch (dev->ieee80211_ptr->iftype) {
|
||||||
|
case NL80211_IFTYPE_AP:
|
||||||
|
case NL80211_IFTYPE_AP_VLAN:
|
||||||
|
/* all ok but must have AID */
|
||||||
|
if (!params.aid)
|
||||||
|
err = -EINVAL;
|
||||||
|
break;
|
||||||
|
case NL80211_IFTYPE_MESH_POINT:
|
||||||
|
/* disallow things mesh doesn't support */
|
||||||
|
if (params.vlan)
|
||||||
|
err = -EINVAL;
|
||||||
|
if (params.aid)
|
||||||
|
err = -EINVAL;
|
||||||
|
if (params.ht_capa)
|
||||||
|
err = -EINVAL;
|
||||||
|
if (params.listen_interval >= 0)
|
||||||
|
err = -EINVAL;
|
||||||
|
if (params.supported_rates)
|
||||||
|
err = -EINVAL;
|
||||||
|
if (params.sta_flags_mask)
|
||||||
|
err = -EINVAL;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
err = -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, ¶ms.vlan);
|
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue