aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2016-09-13 11:08:23 -0400
committerJohannes Berg <johannes.berg@intel.com>2016-09-15 10:45:41 -0400
commitf1c1f17ac52d22227c0074b3d661d7ed692b707a (patch)
tree39a551700fae54fc01846f2e8f093c33eded483c
parent89b706fb28e431fa7639348536c284fb375eb3c0 (diff)
cfg80211: allow connect keys only with default (TX) key
There's no point in allowing connect keys when one of them isn't also configured as the TX key, it would just confuse drivers and probably cause them to pick something for TX. Disallow this confusing and erroneous configuration. As wpa_supplicant will always send NL80211_ATTR_KEYS, even when there are no keys inside, allow that and treat it as though the attribute isn't present at all. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--net/wireless/ibss.c5
-rw-r--r--net/wireless/nl80211.c14
-rw-r--r--net/wireless/sme.c3
-rw-r--r--net/wireless/wext-sme.c2
4 files changed, 22 insertions, 2 deletions
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c
index 896cbb20b6e1..eafdfa5798ae 100644
--- a/net/wireless/ibss.c
+++ b/net/wireless/ibss.c
@@ -114,6 +114,9 @@ static int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
114 } 114 }
115 } 115 }
116 116
117 if (WARN_ON(connkeys && connkeys->def < 0))
118 return -EINVAL;
119
117 if (WARN_ON(wdev->connect_keys)) 120 if (WARN_ON(wdev->connect_keys))
118 kzfree(wdev->connect_keys); 121 kzfree(wdev->connect_keys);
119 wdev->connect_keys = connkeys; 122 wdev->connect_keys = connkeys;
@@ -289,7 +292,7 @@ int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
289 292
290 wdev->wext.ibss.privacy = wdev->wext.default_key != -1; 293 wdev->wext.ibss.privacy = wdev->wext.default_key != -1;
291 294
292 if (wdev->wext.keys) { 295 if (wdev->wext.keys && wdev->wext.keys->def != -1) {
293 ck = kmemdup(wdev->wext.keys, sizeof(*ck), GFP_KERNEL); 296 ck = kmemdup(wdev->wext.keys, sizeof(*ck), GFP_KERNEL);
294 if (!ck) 297 if (!ck)
295 return -ENOMEM; 298 return -ENOMEM;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 71af96e8a947..f2a77c3daa59 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -848,6 +848,15 @@ nl80211_parse_connkeys(struct cfg80211_registered_device *rdev,
848 struct nlattr *key; 848 struct nlattr *key;
849 struct cfg80211_cached_keys *result; 849 struct cfg80211_cached_keys *result;
850 int rem, err, def = 0; 850 int rem, err, def = 0;
851 bool have_key = false;
852
853 nla_for_each_nested(key, keys, rem) {
854 have_key = true;
855 break;
856 }
857
858 if (!have_key)
859 return NULL;
851 860
852 result = kzalloc(sizeof(*result), GFP_KERNEL); 861 result = kzalloc(sizeof(*result), GFP_KERNEL);
853 if (!result) 862 if (!result)
@@ -895,6 +904,11 @@ nl80211_parse_connkeys(struct cfg80211_registered_device *rdev,
895 *no_ht = true; 904 *no_ht = true;
896 } 905 }
897 906
907 if (result->def < 0) {
908 err = -EINVAL;
909 goto error;
910 }
911
898 return result; 912 return result;
899 error: 913 error:
900 kfree(result); 914 kfree(result);
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index add6824c44fd..c08a3b57dca1 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -1043,6 +1043,9 @@ int cfg80211_connect(struct cfg80211_registered_device *rdev,
1043 connect->crypto.ciphers_pairwise[0] = cipher; 1043 connect->crypto.ciphers_pairwise[0] = cipher;
1044 } 1044 }
1045 } 1045 }
1046 } else {
1047 if (WARN_ON(connkeys))
1048 return -EINVAL;
1046 } 1049 }
1047 1050
1048 wdev->connect_keys = connkeys; 1051 wdev->connect_keys = connkeys;
diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c
index f6523a4387cc..88f1f6931ab8 100644
--- a/net/wireless/wext-sme.c
+++ b/net/wireless/wext-sme.c
@@ -42,7 +42,7 @@ int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev,
42 if (!wdev->wext.connect.ssid_len) 42 if (!wdev->wext.connect.ssid_len)
43 return 0; 43 return 0;
44 44
45 if (wdev->wext.keys) { 45 if (wdev->wext.keys && wdev->wext.keys->def != -1) {
46 ck = kmemdup(wdev->wext.keys, sizeof(*ck), GFP_KERNEL); 46 ck = kmemdup(wdev->wext.keys, sizeof(*ck), GFP_KERNEL);
47 if (!ck) 47 if (!ck)
48 return -ENOMEM; 48 return -ENOMEM;