cfg80211: disallow more station changes
authorJohannes Berg <johannes.berg@intel.com>
Thu, 27 Dec 2012 16:32:09 +0000 (17:32 +0100)
committerJohannes Berg <johannes.berg@intel.com>
Thu, 3 Jan 2013 12:01:45 +0000 (13:01 +0100)
The following changes are invalid and should be
disallowed when a station already exists:
 * supported rates changes, except for TDLS peers
 * listen interval changes
 * HT capability changes

Disallow them and also update a mac80211 comment
explaining how they would be racy.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/mac80211/cfg.c
net/wireless/nl80211.c

index f4d12c7..7d290bc 100644 (file)
@@ -1208,10 +1208,11 @@ static int sta_apply_parameters(struct ieee80211_local *local,
                sta->sta.aid = params->aid;
 
        /*
-        * FIXME: updating the following information is racy when this
-        *        function is called from ieee80211_change_station().
-        *        However, all this information should be static so
-        *        maybe we should just reject attemps to change it.
+        * Some of the following updates would be racy if called on an
+        * existing station, via ieee80211_change_station(). However,
+        * all such changes are rejected by cfg80211 except for updates
+        * changing the supported rates on an existing but not yet used
+        * TDLS peer.
         */
 
        if (params->listen_interval >= 0)
index 087f68b..9bd8340 100644 (file)
@@ -3188,13 +3188,9 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
                        nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
        }
 
-       if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
-               params.listen_interval =
-                   nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
-
-       if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
-               params.ht_capa =
-                       nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
+       if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL] ||
+           info->attrs[NL80211_ATTR_HT_CAPABILITY])
+               return -EINVAL;
 
        if (!rdev->ops->change_station)
                return -EOPNOTSUPP;
@@ -3246,6 +3242,10 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
                                 BIT(NL80211_STA_FLAG_ASSOCIATED)))
                        return -EINVAL;
 
+               /* reject other things that can't change */
+               if (params.supported_rates)
+                       return -EINVAL;
+
                /* must be last in here for error handling */
                params.vlan = get_vlan(info, rdev);
                if (IS_ERR(params.vlan))
@@ -3265,10 +3265,6 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
                /* disallow things sta doesn't support */
                if (params.plink_action)
                        return -EINVAL;
-               if (params.ht_capa)
-                       return -EINVAL;
-               if (params.listen_interval >= 0)
-                       return -EINVAL;
                /* reject any changes other than AUTHORIZED */
                if (params.sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED))
                        return -EINVAL;
@@ -3277,9 +3273,7 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
                /* disallow things mesh doesn't support */
                if (params.vlan)
                        return -EINVAL;
-               if (params.ht_capa)
-                       return -EINVAL;
-               if (params.listen_interval >= 0)
+               if (params.supported_rates)
                        return -EINVAL;
                /*
                 * No special handling for TDLS here -- the userspace