aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/nl80211.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-01-02 07:30:03 -0500
committerJohn W. Linville <linville@tuxdriver.com>2012-01-11 15:14:50 -0500
commitbdd3ae3d1e749cf6597f035a5357f297a1af8eb3 (patch)
tree919de2a3adaf00d99c9d3b726c2a47a75026540f /net/wireless/nl80211.c
parent1a19f77f3642b8194ad9cf55548cc5d92e841766 (diff)
nl80211: fix old station flags compatibility
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>
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r--net/wireless/nl80211.c34
1 files changed, 30 insertions, 4 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index b3d3cf8931cb..afeea32e04ad 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -2250,6 +2250,7 @@ static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
2250}; 2250};
2251 2251
2252static int parse_station_flags(struct genl_info *info, 2252static int parse_station_flags(struct genl_info *info,
2253 enum nl80211_iftype iftype,
2253 struct station_parameters *params) 2254 struct station_parameters *params)
2254{ 2255{
2255 struct nlattr *flags[NL80211_STA_FLAG_MAX + 1]; 2256 struct nlattr *flags[NL80211_STA_FLAG_MAX + 1];
@@ -2283,8 +2284,33 @@ static int parse_station_flags(struct genl_info *info,
2283 nla, sta_flags_policy)) 2284 nla, sta_flags_policy))
2284 return -EINVAL; 2285 return -EINVAL;
2285 2286
2286 params->sta_flags_mask = (1 << __NL80211_STA_FLAG_AFTER_LAST) - 1; 2287 /*
2287 params->sta_flags_mask &= ~1; 2288 * Only allow certain flags for interface types so that
2289 * other attributes are silently ignored. Remember that
2290 * this is backward compatibility code with old userspace
2291 * and shouldn't be hit in other cases anyway.
2292 */
2293 switch (iftype) {
2294 case NL80211_IFTYPE_AP:
2295 case NL80211_IFTYPE_AP_VLAN:
2296 case NL80211_IFTYPE_P2P_GO:
2297 params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
2298 BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
2299 BIT(NL80211_STA_FLAG_WME) |
2300 BIT(NL80211_STA_FLAG_MFP);
2301 break;
2302 case NL80211_IFTYPE_P2P_CLIENT:
2303 case NL80211_IFTYPE_STATION:
2304 params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
2305 BIT(NL80211_STA_FLAG_TDLS_PEER);
2306 break;
2307 case NL80211_IFTYPE_MESH_POINT:
2308 params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHENTICATED) |
2309 BIT(NL80211_STA_FLAG_MFP) |
2310 BIT(NL80211_STA_FLAG_AUTHORIZED);
2311 default:
2312 return -EINVAL;
2313 }
2288 2314
2289 for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++) 2315 for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++)
2290 if (flags[flag]) 2316 if (flags[flag])
@@ -2585,7 +2611,7 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
2585 if (!rdev->ops->change_station) 2611 if (!rdev->ops->change_station)
2586 return -EOPNOTSUPP; 2612 return -EOPNOTSUPP;
2587 2613
2588 if (parse_station_flags(info, &params)) 2614 if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params))
2589 return -EINVAL; 2615 return -EINVAL;
2590 2616
2591 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) 2617 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
@@ -2731,7 +2757,7 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
2731 if (!rdev->ops->add_station) 2757 if (!rdev->ops->add_station)
2732 return -EOPNOTSUPP; 2758 return -EOPNOTSUPP;
2733 2759
2734 if (parse_station_flags(info, &params)) 2760 if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params))
2735 return -EINVAL; 2761 return -EINVAL;
2736 2762
2737 switch (dev->ieee80211_ptr->iftype) { 2763 switch (dev->ieee80211_ptr->iftype) {