Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ae811e21 authored by Johannes Berg's avatar Johannes Berg
Browse files

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: default avatarJohannes Berg <johannes.berg@intel.com>
parent c6e13327
Loading
Loading
Loading
Loading
+23 −14
Original line number Diff line number Diff line
@@ -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,
			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,
		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,
			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),
		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,