Commit cb9abd48 authored by Johannes Berg's avatar Johannes Berg

nl80211: clean up code/policy a bit

Use the policy to validate minimum and exact lengths in
some attributes that weren't previously covered in the
right ways, and remove associated validation code.
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Link: https://lore.kernel.org/r/20200805154714.3ba1e233cfa0.I5dc8109b7ab5c3f4ae925f903a30cc9b35753262@changeidSigned-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 7b506ff6
...@@ -539,7 +539,10 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { ...@@ -539,7 +539,10 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
[NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 }, [NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 },
[NL80211_ATTR_WDEV] = { .type = NLA_U64 }, [NL80211_ATTR_WDEV] = { .type = NLA_U64 },
[NL80211_ATTR_USER_REG_HINT_TYPE] = { .type = NLA_U32 }, [NL80211_ATTR_USER_REG_HINT_TYPE] = { .type = NLA_U32 },
[NL80211_ATTR_AUTH_DATA] = { .type = NLA_BINARY, },
/* need to include at least Auth Transaction and Status Code */
[NL80211_ATTR_AUTH_DATA] = NLA_POLICY_MIN_LEN(4),
[NL80211_ATTR_VHT_CAPABILITY] = NLA_POLICY_EXACT_LEN_WARN(NL80211_VHT_CAPABILITY_LEN), [NL80211_ATTR_VHT_CAPABILITY] = NLA_POLICY_EXACT_LEN_WARN(NL80211_VHT_CAPABILITY_LEN),
[NL80211_ATTR_SCAN_FLAGS] = { .type = NLA_U32 }, [NL80211_ATTR_SCAN_FLAGS] = { .type = NLA_U32 },
[NL80211_ATTR_P2P_CTWINDOW] = NLA_POLICY_MAX(NLA_U8, 127), [NL80211_ATTR_P2P_CTWINDOW] = NLA_POLICY_MAX(NLA_U8, 127),
...@@ -561,7 +564,8 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { ...@@ -561,7 +564,8 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
[NL80211_ATTR_IE_RIC] = { .type = NLA_BINARY, [NL80211_ATTR_IE_RIC] = { .type = NLA_BINARY,
.len = IEEE80211_MAX_DATA_LEN }, .len = IEEE80211_MAX_DATA_LEN },
[NL80211_ATTR_CRIT_PROT_ID] = { .type = NLA_U16 }, [NL80211_ATTR_CRIT_PROT_ID] = { .type = NLA_U16 },
[NL80211_ATTR_MAX_CRIT_PROT_DURATION] = { .type = NLA_U16 }, [NL80211_ATTR_MAX_CRIT_PROT_DURATION] =
NLA_POLICY_MAX(NLA_U16, NL80211_CRIT_PROTO_MAX_DURATION),
[NL80211_ATTR_PEER_AID] = [NL80211_ATTR_PEER_AID] =
NLA_POLICY_RANGE(NLA_U16, 1, IEEE80211_MAX_AID), NLA_POLICY_RANGE(NLA_U16, 1, IEEE80211_MAX_AID),
[NL80211_ATTR_CH_SWITCH_COUNT] = { .type = NLA_U32 }, [NL80211_ATTR_CH_SWITCH_COUNT] = { .type = NLA_U32 },
...@@ -569,7 +573,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { ...@@ -569,7 +573,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
[NL80211_ATTR_CSA_IES] = { .type = NLA_NESTED }, [NL80211_ATTR_CSA_IES] = { .type = NLA_NESTED },
[NL80211_ATTR_CSA_C_OFF_BEACON] = { .type = NLA_BINARY }, [NL80211_ATTR_CSA_C_OFF_BEACON] = { .type = NLA_BINARY },
[NL80211_ATTR_CSA_C_OFF_PRESP] = { .type = NLA_BINARY }, [NL80211_ATTR_CSA_C_OFF_PRESP] = { .type = NLA_BINARY },
[NL80211_ATTR_STA_SUPPORTED_CHANNELS] = { .type = NLA_BINARY }, [NL80211_ATTR_STA_SUPPORTED_CHANNELS] = NLA_POLICY_MIN_LEN(2),
[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES] = { .type = NLA_BINARY }, [NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES] = { .type = NLA_BINARY },
[NL80211_ATTR_HANDLE_DFS] = { .type = NLA_FLAG }, [NL80211_ATTR_HANDLE_DFS] = { .type = NLA_FLAG },
[NL80211_ATTR_OPMODE_NOTIF] = { .type = NLA_U8 }, [NL80211_ATTR_OPMODE_NOTIF] = { .type = NLA_U8 },
...@@ -625,6 +629,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { ...@@ -625,6 +629,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
.len = FILS_ERP_MAX_RRK_LEN }, .len = FILS_ERP_MAX_RRK_LEN },
[NL80211_ATTR_FILS_CACHE_ID] = NLA_POLICY_EXACT_LEN_WARN(2), [NL80211_ATTR_FILS_CACHE_ID] = NLA_POLICY_EXACT_LEN_WARN(2),
[NL80211_ATTR_PMK] = { .type = NLA_BINARY, .len = PMK_MAX_LEN }, [NL80211_ATTR_PMK] = { .type = NLA_BINARY, .len = PMK_MAX_LEN },
[NL80211_ATTR_PMKR0_NAME] = NLA_POLICY_EXACT_LEN(WLAN_PMK_NAME_LEN),
[NL80211_ATTR_SCHED_SCAN_MULTI] = { .type = NLA_FLAG }, [NL80211_ATTR_SCHED_SCAN_MULTI] = { .type = NLA_FLAG },
[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT] = { .type = NLA_FLAG }, [NL80211_ATTR_EXTERNAL_AUTH_SUPPORT] = { .type = NLA_FLAG },
...@@ -736,7 +741,7 @@ nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = { ...@@ -736,7 +741,7 @@ nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = {
.type = NLA_BINARY, .type = NLA_BINARY,
.len = NL80211_KCK_EXT_LEN .len = NL80211_KCK_EXT_LEN
}, },
[NL80211_REKEY_DATA_REPLAY_CTR] = NLA_POLICY_EXACT_LEN_WARN(NL80211_REPLAY_CTR_LEN), [NL80211_REKEY_DATA_REPLAY_CTR] = NLA_POLICY_EXACT_LEN(NL80211_REPLAY_CTR_LEN),
[NL80211_REKEY_DATA_AKM] = { .type = NLA_U32 }, [NL80211_REKEY_DATA_AKM] = { .type = NLA_U32 },
}; };
...@@ -776,7 +781,8 @@ nl80211_bss_select_policy[NL80211_BSS_SELECT_ATTR_MAX + 1] = { ...@@ -776,7 +781,8 @@ nl80211_bss_select_policy[NL80211_BSS_SELECT_ATTR_MAX + 1] = {
/* policy for NAN function attributes */ /* policy for NAN function attributes */
static const struct nla_policy static const struct nla_policy
nl80211_nan_func_policy[NL80211_NAN_FUNC_ATTR_MAX + 1] = { nl80211_nan_func_policy[NL80211_NAN_FUNC_ATTR_MAX + 1] = {
[NL80211_NAN_FUNC_TYPE] = { .type = NLA_U8 }, [NL80211_NAN_FUNC_TYPE] =
NLA_POLICY_MAX(NLA_U8, NL80211_NAN_FUNC_MAX_TYPE),
[NL80211_NAN_FUNC_SERVICE_ID] = { [NL80211_NAN_FUNC_SERVICE_ID] = {
.len = NL80211_NAN_FUNC_SERVICE_ID_LEN }, .len = NL80211_NAN_FUNC_SERVICE_ID_LEN },
[NL80211_NAN_FUNC_PUBLISH_TYPE] = { .type = NLA_U8 }, [NL80211_NAN_FUNC_PUBLISH_TYPE] = { .type = NLA_U8 },
...@@ -4894,8 +4900,7 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) ...@@ -4894,8 +4900,7 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
params.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); params.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
params.ssid_len = params.ssid_len =
nla_len(info->attrs[NL80211_ATTR_SSID]); nla_len(info->attrs[NL80211_ATTR_SSID]);
if (params.ssid_len == 0 || if (params.ssid_len == 0)
params.ssid_len > IEEE80211_MAX_SSID_LEN)
return -EINVAL; return -EINVAL;
} }
...@@ -5835,11 +5840,9 @@ static int nl80211_parse_sta_channel_info(struct genl_info *info, ...@@ -5835,11 +5840,9 @@ static int nl80211_parse_sta_channel_info(struct genl_info *info,
nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]); nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]);
/* /*
* Need to include at least one (first channel, number of * Need to include at least one (first channel, number of
* channels) tuple for each subband, and must have proper * channels) tuple for each subband (checked in policy),
* tuples for the rest of the data as well. * and must have proper tuples for the rest of the data as well.
*/ */
if (params->supported_channels_len < 2)
return -EINVAL;
if (params->supported_channels_len % 2) if (params->supported_channels_len % 2)
return -EINVAL; return -EINVAL;
} }
...@@ -8414,23 +8417,14 @@ nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev, ...@@ -8414,23 +8417,14 @@ nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
} }
if (ssid) { if (ssid) {
if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) {
err = -EINVAL;
goto out_free;
}
memcpy(request->match_sets[i].ssid.ssid, memcpy(request->match_sets[i].ssid.ssid,
nla_data(ssid), nla_len(ssid)); nla_data(ssid), nla_len(ssid));
request->match_sets[i].ssid.ssid_len = request->match_sets[i].ssid.ssid_len =
nla_len(ssid); nla_len(ssid);
} }
if (bssid) { if (bssid)
if (nla_len(bssid) != ETH_ALEN) {
err = -EINVAL;
goto out_free;
}
memcpy(request->match_sets[i].bssid, memcpy(request->match_sets[i].bssid,
nla_data(bssid), ETH_ALEN); nla_data(bssid), ETH_ALEN);
}
/* special attribute - old implementation w/a */ /* special attribute - old implementation w/a */
request->match_sets[i].rssi_thold = default_match_rssi; request->match_sets[i].rssi_thold = default_match_rssi;
...@@ -9307,9 +9301,6 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info) ...@@ -9307,9 +9301,6 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
return -EINVAL; return -EINVAL;
auth_data = nla_data(info->attrs[NL80211_ATTR_AUTH_DATA]); auth_data = nla_data(info->attrs[NL80211_ATTR_AUTH_DATA]);
auth_data_len = nla_len(info->attrs[NL80211_ATTR_AUTH_DATA]); auth_data_len = nla_len(info->attrs[NL80211_ATTR_AUTH_DATA]);
/* need to include at least Auth Transaction and Status Code */
if (auth_data_len < 4)
return -EINVAL;
} }
local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE]; local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
...@@ -12356,8 +12347,6 @@ static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info) ...@@ -12356,8 +12347,6 @@ static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info)
if (!tb[NL80211_REKEY_DATA_REPLAY_CTR] || !tb[NL80211_REKEY_DATA_KEK] || if (!tb[NL80211_REKEY_DATA_REPLAY_CTR] || !tb[NL80211_REKEY_DATA_KEK] ||
!tb[NL80211_REKEY_DATA_KCK]) !tb[NL80211_REKEY_DATA_KCK])
return -EINVAL; return -EINVAL;
if (nla_len(tb[NL80211_REKEY_DATA_REPLAY_CTR]) != NL80211_REPLAY_CTR_LEN)
return -ERANGE;
if (nla_len(tb[NL80211_REKEY_DATA_KEK]) != NL80211_KEK_LEN && if (nla_len(tb[NL80211_REKEY_DATA_KEK]) != NL80211_KEK_LEN &&
!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK && !(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK &&
nla_len(tb[NL80211_REKEY_DATA_KEK]) == NL80211_KEK_EXT_LEN)) nla_len(tb[NL80211_REKEY_DATA_KEK]) == NL80211_KEK_EXT_LEN))
...@@ -12682,8 +12671,7 @@ static int nl80211_nan_add_func(struct sk_buff *skb, ...@@ -12682,8 +12671,7 @@ static int nl80211_nan_add_func(struct sk_buff *skb,
func->cookie = cfg80211_assign_cookie(rdev); func->cookie = cfg80211_assign_cookie(rdev);
if (!tb[NL80211_NAN_FUNC_TYPE] || if (!tb[NL80211_NAN_FUNC_TYPE]) {
nla_get_u8(tb[NL80211_NAN_FUNC_TYPE]) > NL80211_NAN_FUNC_MAX_TYPE) {
err = -EINVAL; err = -EINVAL;
goto out; goto out;
} }
...@@ -13173,9 +13161,6 @@ static int nl80211_crit_protocol_start(struct sk_buff *skb, ...@@ -13173,9 +13161,6 @@ static int nl80211_crit_protocol_start(struct sk_buff *skb,
duration = duration =
nla_get_u16(info->attrs[NL80211_ATTR_MAX_CRIT_PROT_DURATION]); nla_get_u16(info->attrs[NL80211_ATTR_MAX_CRIT_PROT_DURATION]);
if (duration > NL80211_CRIT_PROTO_MAX_DURATION)
return -ERANGE;
ret = rdev_crit_proto_start(rdev, wdev, proto, duration); ret = rdev_crit_proto_start(rdev, wdev, proto, duration);
if (!ret) if (!ret)
rdev->crit_proto_nlportid = info->snd_portid; rdev->crit_proto_nlportid = info->snd_portid;
...@@ -13829,17 +13814,9 @@ static int nl80211_set_pmk(struct sk_buff *skb, struct genl_info *info) ...@@ -13829,17 +13814,9 @@ static int nl80211_set_pmk(struct sk_buff *skb, struct genl_info *info)
goto out; goto out;
} }
if (info->attrs[NL80211_ATTR_PMKR0_NAME]) { if (info->attrs[NL80211_ATTR_PMKR0_NAME])
int r0_name_len = nla_len(info->attrs[NL80211_ATTR_PMKR0_NAME]);
if (r0_name_len != WLAN_PMK_NAME_LEN) {
ret = -EINVAL;
goto out;
}
pmk_conf.pmk_r0_name = pmk_conf.pmk_r0_name =
nla_data(info->attrs[NL80211_ATTR_PMKR0_NAME]); nla_data(info->attrs[NL80211_ATTR_PMKR0_NAME]);
}
ret = rdev_set_pmk(rdev, dev, &pmk_conf); ret = rdev_set_pmk(rdev, dev, &pmk_conf);
out: out:
...@@ -13898,8 +13875,7 @@ static int nl80211_external_auth(struct sk_buff *skb, struct genl_info *info) ...@@ -13898,8 +13875,7 @@ static int nl80211_external_auth(struct sk_buff *skb, struct genl_info *info)
if (info->attrs[NL80211_ATTR_SSID]) { if (info->attrs[NL80211_ATTR_SSID]) {
params.ssid.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]); params.ssid.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
if (params.ssid.ssid_len == 0 || if (params.ssid.ssid_len == 0)
params.ssid.ssid_len > IEEE80211_MAX_SSID_LEN)
return -EINVAL; return -EINVAL;
memcpy(params.ssid.ssid, memcpy(params.ssid.ssid,
nla_data(info->attrs[NL80211_ATTR_SSID]), nla_data(info->attrs[NL80211_ATTR_SSID]),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment