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>
This commit is contained in:
Johannes Berg 2014-01-24 10:17:47 +01:00
parent c6e133277b
commit ae811e21df

View File

@ -2055,10 +2055,12 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
nla_for_each_nested(nl_txq_params,
info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS],
rem_txq_params) {
nla_parse(tb, NL80211_TXQ_ATTR_MAX,
nla_data(nl_txq_params),
nla_len(nl_txq_params),
txq_params_policy);
result = nla_parse(tb, NL80211_TXQ_ATTR_MAX,
nla_data(nl_txq_params),
nla_len(nl_txq_params),
txq_params_policy);
if (result)
return result;
result = parse_txq_params(tb, &txq_params);
if (result)
return result;
@ -5198,9 +5200,11 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
rem_reg_rules) {
nla_parse(tb, NL80211_REG_RULE_ATTR_MAX,
nla_data(nl_reg_rule), nla_len(nl_reg_rule),
reg_rule_policy);
r = nla_parse(tb, NL80211_REG_RULE_ATTR_MAX,
nla_data(nl_reg_rule), nla_len(nl_reg_rule),
reg_rule_policy);
if (r)
goto bad_reg;
r = parse_reg_rule(tb, &rd->reg_rules[rule_idx]);
if (r)
goto bad_reg;
@ -5622,9 +5626,11 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
tmp) {
struct nlattr *ssid, *rssi;
nla_parse(tb, NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
nla_data(attr), nla_len(attr),
nl80211_match_policy);
err = nla_parse(tb, NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
nla_data(attr), nla_len(attr),
nl80211_match_policy);
if (err)
goto out_free;
ssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID];
if (ssid) {
if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) {
@ -7499,16 +7505,19 @@ static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
* directly to the enum ieee80211_band values used in cfg80211.
*/
BUILD_BUG_ON(NL80211_MAX_SUPP_HT_RATES > IEEE80211_HT_MCS_MASK_LEN * 8);
nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], rem)
{
nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], rem) {
enum ieee80211_band band = nla_type(tx_rates);
int err;
if (band < 0 || band >= IEEE80211_NUM_BANDS)
return -EINVAL;
sband = rdev->wiphy.bands[band];
if (sband == NULL)
return -EINVAL;
nla_parse(tb, NL80211_TXRATE_MAX, nla_data(tx_rates),
nla_len(tx_rates), nl80211_txattr_policy);
err = nla_parse(tb, NL80211_TXRATE_MAX, nla_data(tx_rates),
nla_len(tx_rates), nl80211_txattr_policy);
if (err)
return err;
if (tb[NL80211_TXRATE_LEGACY]) {
mask.control[band].legacy = rateset_to_mask(
sband,