summaryrefslogtreecommitdiffstats
path: root/net/wireless/nl80211.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2018-10-02 04:00:07 -0400
committerJohannes Berg <johannes.berg@intel.com>2018-10-11 10:00:58 -0400
commitab0d76f6823cc3a4e277c888abd344e3b977e279 (patch)
treead4aaeefebe33e1938c904b994c769dbd2232845 /net/wireless/nl80211.c
parentb802a5d6f345d207a5dd120149f6d2fdff2e4fcc (diff)
nl80211: use policy range validation where applicable
Many range checks can be done in the policy, move them there. A few in mesh are added in the code (taken out of the macros) because they don't fit into the s16 range in the policy validation. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r--net/wireless/nl80211.c469
1 files changed, 180 insertions, 289 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 9a20c66a1505..3e368c3f1df2 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -222,14 +222,14 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
222 [NL80211_ATTR_CENTER_FREQ1] = { .type = NLA_U32 }, 222 [NL80211_ATTR_CENTER_FREQ1] = { .type = NLA_U32 },
223 [NL80211_ATTR_CENTER_FREQ2] = { .type = NLA_U32 }, 223 [NL80211_ATTR_CENTER_FREQ2] = { .type = NLA_U32 },
224 224
225 [NL80211_ATTR_WIPHY_RETRY_SHORT] = { .type = NLA_U8 }, 225 [NL80211_ATTR_WIPHY_RETRY_SHORT] = NLA_POLICY_MIN(NLA_U8, 1),
226 [NL80211_ATTR_WIPHY_RETRY_LONG] = { .type = NLA_U8 }, 226 [NL80211_ATTR_WIPHY_RETRY_LONG] = NLA_POLICY_MIN(NLA_U8, 1),
227 [NL80211_ATTR_WIPHY_FRAG_THRESHOLD] = { .type = NLA_U32 }, 227 [NL80211_ATTR_WIPHY_FRAG_THRESHOLD] = { .type = NLA_U32 },
228 [NL80211_ATTR_WIPHY_RTS_THRESHOLD] = { .type = NLA_U32 }, 228 [NL80211_ATTR_WIPHY_RTS_THRESHOLD] = { .type = NLA_U32 },
229 [NL80211_ATTR_WIPHY_COVERAGE_CLASS] = { .type = NLA_U8 }, 229 [NL80211_ATTR_WIPHY_COVERAGE_CLASS] = { .type = NLA_U8 },
230 [NL80211_ATTR_WIPHY_DYN_ACK] = { .type = NLA_FLAG }, 230 [NL80211_ATTR_WIPHY_DYN_ACK] = { .type = NLA_FLAG },
231 231
232 [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 }, 232 [NL80211_ATTR_IFTYPE] = NLA_POLICY_MAX(NLA_U32, NL80211_IFTYPE_MAX),
233 [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 }, 233 [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
234 [NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 }, 234 [NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 },
235 235
@@ -239,11 +239,12 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
239 [NL80211_ATTR_KEY] = { .type = NLA_NESTED, }, 239 [NL80211_ATTR_KEY] = { .type = NLA_NESTED, },
240 [NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY, 240 [NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY,
241 .len = WLAN_MAX_KEY_LEN }, 241 .len = WLAN_MAX_KEY_LEN },
242 [NL80211_ATTR_KEY_IDX] = { .type = NLA_U8 }, 242 [NL80211_ATTR_KEY_IDX] = NLA_POLICY_MAX(NLA_U8, 5),
243 [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 }, 243 [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 },
244 [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG }, 244 [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG },
245 [NL80211_ATTR_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 }, 245 [NL80211_ATTR_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 },
246 [NL80211_ATTR_KEY_TYPE] = { .type = NLA_U32 }, 246 [NL80211_ATTR_KEY_TYPE] =
247 NLA_POLICY_MAX(NLA_U32, NUM_NL80211_KEYTYPES),
247 248
248 [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 }, 249 [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 },
249 [NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 }, 250 [NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 },
@@ -251,12 +252,14 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
251 .len = IEEE80211_MAX_DATA_LEN }, 252 .len = IEEE80211_MAX_DATA_LEN },
252 [NL80211_ATTR_BEACON_TAIL] = { .type = NLA_BINARY, 253 [NL80211_ATTR_BEACON_TAIL] = { .type = NLA_BINARY,
253 .len = IEEE80211_MAX_DATA_LEN }, 254 .len = IEEE80211_MAX_DATA_LEN },
254 [NL80211_ATTR_STA_AID] = { .type = NLA_U16 }, 255 [NL80211_ATTR_STA_AID] =
256 NLA_POLICY_RANGE(NLA_U16, 1, IEEE80211_MAX_AID),
255 [NL80211_ATTR_STA_FLAGS] = { .type = NLA_NESTED }, 257 [NL80211_ATTR_STA_FLAGS] = { .type = NLA_NESTED },
256 [NL80211_ATTR_STA_LISTEN_INTERVAL] = { .type = NLA_U16 }, 258 [NL80211_ATTR_STA_LISTEN_INTERVAL] = { .type = NLA_U16 },
257 [NL80211_ATTR_STA_SUPPORTED_RATES] = { .type = NLA_BINARY, 259 [NL80211_ATTR_STA_SUPPORTED_RATES] = { .type = NLA_BINARY,
258 .len = NL80211_MAX_SUPP_RATES }, 260 .len = NL80211_MAX_SUPP_RATES },
259 [NL80211_ATTR_STA_PLINK_ACTION] = { .type = NLA_U8 }, 261 [NL80211_ATTR_STA_PLINK_ACTION] =
262 NLA_POLICY_MAX(NLA_U8, NUM_NL80211_PLINK_ACTIONS - 1),
260 [NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 }, 263 [NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 },
261 [NL80211_ATTR_MNTR_FLAGS] = { /* NLA_NESTED can't be empty */ }, 264 [NL80211_ATTR_MNTR_FLAGS] = { /* NLA_NESTED can't be empty */ },
262 [NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY, 265 [NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY,
@@ -290,7 +293,9 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
290 [NL80211_ATTR_REASON_CODE] = { .type = NLA_U16 }, 293 [NL80211_ATTR_REASON_CODE] = { .type = NLA_U16 },
291 [NL80211_ATTR_FREQ_FIXED] = { .type = NLA_FLAG }, 294 [NL80211_ATTR_FREQ_FIXED] = { .type = NLA_FLAG },
292 [NL80211_ATTR_TIMED_OUT] = { .type = NLA_FLAG }, 295 [NL80211_ATTR_TIMED_OUT] = { .type = NLA_FLAG },
293 [NL80211_ATTR_USE_MFP] = { .type = NLA_U32 }, 296 [NL80211_ATTR_USE_MFP] = NLA_POLICY_RANGE(NLA_U32,
297 NL80211_MFP_NO,
298 NL80211_MFP_OPTIONAL),
294 [NL80211_ATTR_STA_FLAGS2] = { 299 [NL80211_ATTR_STA_FLAGS2] = {
295 .len = sizeof(struct nl80211_sta_flag_update), 300 .len = sizeof(struct nl80211_sta_flag_update),
296 }, 301 },
@@ -310,7 +315,9 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
310 [NL80211_ATTR_FRAME] = { .type = NLA_BINARY, 315 [NL80211_ATTR_FRAME] = { .type = NLA_BINARY,
311 .len = IEEE80211_MAX_DATA_LEN }, 316 .len = IEEE80211_MAX_DATA_LEN },
312 [NL80211_ATTR_FRAME_MATCH] = { .type = NLA_BINARY, }, 317 [NL80211_ATTR_FRAME_MATCH] = { .type = NLA_BINARY, },
313 [NL80211_ATTR_PS_STATE] = { .type = NLA_U32 }, 318 [NL80211_ATTR_PS_STATE] = NLA_POLICY_RANGE(NLA_U32,
319 NL80211_PS_DISABLED,
320 NL80211_PS_ENABLED),
314 [NL80211_ATTR_CQM] = { .type = NLA_NESTED, }, 321 [NL80211_ATTR_CQM] = { .type = NLA_NESTED, },
315 [NL80211_ATTR_LOCAL_STATE_CHANGE] = { .type = NLA_FLAG }, 322 [NL80211_ATTR_LOCAL_STATE_CHANGE] = { .type = NLA_FLAG },
316 [NL80211_ATTR_AP_ISOLATE] = { .type = NLA_U8 }, 323 [NL80211_ATTR_AP_ISOLATE] = { .type = NLA_U8 },
@@ -323,11 +330,17 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
323 [NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG }, 330 [NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG },
324 [NL80211_ATTR_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED }, 331 [NL80211_ATTR_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
325 [NL80211_ATTR_WOWLAN_TRIGGERS] = { .type = NLA_NESTED }, 332 [NL80211_ATTR_WOWLAN_TRIGGERS] = { .type = NLA_NESTED },
326 [NL80211_ATTR_STA_PLINK_STATE] = { .type = NLA_U8 }, 333 [NL80211_ATTR_STA_PLINK_STATE] =
334 NLA_POLICY_MAX(NLA_U8, NUM_NL80211_PLINK_STATES - 1),
335 [NL80211_ATTR_MESH_PEER_AID] =
336 NLA_POLICY_RANGE(NLA_U16, 1, IEEE80211_MAX_AID),
327 [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 }, 337 [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 },
328 [NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED }, 338 [NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED },
329 [NL80211_ATTR_SCAN_SUPP_RATES] = { .type = NLA_NESTED }, 339 [NL80211_ATTR_SCAN_SUPP_RATES] = { .type = NLA_NESTED },
330 [NL80211_ATTR_HIDDEN_SSID] = { .type = NLA_U32 }, 340 [NL80211_ATTR_HIDDEN_SSID] =
341 NLA_POLICY_RANGE(NLA_U32,
342 NL80211_HIDDEN_SSID_NOT_IN_USE,
343 NL80211_HIDDEN_SSID_ZERO_CONTENTS),
331 [NL80211_ATTR_IE_PROBE_RESP] = { .type = NLA_BINARY, 344 [NL80211_ATTR_IE_PROBE_RESP] = { .type = NLA_BINARY,
332 .len = IEEE80211_MAX_DATA_LEN }, 345 .len = IEEE80211_MAX_DATA_LEN },
333 [NL80211_ATTR_IE_ASSOC_RESP] = { .type = NLA_BINARY, 346 [NL80211_ATTR_IE_ASSOC_RESP] = { .type = NLA_BINARY,
@@ -357,9 +370,12 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
357 [NL80211_ATTR_AUTH_DATA] = { .type = NLA_BINARY, }, 370 [NL80211_ATTR_AUTH_DATA] = { .type = NLA_BINARY, },
358 [NL80211_ATTR_VHT_CAPABILITY] = { .len = NL80211_VHT_CAPABILITY_LEN }, 371 [NL80211_ATTR_VHT_CAPABILITY] = { .len = NL80211_VHT_CAPABILITY_LEN },
359 [NL80211_ATTR_SCAN_FLAGS] = { .type = NLA_U32 }, 372 [NL80211_ATTR_SCAN_FLAGS] = { .type = NLA_U32 },
360 [NL80211_ATTR_P2P_CTWINDOW] = { .type = NLA_U8 }, 373 [NL80211_ATTR_P2P_CTWINDOW] = NLA_POLICY_MAX(NLA_U8, 127),
361 [NL80211_ATTR_P2P_OPPPS] = { .type = NLA_U8 }, 374 [NL80211_ATTR_P2P_OPPPS] = NLA_POLICY_MAX(NLA_U8, 1),
362 [NL80211_ATTR_LOCAL_MESH_POWER_MODE] = {. type = NLA_U32 }, 375 [NL80211_ATTR_LOCAL_MESH_POWER_MODE] =
376 NLA_POLICY_RANGE(NLA_U32,
377 NL80211_MESH_POWER_UNKNOWN + 1,
378 NL80211_MESH_POWER_MAX),
363 [NL80211_ATTR_ACL_POLICY] = {. type = NLA_U32 }, 379 [NL80211_ATTR_ACL_POLICY] = {. type = NLA_U32 },
364 [NL80211_ATTR_MAC_ADDRS] = { .type = NLA_NESTED }, 380 [NL80211_ATTR_MAC_ADDRS] = { .type = NLA_NESTED },
365 [NL80211_ATTR_STA_CAPABILITY] = { .type = NLA_U16 }, 381 [NL80211_ATTR_STA_CAPABILITY] = { .type = NLA_U16 },
@@ -372,7 +388,8 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
372 [NL80211_ATTR_MDID] = { .type = NLA_U16 }, 388 [NL80211_ATTR_MDID] = { .type = NLA_U16 },
373 [NL80211_ATTR_IE_RIC] = { .type = NLA_BINARY, 389 [NL80211_ATTR_IE_RIC] = { .type = NLA_BINARY,
374 .len = IEEE80211_MAX_DATA_LEN }, 390 .len = IEEE80211_MAX_DATA_LEN },
375 [NL80211_ATTR_PEER_AID] = { .type = NLA_U16 }, 391 [NL80211_ATTR_PEER_AID] =
392 NLA_POLICY_RANGE(NLA_U16, 1, IEEE80211_MAX_AID),
376 [NL80211_ATTR_CH_SWITCH_COUNT] = { .type = NLA_U32 }, 393 [NL80211_ATTR_CH_SWITCH_COUNT] = { .type = NLA_U32 },
377 [NL80211_ATTR_CH_SWITCH_BLOCK_TX] = { .type = NLA_FLAG }, 394 [NL80211_ATTR_CH_SWITCH_BLOCK_TX] = { .type = NLA_FLAG },
378 [NL80211_ATTR_CSA_IES] = { .type = NLA_NESTED }, 395 [NL80211_ATTR_CSA_IES] = { .type = NLA_NESTED },
@@ -393,8 +410,9 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
393 [NL80211_ATTR_SOCKET_OWNER] = { .type = NLA_FLAG }, 410 [NL80211_ATTR_SOCKET_OWNER] = { .type = NLA_FLAG },
394 [NL80211_ATTR_CSA_C_OFFSETS_TX] = { .type = NLA_BINARY }, 411 [NL80211_ATTR_CSA_C_OFFSETS_TX] = { .type = NLA_BINARY },
395 [NL80211_ATTR_USE_RRM] = { .type = NLA_FLAG }, 412 [NL80211_ATTR_USE_RRM] = { .type = NLA_FLAG },
396 [NL80211_ATTR_TSID] = { .type = NLA_U8 }, 413 [NL80211_ATTR_TSID] = NLA_POLICY_MAX(NLA_U8, IEEE80211_NUM_TIDS - 1),
397 [NL80211_ATTR_USER_PRIO] = { .type = NLA_U8 }, 414 [NL80211_ATTR_USER_PRIO] =
415 NLA_POLICY_MAX(NLA_U8, IEEE80211_NUM_UPS - 1),
398 [NL80211_ATTR_ADMITTED_TIME] = { .type = NLA_U16 }, 416 [NL80211_ATTR_ADMITTED_TIME] = { .type = NLA_U16 },
399 [NL80211_ATTR_SMPS_MODE] = { .type = NLA_U8 }, 417 [NL80211_ATTR_SMPS_MODE] = { .type = NLA_U8 },
400 [NL80211_ATTR_MAC_MASK] = { .len = ETH_ALEN }, 418 [NL80211_ATTR_MAC_MASK] = { .len = ETH_ALEN },
@@ -404,12 +422,13 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
404 [NL80211_ATTR_REG_INDOOR] = { .type = NLA_FLAG }, 422 [NL80211_ATTR_REG_INDOOR] = { .type = NLA_FLAG },
405 [NL80211_ATTR_PBSS] = { .type = NLA_FLAG }, 423 [NL80211_ATTR_PBSS] = { .type = NLA_FLAG },
406 [NL80211_ATTR_BSS_SELECT] = { .type = NLA_NESTED }, 424 [NL80211_ATTR_BSS_SELECT] = { .type = NLA_NESTED },
407 [NL80211_ATTR_STA_SUPPORT_P2P_PS] = { .type = NLA_U8 }, 425 [NL80211_ATTR_STA_SUPPORT_P2P_PS] =
426 NLA_POLICY_MAX(NLA_U8, NUM_NL80211_P2P_PS_STATUS - 1),
408 [NL80211_ATTR_MU_MIMO_GROUP_DATA] = { 427 [NL80211_ATTR_MU_MIMO_GROUP_DATA] = {
409 .len = VHT_MUMIMO_GROUPS_DATA_LEN 428 .len = VHT_MUMIMO_GROUPS_DATA_LEN
410 }, 429 },
411 [NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR] = { .len = ETH_ALEN }, 430 [NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR] = { .len = ETH_ALEN },
412 [NL80211_ATTR_NAN_MASTER_PREF] = { .type = NLA_U8 }, 431 [NL80211_ATTR_NAN_MASTER_PREF] = NLA_POLICY_MIN(NLA_U8, 1),
413 [NL80211_ATTR_BANDS] = { .type = NLA_U32 }, 432 [NL80211_ATTR_BANDS] = { .type = NLA_U32 },
414 [NL80211_ATTR_NAN_FUNC] = { .type = NLA_NESTED }, 433 [NL80211_ATTR_NAN_FUNC] = { .type = NLA_NESTED },
415 [NL80211_ATTR_FILS_KEK] = { .type = NLA_BINARY, 434 [NL80211_ATTR_FILS_KEK] = { .type = NLA_BINARY,
@@ -454,7 +473,7 @@ static const struct nla_policy nl80211_key_policy[NL80211_KEY_MAX + 1] = {
454 [NL80211_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 }, 473 [NL80211_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 },
455 [NL80211_KEY_DEFAULT] = { .type = NLA_FLAG }, 474 [NL80211_KEY_DEFAULT] = { .type = NLA_FLAG },
456 [NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG }, 475 [NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG },
457 [NL80211_KEY_TYPE] = { .type = NLA_U32 }, 476 [NL80211_KEY_TYPE] = NLA_POLICY_MAX(NLA_U32, NUM_NL80211_KEYTYPES - 1),
458 [NL80211_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED }, 477 [NL80211_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
459}; 478};
460 479
@@ -505,7 +524,10 @@ nl80211_wowlan_tcp_policy[NUM_NL80211_WOWLAN_TCP] = {
505static const struct nla_policy 524static const struct nla_policy
506nl80211_coalesce_policy[NUM_NL80211_ATTR_COALESCE_RULE] = { 525nl80211_coalesce_policy[NUM_NL80211_ATTR_COALESCE_RULE] = {
507 [NL80211_ATTR_COALESCE_RULE_DELAY] = { .type = NLA_U32 }, 526 [NL80211_ATTR_COALESCE_RULE_DELAY] = { .type = NLA_U32 },
508 [NL80211_ATTR_COALESCE_RULE_CONDITION] = { .type = NLA_U32 }, 527 [NL80211_ATTR_COALESCE_RULE_CONDITION] =
528 NLA_POLICY_RANGE(NLA_U32,
529 NL80211_COALESCE_CONDITION_MATCH,
530 NL80211_COALESCE_CONDITION_NO_MATCH),
509 [NL80211_ATTR_COALESCE_RULE_PKT_PATTERN] = { .type = NLA_NESTED }, 531 [NL80211_ATTR_COALESCE_RULE_PKT_PATTERN] = { .type = NLA_NESTED },
510}; 532};
511 533
@@ -871,12 +893,8 @@ static int nl80211_parse_key_new(struct genl_info *info, struct nlattr *key,
871 if (tb[NL80211_KEY_CIPHER]) 893 if (tb[NL80211_KEY_CIPHER])
872 k->p.cipher = nla_get_u32(tb[NL80211_KEY_CIPHER]); 894 k->p.cipher = nla_get_u32(tb[NL80211_KEY_CIPHER]);
873 895
874 if (tb[NL80211_KEY_TYPE]) { 896 if (tb[NL80211_KEY_TYPE])
875 k->type = nla_get_u32(tb[NL80211_KEY_TYPE]); 897 k->type = nla_get_u32(tb[NL80211_KEY_TYPE]);
876 if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES)
877 return genl_err_attr(info, -EINVAL,
878 tb[NL80211_KEY_TYPE]);
879 }
880 898
881 if (tb[NL80211_KEY_DEFAULT_TYPES]) { 899 if (tb[NL80211_KEY_DEFAULT_TYPES]) {
882 struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES]; 900 struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
@@ -923,13 +941,8 @@ static int nl80211_parse_key_old(struct genl_info *info, struct key_parse *k)
923 if (k->defmgmt) 941 if (k->defmgmt)
924 k->def_multi = true; 942 k->def_multi = true;
925 943
926 if (info->attrs[NL80211_ATTR_KEY_TYPE]) { 944 if (info->attrs[NL80211_ATTR_KEY_TYPE])
927 k->type = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]); 945 k->type = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
928 if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES) {
929 GENL_SET_ERR_MSG(info, "key type out of range");
930 return -EINVAL;
931 }
932 }
933 946
934 if (info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES]) { 947 if (info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES]) {
935 struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES]; 948 struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
@@ -2648,8 +2661,6 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
2648 if (info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]) { 2661 if (info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]) {
2649 retry_short = nla_get_u8( 2662 retry_short = nla_get_u8(
2650 info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]); 2663 info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]);
2651 if (retry_short == 0)
2652 return -EINVAL;
2653 2664
2654 changed |= WIPHY_PARAM_RETRY_SHORT; 2665 changed |= WIPHY_PARAM_RETRY_SHORT;
2655 } 2666 }
@@ -2657,8 +2668,6 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
2657 if (info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]) { 2668 if (info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]) {
2658 retry_long = nla_get_u8( 2669 retry_long = nla_get_u8(
2659 info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]); 2670 info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]);
2660 if (retry_long == 0)
2661 return -EINVAL;
2662 2671
2663 changed |= WIPHY_PARAM_RETRY_LONG; 2672 changed |= WIPHY_PARAM_RETRY_LONG;
2664 } 2673 }
@@ -3150,8 +3159,6 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
3150 ntype = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]); 3159 ntype = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
3151 if (otype != ntype) 3160 if (otype != ntype)
3152 change = true; 3161 change = true;
3153 if (ntype > NL80211_IFTYPE_MAX)
3154 return -EINVAL;
3155 } 3162 }
3156 3163
3157 if (info->attrs[NL80211_ATTR_MESH_ID]) { 3164 if (info->attrs[NL80211_ATTR_MESH_ID]) {
@@ -3216,11 +3223,8 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
3216 if (!info->attrs[NL80211_ATTR_IFNAME]) 3223 if (!info->attrs[NL80211_ATTR_IFNAME])
3217 return -EINVAL; 3224 return -EINVAL;
3218 3225
3219 if (info->attrs[NL80211_ATTR_IFTYPE]) { 3226 if (info->attrs[NL80211_ATTR_IFTYPE])
3220 type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]); 3227 type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
3221 if (type > NL80211_IFTYPE_MAX)
3222 return -EINVAL;
3223 }
3224 3228
3225 if (!rdev->ops->add_virtual_intf || 3229 if (!rdev->ops->add_virtual_intf ||
3226 !(rdev->wiphy.interface_modes & (1 << type))) 3230 !(rdev->wiphy.interface_modes & (1 << type)))
@@ -3400,9 +3404,6 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
3400 if (info->attrs[NL80211_ATTR_KEY_IDX]) 3404 if (info->attrs[NL80211_ATTR_KEY_IDX])
3401 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]); 3405 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
3402 3406
3403 if (key_idx > 5)
3404 return -EINVAL;
3405
3406 if (info->attrs[NL80211_ATTR_MAC]) 3407 if (info->attrs[NL80211_ATTR_MAC])
3407 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); 3408 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
3408 3409
@@ -3410,8 +3411,6 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
3410 if (info->attrs[NL80211_ATTR_KEY_TYPE]) { 3411 if (info->attrs[NL80211_ATTR_KEY_TYPE]) {
3411 u32 kt = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]); 3412 u32 kt = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
3412 3413
3413 if (kt >= NUM_NL80211_KEYTYPES)
3414 return -EINVAL;
3415 if (kt != NL80211_KEYTYPE_GROUP && 3414 if (kt != NL80211_KEYTYPE_GROUP &&
3416 kt != NL80211_KEYTYPE_PAIRWISE) 3415 kt != NL80211_KEYTYPE_PAIRWISE)
3417 return -EINVAL; 3416 return -EINVAL;
@@ -4273,14 +4272,9 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
4273 return -EINVAL; 4272 return -EINVAL;
4274 } 4273 }
4275 4274
4276 if (info->attrs[NL80211_ATTR_HIDDEN_SSID]) { 4275 if (info->attrs[NL80211_ATTR_HIDDEN_SSID])
4277 params.hidden_ssid = nla_get_u32( 4276 params.hidden_ssid = nla_get_u32(
4278 info->attrs[NL80211_ATTR_HIDDEN_SSID]); 4277 info->attrs[NL80211_ATTR_HIDDEN_SSID]);
4279 if (params.hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE &&
4280 params.hidden_ssid != NL80211_HIDDEN_SSID_ZERO_LEN &&
4281 params.hidden_ssid != NL80211_HIDDEN_SSID_ZERO_CONTENTS)
4282 return -EINVAL;
4283 }
4284 4278
4285 params.privacy = !!info->attrs[NL80211_ATTR_PRIVACY]; 4279 params.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
4286 4280
@@ -4310,8 +4304,6 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
4310 return -EINVAL; 4304 return -EINVAL;
4311 params.p2p_ctwindow = 4305 params.p2p_ctwindow =
4312 nla_get_u8(info->attrs[NL80211_ATTR_P2P_CTWINDOW]); 4306 nla_get_u8(info->attrs[NL80211_ATTR_P2P_CTWINDOW]);
4313 if (params.p2p_ctwindow > 127)
4314 return -EINVAL;
4315 if (params.p2p_ctwindow != 0 && 4307 if (params.p2p_ctwindow != 0 &&
4316 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_CTWIN)) 4308 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_CTWIN))
4317 return -EINVAL; 4309 return -EINVAL;
@@ -4323,8 +4315,6 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
4323 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) 4315 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
4324 return -EINVAL; 4316 return -EINVAL;
4325 tmp = nla_get_u8(info->attrs[NL80211_ATTR_P2P_OPPPS]); 4317 tmp = nla_get_u8(info->attrs[NL80211_ATTR_P2P_OPPPS]);
4326 if (tmp > 1)
4327 return -EINVAL;
4328 params.p2p_opp_ps = tmp; 4318 params.p2p_opp_ps = tmp;
4329 if (params.p2p_opp_ps != 0 && 4319 if (params.p2p_opp_ps != 0 &&
4330 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_OPPPS)) 4320 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_OPPPS))
@@ -5261,17 +5251,11 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
5261 else 5251 else
5262 params.listen_interval = -1; 5252 params.listen_interval = -1;
5263 5253
5264 if (info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]) { 5254 if (info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS])
5265 u8 tmp; 5255 params.support_p2p_ps =
5266 5256 nla_get_u8(info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]);
5267 tmp = nla_get_u8(info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]); 5257 else
5268 if (tmp >= NUM_NL80211_P2P_PS_STATUS)
5269 return -EINVAL;
5270
5271 params.support_p2p_ps = tmp;
5272 } else {
5273 params.support_p2p_ps = -1; 5258 params.support_p2p_ps = -1;
5274 }
5275 5259
5276 if (!info->attrs[NL80211_ATTR_MAC]) 5260 if (!info->attrs[NL80211_ATTR_MAC])
5277 return -EINVAL; 5261 return -EINVAL;
@@ -5301,38 +5285,23 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
5301 if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params)) 5285 if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params))
5302 return -EINVAL; 5286 return -EINVAL;
5303 5287
5304 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) { 5288 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
5305 params.plink_action = 5289 params.plink_action =
5306 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]); 5290 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
5307 if (params.plink_action >= NUM_NL80211_PLINK_ACTIONS)
5308 return -EINVAL;
5309 }
5310 5291
5311 if (info->attrs[NL80211_ATTR_STA_PLINK_STATE]) { 5292 if (info->attrs[NL80211_ATTR_STA_PLINK_STATE]) {
5312 params.plink_state = 5293 params.plink_state =
5313 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_STATE]); 5294 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_STATE]);
5314 if (params.plink_state >= NUM_NL80211_PLINK_STATES) 5295 if (info->attrs[NL80211_ATTR_MESH_PEER_AID])
5315 return -EINVAL;
5316 if (info->attrs[NL80211_ATTR_MESH_PEER_AID]) {
5317 params.peer_aid = nla_get_u16( 5296 params.peer_aid = nla_get_u16(
5318 info->attrs[NL80211_ATTR_MESH_PEER_AID]); 5297 info->attrs[NL80211_ATTR_MESH_PEER_AID]);
5319 if (params.peer_aid > IEEE80211_MAX_AID)
5320 return -EINVAL;
5321 }
5322 params.sta_modify_mask |= STATION_PARAM_APPLY_PLINK_STATE; 5298 params.sta_modify_mask |= STATION_PARAM_APPLY_PLINK_STATE;
5323 } 5299 }
5324 5300
5325 if (info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE]) { 5301 if (info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE])
5326 enum nl80211_mesh_power_mode pm = nla_get_u32( 5302 params.local_pm = nla_get_u32(
5327 info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE]); 5303 info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE]);
5328 5304
5329 if (pm <= NL80211_MESH_POWER_UNKNOWN ||
5330 pm > NL80211_MESH_POWER_MAX)
5331 return -EINVAL;
5332
5333 params.local_pm = pm;
5334 }
5335
5336 if (info->attrs[NL80211_ATTR_OPMODE_NOTIF]) { 5305 if (info->attrs[NL80211_ATTR_OPMODE_NOTIF]) {
5337 params.opmode_notif_used = true; 5306 params.opmode_notif_used = true;
5338 params.opmode_notif = 5307 params.opmode_notif =
@@ -5409,13 +5378,8 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
5409 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]); 5378 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
5410 5379
5411 if (info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]) { 5380 if (info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]) {
5412 u8 tmp; 5381 params.support_p2p_ps =
5413 5382 nla_get_u8(info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]);
5414 tmp = nla_get_u8(info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]);
5415 if (tmp >= NUM_NL80211_P2P_PS_STATUS)
5416 return -EINVAL;
5417
5418 params.support_p2p_ps = tmp;
5419 } else { 5383 } else {
5420 /* 5384 /*
5421 * if not specified, assume it's supported for P2P GO interface, 5385 * if not specified, assume it's supported for P2P GO interface,
@@ -5429,8 +5393,6 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
5429 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]); 5393 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]);
5430 else 5394 else
5431 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]); 5395 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
5432 if (!params.aid || params.aid > IEEE80211_MAX_AID)
5433 return -EINVAL;
5434 5396
5435 if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) { 5397 if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) {
5436 params.capability = 5398 params.capability =
@@ -5470,12 +5432,9 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
5470 nla_get_u8(info->attrs[NL80211_ATTR_OPMODE_NOTIF]); 5432 nla_get_u8(info->attrs[NL80211_ATTR_OPMODE_NOTIF]);
5471 } 5433 }
5472 5434
5473 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) { 5435 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
5474 params.plink_action = 5436 params.plink_action =
5475 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]); 5437 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
5476 if (params.plink_action >= NUM_NL80211_PLINK_ACTIONS)
5477 return -EINVAL;
5478 }
5479 5438
5480 err = nl80211_parse_sta_channel_info(info, &params); 5439 err = nl80211_parse_sta_channel_info(info, &params);
5481 if (err) 5440 if (err)
@@ -5985,9 +5944,7 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
5985 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) 5944 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
5986 return -EINVAL; 5945 return -EINVAL;
5987 params.p2p_ctwindow = 5946 params.p2p_ctwindow =
5988 nla_get_s8(info->attrs[NL80211_ATTR_P2P_CTWINDOW]); 5947 nla_get_u8(info->attrs[NL80211_ATTR_P2P_CTWINDOW]);
5989 if (params.p2p_ctwindow < 0)
5990 return -EINVAL;
5991 if (params.p2p_ctwindow != 0 && 5948 if (params.p2p_ctwindow != 0 &&
5992 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_CTWIN)) 5949 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_CTWIN))
5993 return -EINVAL; 5950 return -EINVAL;
@@ -5999,8 +5956,6 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
5999 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) 5956 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
6000 return -EINVAL; 5957 return -EINVAL;
6001 tmp = nla_get_u8(info->attrs[NL80211_ATTR_P2P_OPPPS]); 5958 tmp = nla_get_u8(info->attrs[NL80211_ATTR_P2P_OPPPS]);
6002 if (tmp > 1)
6003 return -EINVAL;
6004 params.p2p_opp_ps = tmp; 5959 params.p2p_opp_ps = tmp;
6005 if (params.p2p_opp_ps && 5960 if (params.p2p_opp_ps &&
6006 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_OPPPS)) 5961 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_OPPPS))
@@ -6179,33 +6134,49 @@ static int nl80211_get_mesh_config(struct sk_buff *skb,
6179 return -ENOBUFS; 6134 return -ENOBUFS;
6180} 6135}
6181 6136
6182static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_ATTR_MAX+1] = { 6137static const struct nla_policy
6183 [NL80211_MESHCONF_RETRY_TIMEOUT] = { .type = NLA_U16 }, 6138nl80211_meshconf_params_policy[NL80211_MESHCONF_ATTR_MAX+1] = {
6184 [NL80211_MESHCONF_CONFIRM_TIMEOUT] = { .type = NLA_U16 }, 6139 [NL80211_MESHCONF_RETRY_TIMEOUT] =
6185 [NL80211_MESHCONF_HOLDING_TIMEOUT] = { .type = NLA_U16 }, 6140 NLA_POLICY_RANGE(NLA_U16, 1, 255),
6186 [NL80211_MESHCONF_MAX_PEER_LINKS] = { .type = NLA_U16 }, 6141 [NL80211_MESHCONF_CONFIRM_TIMEOUT] =
6187 [NL80211_MESHCONF_MAX_RETRIES] = { .type = NLA_U8 }, 6142 NLA_POLICY_RANGE(NLA_U16, 1, 255),
6188 [NL80211_MESHCONF_TTL] = { .type = NLA_U8 }, 6143 [NL80211_MESHCONF_HOLDING_TIMEOUT] =
6189 [NL80211_MESHCONF_ELEMENT_TTL] = { .type = NLA_U8 }, 6144 NLA_POLICY_RANGE(NLA_U16, 1, 255),
6190 [NL80211_MESHCONF_AUTO_OPEN_PLINKS] = { .type = NLA_U8 }, 6145 [NL80211_MESHCONF_MAX_PEER_LINKS] =
6191 [NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR] = { .type = NLA_U32 }, 6146 NLA_POLICY_RANGE(NLA_U16, 0, 255),
6147 [NL80211_MESHCONF_MAX_RETRIES] = NLA_POLICY_MAX(NLA_U8, 16),
6148 [NL80211_MESHCONF_TTL] = NLA_POLICY_MIN(NLA_U8, 1),
6149 [NL80211_MESHCONF_ELEMENT_TTL] = NLA_POLICY_MIN(NLA_U8, 1),
6150 [NL80211_MESHCONF_AUTO_OPEN_PLINKS] = NLA_POLICY_MAX(NLA_U8, 1),
6151 [NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR] =
6152 NLA_POLICY_RANGE(NLA_U32, 1, 255),
6192 [NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES] = { .type = NLA_U8 }, 6153 [NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES] = { .type = NLA_U8 },
6193 [NL80211_MESHCONF_PATH_REFRESH_TIME] = { .type = NLA_U32 }, 6154 [NL80211_MESHCONF_PATH_REFRESH_TIME] = { .type = NLA_U32 },
6194 [NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT] = { .type = NLA_U16 }, 6155 [NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT] = NLA_POLICY_MIN(NLA_U16, 1),
6195 [NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT] = { .type = NLA_U32 }, 6156 [NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT] = { .type = NLA_U32 },
6196 [NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL] = { .type = NLA_U16 }, 6157 [NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL] =
6197 [NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL] = { .type = NLA_U16 }, 6158 NLA_POLICY_MIN(NLA_U16, 1),
6198 [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 }, 6159 [NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL] =
6199 [NL80211_MESHCONF_HWMP_ROOTMODE] = { .type = NLA_U8 }, 6160 NLA_POLICY_MIN(NLA_U16, 1),
6200 [NL80211_MESHCONF_HWMP_RANN_INTERVAL] = { .type = NLA_U16 }, 6161 [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] =
6201 [NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = { .type = NLA_U8 }, 6162 NLA_POLICY_MIN(NLA_U16, 1),
6202 [NL80211_MESHCONF_FORWARDING] = { .type = NLA_U8 }, 6163 [NL80211_MESHCONF_HWMP_ROOTMODE] = NLA_POLICY_MAX(NLA_U8, 4),
6203 [NL80211_MESHCONF_RSSI_THRESHOLD] = { .type = NLA_U32 }, 6164 [NL80211_MESHCONF_HWMP_RANN_INTERVAL] =
6165 NLA_POLICY_MIN(NLA_U16, 1),
6166 [NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = NLA_POLICY_MAX(NLA_U8, 1),
6167 [NL80211_MESHCONF_FORWARDING] = NLA_POLICY_MAX(NLA_U8, 1),
6168 [NL80211_MESHCONF_RSSI_THRESHOLD] =
6169 NLA_POLICY_RANGE(NLA_S32, -255, 0),
6204 [NL80211_MESHCONF_HT_OPMODE] = { .type = NLA_U16 }, 6170 [NL80211_MESHCONF_HT_OPMODE] = { .type = NLA_U16 },
6205 [NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT] = { .type = NLA_U32 }, 6171 [NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT] = { .type = NLA_U32 },
6206 [NL80211_MESHCONF_HWMP_ROOT_INTERVAL] = { .type = NLA_U16 }, 6172 [NL80211_MESHCONF_HWMP_ROOT_INTERVAL] =
6207 [NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL] = { .type = NLA_U16 }, 6173 NLA_POLICY_MIN(NLA_U16, 1),
6208 [NL80211_MESHCONF_POWER_MODE] = { .type = NLA_U32 }, 6174 [NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL] =
6175 NLA_POLICY_MIN(NLA_U16, 1),
6176 [NL80211_MESHCONF_POWER_MODE] =
6177 NLA_POLICY_RANGE(NLA_U32,
6178 NL80211_MESH_POWER_ACTIVE,
6179 NL80211_MESH_POWER_MAX),
6209 [NL80211_MESHCONF_AWAKE_WINDOW] = { .type = NLA_U16 }, 6180 [NL80211_MESHCONF_AWAKE_WINDOW] = { .type = NLA_U16 },
6210 [NL80211_MESHCONF_PLINK_TIMEOUT] = { .type = NLA_U32 }, 6181 [NL80211_MESHCONF_PLINK_TIMEOUT] = { .type = NLA_U32 },
6211}; 6182};
@@ -6223,63 +6194,6 @@ static const struct nla_policy
6223 [NL80211_MESH_SETUP_USERSPACE_AMPE] = { .type = NLA_FLAG }, 6194 [NL80211_MESH_SETUP_USERSPACE_AMPE] = { .type = NLA_FLAG },
6224}; 6195};
6225 6196
6226static int nl80211_check_bool(const struct nlattr *nla, u8 min, u8 max, bool *out)
6227{
6228 u8 val = nla_get_u8(nla);
6229 if (val < min || val > max)
6230 return -EINVAL;
6231 *out = val;
6232 return 0;
6233}
6234
6235static int nl80211_check_u8(const struct nlattr *nla, u8 min, u8 max, u8 *out)
6236{
6237 u8 val = nla_get_u8(nla);
6238 if (val < min || val > max)
6239 return -EINVAL;
6240 *out = val;
6241 return 0;
6242}
6243
6244static int nl80211_check_u16(const struct nlattr *nla, u16 min, u16 max, u16 *out)
6245{
6246 u16 val = nla_get_u16(nla);
6247 if (val < min || val > max)
6248 return -EINVAL;
6249 *out = val;
6250 return 0;
6251}
6252
6253static int nl80211_check_u32(const struct nlattr *nla, u32 min, u32 max, u32 *out)
6254{
6255 u32 val = nla_get_u32(nla);
6256 if (val < min || val > max)
6257 return -EINVAL;
6258 *out = val;
6259 return 0;
6260}
6261
6262static int nl80211_check_s32(const struct nlattr *nla, s32 min, s32 max, s32 *out)
6263{
6264 s32 val = nla_get_s32(nla);
6265 if (val < min || val > max)
6266 return -EINVAL;
6267 *out = val;
6268 return 0;
6269}
6270
6271static int nl80211_check_power_mode(const struct nlattr *nla,
6272 enum nl80211_mesh_power_mode min,
6273 enum nl80211_mesh_power_mode max,
6274 enum nl80211_mesh_power_mode *out)
6275{
6276 u32 val = nla_get_u32(nla);
6277 if (val < min || val > max)
6278 return -EINVAL;
6279 *out = val;
6280 return 0;
6281}
6282
6283static int nl80211_parse_mesh_config(struct genl_info *info, 6197static int nl80211_parse_mesh_config(struct genl_info *info,
6284 struct mesh_config *cfg, 6198 struct mesh_config *cfg,
6285 u32 *mask_out) 6199 u32 *mask_out)
@@ -6288,13 +6202,12 @@ static int nl80211_parse_mesh_config(struct genl_info *info,
6288 u32 mask = 0; 6202 u32 mask = 0;
6289 u16 ht_opmode; 6203 u16 ht_opmode;
6290 6204
6291#define FILL_IN_MESH_PARAM_IF_SET(tb, cfg, param, min, max, mask, attr, fn) \ 6205#define FILL_IN_MESH_PARAM_IF_SET(tb, cfg, param, mask, attr, fn) \
6292do { \ 6206do { \
6293 if (tb[attr]) { \ 6207 if (tb[attr]) { \
6294 if (fn(tb[attr], min, max, &cfg->param)) \ 6208 cfg->param = fn(tb[attr]); \
6295 return -EINVAL; \ 6209 mask |= BIT((attr) - 1); \
6296 mask |= (1 << (attr - 1)); \ 6210 } \
6297 } \
6298} while (0) 6211} while (0)
6299 6212
6300 if (!info->attrs[NL80211_ATTR_MESH_CONFIG]) 6213 if (!info->attrs[NL80211_ATTR_MESH_CONFIG])
@@ -6309,75 +6222,73 @@ do { \
6309 BUILD_BUG_ON(NL80211_MESHCONF_ATTR_MAX > 32); 6222 BUILD_BUG_ON(NL80211_MESHCONF_ATTR_MAX > 32);
6310 6223
6311 /* Fill in the params struct */ 6224 /* Fill in the params struct */
6312 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshRetryTimeout, 1, 255, 6225 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshRetryTimeout, mask,
6313 mask, NL80211_MESHCONF_RETRY_TIMEOUT, 6226 NL80211_MESHCONF_RETRY_TIMEOUT, nla_get_u16);
6314 nl80211_check_u16); 6227 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConfirmTimeout, mask,
6315 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConfirmTimeout, 1, 255, 6228 NL80211_MESHCONF_CONFIRM_TIMEOUT,
6316 mask, NL80211_MESHCONF_CONFIRM_TIMEOUT, 6229 nla_get_u16);
6317 nl80211_check_u16); 6230 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHoldingTimeout, mask,
6318 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHoldingTimeout, 1, 255, 6231 NL80211_MESHCONF_HOLDING_TIMEOUT,
6319 mask, NL80211_MESHCONF_HOLDING_TIMEOUT, 6232 nla_get_u16);
6320 nl80211_check_u16); 6233 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxPeerLinks, mask,
6321 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxPeerLinks, 0, 255, 6234 NL80211_MESHCONF_MAX_PEER_LINKS,
6322 mask, NL80211_MESHCONF_MAX_PEER_LINKS, 6235 nla_get_u16);
6323 nl80211_check_u16); 6236 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxRetries, mask,
6324 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxRetries, 0, 16, 6237 NL80211_MESHCONF_MAX_RETRIES, nla_get_u8);
6325 mask, NL80211_MESHCONF_MAX_RETRIES, 6238 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshTTL, mask,
6326 nl80211_check_u8); 6239 NL80211_MESHCONF_TTL, nla_get_u8);
6327 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshTTL, 1, 255, 6240 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, element_ttl, mask,
6328 mask, NL80211_MESHCONF_TTL, nl80211_check_u8); 6241 NL80211_MESHCONF_ELEMENT_TTL, nla_get_u8);
6329 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, element_ttl, 1, 255, 6242 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, auto_open_plinks, mask,
6330 mask, NL80211_MESHCONF_ELEMENT_TTL, 6243 NL80211_MESHCONF_AUTO_OPEN_PLINKS,
6331 nl80211_check_u8); 6244 nla_get_u8);
6332 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, auto_open_plinks, 0, 1,
6333 mask, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
6334 nl80211_check_bool);
6335 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshNbrOffsetMaxNeighbor, 6245 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshNbrOffsetMaxNeighbor,
6336 1, 255, mask, 6246 mask,
6337 NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR, 6247 NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
6338 nl80211_check_u32); 6248 nla_get_u32);
6339 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPmaxPREQretries, 0, 255, 6249 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPmaxPREQretries, mask,
6340 mask, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES, 6250 NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
6341 nl80211_check_u8); 6251 nla_get_u8);
6342 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, path_refresh_time, 1, 65535, 6252 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, path_refresh_time, mask,
6343 mask, NL80211_MESHCONF_PATH_REFRESH_TIME, 6253 NL80211_MESHCONF_PATH_REFRESH_TIME,
6344 nl80211_check_u32); 6254 nla_get_u32);
6345 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, min_discovery_timeout, 1, 65535, 6255 if (mask & BIT(NL80211_MESHCONF_PATH_REFRESH_TIME) &&
6346 mask, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT, 6256 (cfg->path_refresh_time < 1 || cfg->path_refresh_time > 65535))
6347 nl80211_check_u16); 6257 return -EINVAL;
6258 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, min_discovery_timeout, mask,
6259 NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
6260 nla_get_u16);
6348 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathTimeout, 6261 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathTimeout,
6349 1, 65535, mask, 6262 mask,
6350 NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT, 6263 NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
6351 nl80211_check_u32); 6264 nla_get_u32);
6352 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPpreqMinInterval, 6265 if (mask & BIT(NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT) &&
6353 1, 65535, mask, 6266 (cfg->dot11MeshHWMPactivePathTimeout < 1 ||
6267 cfg->dot11MeshHWMPactivePathTimeout > 65535))
6268 return -EINVAL;
6269 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPpreqMinInterval, mask,
6354 NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL, 6270 NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
6355 nl80211_check_u16); 6271 nla_get_u16);
6356 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPperrMinInterval, 6272 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPperrMinInterval, mask,
6357 1, 65535, mask,
6358 NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL, 6273 NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
6359 nl80211_check_u16); 6274 nla_get_u16);
6360 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, 6275 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
6361 dot11MeshHWMPnetDiameterTraversalTime, 6276 dot11MeshHWMPnetDiameterTraversalTime, mask,
6362 1, 65535, mask,
6363 NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME, 6277 NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
6364 nl80211_check_u16); 6278 nla_get_u16);
6365 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRootMode, 0, 4, 6279 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRootMode, mask,
6366 mask, NL80211_MESHCONF_HWMP_ROOTMODE, 6280 NL80211_MESHCONF_HWMP_ROOTMODE, nla_get_u8);
6367 nl80211_check_u8); 6281 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRannInterval, mask,
6368 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRannInterval, 1, 65535, 6282 NL80211_MESHCONF_HWMP_RANN_INTERVAL,
6369 mask, NL80211_MESHCONF_HWMP_RANN_INTERVAL, 6283 nla_get_u16);
6370 nl80211_check_u16); 6284 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshGateAnnouncementProtocol,
6371 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
6372 dot11MeshGateAnnouncementProtocol, 0, 1,
6373 mask, NL80211_MESHCONF_GATE_ANNOUNCEMENTS, 6285 mask, NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
6374 nl80211_check_bool); 6286 nla_get_u8);
6375 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshForwarding, 0, 1, 6287 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshForwarding, mask,
6376 mask, NL80211_MESHCONF_FORWARDING, 6288 NL80211_MESHCONF_FORWARDING, nla_get_u8);
6377 nl80211_check_bool); 6289 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold, mask,
6378 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold, -255, 0, 6290 NL80211_MESHCONF_RSSI_THRESHOLD,
6379 mask, NL80211_MESHCONF_RSSI_THRESHOLD, 6291 nla_get_s32);
6380 nl80211_check_s32);
6381 /* 6292 /*
6382 * Check HT operation mode based on 6293 * Check HT operation mode based on
6383 * IEEE 802.11-2016 9.4.2.57 HT Operation element. 6294 * IEEE 802.11-2016 9.4.2.57 HT Operation element.
@@ -6396,29 +6307,27 @@ do { \
6396 cfg->ht_opmode = ht_opmode; 6307 cfg->ht_opmode = ht_opmode;
6397 mask |= (1 << (NL80211_MESHCONF_HT_OPMODE - 1)); 6308 mask |= (1 << (NL80211_MESHCONF_HT_OPMODE - 1));
6398 } 6309 }
6399 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathToRootTimeout,
6400 1, 65535, mask,
6401 NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
6402 nl80211_check_u32);
6403 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMProotInterval, 1, 65535,
6404 mask, NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
6405 nl80211_check_u16);
6406 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, 6310 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
6407 dot11MeshHWMPconfirmationInterval, 6311 dot11MeshHWMPactivePathToRootTimeout, mask,
6408 1, 65535, mask, 6312 NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
6313 nla_get_u32);
6314 if (mask & BIT(NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT) &&
6315 (cfg->dot11MeshHWMPactivePathToRootTimeout < 1 ||
6316 cfg->dot11MeshHWMPactivePathToRootTimeout > 65535))
6317 return -EINVAL;
6318 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMProotInterval, mask,
6319 NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
6320 nla_get_u16);
6321 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPconfirmationInterval,
6322 mask,
6409 NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL, 6323 NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
6410 nl80211_check_u16); 6324 nla_get_u16);
6411 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, power_mode, 6325 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, power_mode, mask,
6412 NL80211_MESH_POWER_ACTIVE, 6326 NL80211_MESHCONF_POWER_MODE, nla_get_u32);
6413 NL80211_MESH_POWER_MAX, 6327 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshAwakeWindowDuration, mask,
6414 mask, NL80211_MESHCONF_POWER_MODE, 6328 NL80211_MESHCONF_AWAKE_WINDOW, nla_get_u16);
6415 nl80211_check_power_mode); 6329 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, plink_timeout, mask,
6416 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshAwakeWindowDuration, 6330 NL80211_MESHCONF_PLINK_TIMEOUT, nla_get_u32);
6417 0, 65535, mask,
6418 NL80211_MESHCONF_AWAKE_WINDOW, nl80211_check_u16);
6419 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, plink_timeout, 0, 0xffffffff,
6420 mask, NL80211_MESHCONF_PLINK_TIMEOUT,
6421 nl80211_check_u32);
6422 if (mask_out) 6331 if (mask_out)
6423 *mask_out = mask; 6332 *mask_out = mask;
6424 6333
@@ -9417,11 +9326,6 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
9417 !wiphy_ext_feature_isset(&rdev->wiphy, 9326 !wiphy_ext_feature_isset(&rdev->wiphy,
9418 NL80211_EXT_FEATURE_MFP_OPTIONAL)) 9327 NL80211_EXT_FEATURE_MFP_OPTIONAL))
9419 return -EOPNOTSUPP; 9328 return -EOPNOTSUPP;
9420
9421 if (connect.mfp != NL80211_MFP_REQUIRED &&
9422 connect.mfp != NL80211_MFP_NO &&
9423 connect.mfp != NL80211_MFP_OPTIONAL)
9424 return -EINVAL;
9425 } else { 9329 } else {
9426 connect.mfp = NL80211_MFP_NO; 9330 connect.mfp = NL80211_MFP_NO;
9427 } 9331 }
@@ -10180,9 +10084,6 @@ static int nl80211_set_power_save(struct sk_buff *skb, struct genl_info *info)
10180 10084
10181 ps_state = nla_get_u32(info->attrs[NL80211_ATTR_PS_STATE]); 10085 ps_state = nla_get_u32(info->attrs[NL80211_ATTR_PS_STATE]);
10182 10086
10183 if (ps_state != NL80211_PS_DISABLED && ps_state != NL80211_PS_ENABLED)
10184 return -EINVAL;
10185
10186 wdev = dev->ieee80211_ptr; 10087 wdev = dev->ieee80211_ptr;
10187 10088
10188 if (!rdev->ops->set_power_mgmt) 10089 if (!rdev->ops->set_power_mgmt)
@@ -11343,9 +11244,6 @@ static int nl80211_parse_coalesce_rule(struct cfg80211_registered_device *rdev,
11343 if (tb[NL80211_ATTR_COALESCE_RULE_CONDITION]) 11244 if (tb[NL80211_ATTR_COALESCE_RULE_CONDITION])
11344 new_rule->condition = 11245 new_rule->condition =
11345 nla_get_u32(tb[NL80211_ATTR_COALESCE_RULE_CONDITION]); 11246 nla_get_u32(tb[NL80211_ATTR_COALESCE_RULE_CONDITION]);
11346 if (new_rule->condition != NL80211_COALESCE_CONDITION_MATCH &&
11347 new_rule->condition != NL80211_COALESCE_CONDITION_NO_MATCH)
11348 return -EINVAL;
11349 11247
11350 if (!tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN]) 11248 if (!tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN])
11351 return -EINVAL; 11249 return -EINVAL;
@@ -11698,8 +11596,6 @@ static int nl80211_start_nan(struct sk_buff *skb, struct genl_info *info)
11698 11596
11699 conf.master_pref = 11597 conf.master_pref =
11700 nla_get_u8(info->attrs[NL80211_ATTR_NAN_MASTER_PREF]); 11598 nla_get_u8(info->attrs[NL80211_ATTR_NAN_MASTER_PREF]);
11701 if (!conf.master_pref)
11702 return -EINVAL;
11703 11599
11704 if (info->attrs[NL80211_ATTR_BANDS]) { 11600 if (info->attrs[NL80211_ATTR_BANDS]) {
11705 u32 bands = nla_get_u32(info->attrs[NL80211_ATTR_BANDS]); 11601 u32 bands = nla_get_u32(info->attrs[NL80211_ATTR_BANDS]);
@@ -12684,12 +12580,7 @@ static int nl80211_add_tx_ts(struct sk_buff *skb, struct genl_info *info)
12684 return -EINVAL; 12580 return -EINVAL;
12685 12581
12686 tsid = nla_get_u8(info->attrs[NL80211_ATTR_TSID]); 12582 tsid = nla_get_u8(info->attrs[NL80211_ATTR_TSID]);
12687 if (tsid >= IEEE80211_NUM_TIDS)
12688 return -EINVAL;
12689
12690 up = nla_get_u8(info->attrs[NL80211_ATTR_USER_PRIO]); 12583 up = nla_get_u8(info->attrs[NL80211_ATTR_USER_PRIO]);
12691 if (up >= IEEE80211_NUM_UPS)
12692 return -EINVAL;
12693 12584
12694 /* WMM uses TIDs 0-7 even for TSPEC */ 12585 /* WMM uses TIDs 0-7 even for TSPEC */
12695 if (tsid >= IEEE80211_FIRST_TSPEC_TSID) { 12586 if (tsid >= IEEE80211_FIRST_TSPEC_TSID) {