Skip to content

Commit

Permalink
nl80211: fix old station flags compatibility
Browse files Browse the repository at this point in the history
My patch to validate station flags broke compatibility
with the old station flags setting where all flags are
always set at once since it always set the mask as all
possible flags which ended up being rejected later in
the station add/modify code.

Fix by parsing only the current flags in the old flags
attribute -- new applications and new flags should use
(and will now require) the new flags attribute where
the mask is given by the application.

Reported-and-tested-by: Thomas Hilber <ath9k-dev@toh.cx>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Johannes Berg authored and John W. Linville committed Jan 11, 2012
1 parent 1a19f77 commit bdd3ae3
Showing 1 changed file with 30 additions and 4 deletions.
34 changes: 30 additions & 4 deletions net/wireless/nl80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -2250,6 +2250,7 @@ static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
};

static int parse_station_flags(struct genl_info *info,
enum nl80211_iftype iftype,
struct station_parameters *params)
{
struct nlattr *flags[NL80211_STA_FLAG_MAX + 1];
Expand Down Expand Up @@ -2283,8 +2284,33 @@ static int parse_station_flags(struct genl_info *info,
nla, sta_flags_policy))
return -EINVAL;

params->sta_flags_mask = (1 << __NL80211_STA_FLAG_AFTER_LAST) - 1;
params->sta_flags_mask &= ~1;
/*
* Only allow certain flags for interface types so that
* other attributes are silently ignored. Remember that
* this is backward compatibility code with old userspace
* and shouldn't be hit in other cases anyway.
*/
switch (iftype) {
case NL80211_IFTYPE_AP:
case NL80211_IFTYPE_AP_VLAN:
case NL80211_IFTYPE_P2P_GO:
params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
BIT(NL80211_STA_FLAG_WME) |
BIT(NL80211_STA_FLAG_MFP);
break;
case NL80211_IFTYPE_P2P_CLIENT:
case NL80211_IFTYPE_STATION:
params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
BIT(NL80211_STA_FLAG_TDLS_PEER);
break;
case NL80211_IFTYPE_MESH_POINT:
params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHENTICATED) |
BIT(NL80211_STA_FLAG_MFP) |
BIT(NL80211_STA_FLAG_AUTHORIZED);
default:
return -EINVAL;
}

for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++)
if (flags[flag])
Expand Down Expand Up @@ -2585,7 +2611,7 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
if (!rdev->ops->change_station)
return -EOPNOTSUPP;

if (parse_station_flags(info, &params))
if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params))
return -EINVAL;

if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
Expand Down Expand Up @@ -2731,7 +2757,7 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
if (!rdev->ops->add_station)
return -EOPNOTSUPP;

if (parse_station_flags(info, &params))
if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params))
return -EINVAL;

switch (dev->ieee80211_ptr->iftype) {
Expand Down

0 comments on commit bdd3ae3

Please sign in to comment.