diff options
author | Johannes Berg <johannes.berg@intel.com> | 2014-01-24 04:17:47 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2014-02-04 15:57:56 -0500 |
commit | ae811e21df28deb4c2adab0a47fc3da4f56d777b (patch) | |
tree | df34ff9e894db235832b0b0178b2f6333fc59ab2 /net/wireless | |
parent | c6e133277bcf05597ad32f2699b928b284138d59 (diff) |
nl80211: check nla_parse() return values
If there's a policy, then nla_parse() return values must be
checked, otherwise the policy is useless and there's nothing
that ensures the attributes are actually what we expect them
to be.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless')
-rw-r--r-- | net/wireless/nl80211.c | 37 |
1 files changed, 23 insertions, 14 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 55abbe5b34f6..9ed6ef6fd2c5 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -2055,10 +2055,12 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) | |||
2055 | nla_for_each_nested(nl_txq_params, | 2055 | nla_for_each_nested(nl_txq_params, |
2056 | info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS], | 2056 | info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS], |
2057 | rem_txq_params) { | 2057 | rem_txq_params) { |
2058 | nla_parse(tb, NL80211_TXQ_ATTR_MAX, | 2058 | result = nla_parse(tb, NL80211_TXQ_ATTR_MAX, |
2059 | nla_data(nl_txq_params), | 2059 | nla_data(nl_txq_params), |
2060 | nla_len(nl_txq_params), | 2060 | nla_len(nl_txq_params), |
2061 | txq_params_policy); | 2061 | txq_params_policy); |
2062 | if (result) | ||
2063 | return result; | ||
2062 | result = parse_txq_params(tb, &txq_params); | 2064 | result = parse_txq_params(tb, &txq_params); |
2063 | if (result) | 2065 | if (result) |
2064 | return result; | 2066 | return result; |
@@ -5198,9 +5200,11 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info) | |||
5198 | 5200 | ||
5199 | nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES], | 5201 | nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES], |
5200 | rem_reg_rules) { | 5202 | rem_reg_rules) { |
5201 | nla_parse(tb, NL80211_REG_RULE_ATTR_MAX, | 5203 | r = nla_parse(tb, NL80211_REG_RULE_ATTR_MAX, |
5202 | nla_data(nl_reg_rule), nla_len(nl_reg_rule), | 5204 | nla_data(nl_reg_rule), nla_len(nl_reg_rule), |
5203 | reg_rule_policy); | 5205 | reg_rule_policy); |
5206 | if (r) | ||
5207 | goto bad_reg; | ||
5204 | r = parse_reg_rule(tb, &rd->reg_rules[rule_idx]); | 5208 | r = parse_reg_rule(tb, &rd->reg_rules[rule_idx]); |
5205 | if (r) | 5209 | if (r) |
5206 | goto bad_reg; | 5210 | goto bad_reg; |
@@ -5622,9 +5626,11 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, | |||
5622 | tmp) { | 5626 | tmp) { |
5623 | struct nlattr *ssid, *rssi; | 5627 | struct nlattr *ssid, *rssi; |
5624 | 5628 | ||
5625 | nla_parse(tb, NL80211_SCHED_SCAN_MATCH_ATTR_MAX, | 5629 | err = nla_parse(tb, NL80211_SCHED_SCAN_MATCH_ATTR_MAX, |
5626 | nla_data(attr), nla_len(attr), | 5630 | nla_data(attr), nla_len(attr), |
5627 | nl80211_match_policy); | 5631 | nl80211_match_policy); |
5632 | if (err) | ||
5633 | goto out_free; | ||
5628 | ssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID]; | 5634 | ssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID]; |
5629 | if (ssid) { | 5635 | if (ssid) { |
5630 | if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) { | 5636 | if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) { |
@@ -7499,16 +7505,19 @@ static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb, | |||
7499 | * directly to the enum ieee80211_band values used in cfg80211. | 7505 | * directly to the enum ieee80211_band values used in cfg80211. |
7500 | */ | 7506 | */ |
7501 | BUILD_BUG_ON(NL80211_MAX_SUPP_HT_RATES > IEEE80211_HT_MCS_MASK_LEN * 8); | 7507 | BUILD_BUG_ON(NL80211_MAX_SUPP_HT_RATES > IEEE80211_HT_MCS_MASK_LEN * 8); |
7502 | nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], rem) | 7508 | nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], rem) { |
7503 | { | ||
7504 | enum ieee80211_band band = nla_type(tx_rates); | 7509 | enum ieee80211_band band = nla_type(tx_rates); |
7510 | int err; | ||
7511 | |||
7505 | if (band < 0 || band >= IEEE80211_NUM_BANDS) | 7512 | if (band < 0 || band >= IEEE80211_NUM_BANDS) |
7506 | return -EINVAL; | 7513 | return -EINVAL; |
7507 | sband = rdev->wiphy.bands[band]; | 7514 | sband = rdev->wiphy.bands[band]; |
7508 | if (sband == NULL) | 7515 | if (sband == NULL) |
7509 | return -EINVAL; | 7516 | return -EINVAL; |
7510 | nla_parse(tb, NL80211_TXRATE_MAX, nla_data(tx_rates), | 7517 | err = nla_parse(tb, NL80211_TXRATE_MAX, nla_data(tx_rates), |
7511 | nla_len(tx_rates), nl80211_txattr_policy); | 7518 | nla_len(tx_rates), nl80211_txattr_policy); |
7519 | if (err) | ||
7520 | return err; | ||
7512 | if (tb[NL80211_TXRATE_LEGACY]) { | 7521 | if (tb[NL80211_TXRATE_LEGACY]) { |
7513 | mask.control[band].legacy = rateset_to_mask( | 7522 | mask.control[band].legacy = rateset_to_mask( |
7514 | sband, | 7523 | sband, |