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

Commit 9757235f authored by Masashi Honma's avatar Masashi Honma Committed by Johannes Berg
Browse files

nl80211: correct checks for NL80211_MESHCONF_HT_OPMODE value



Previously, NL80211_MESHCONF_HT_OPMODE validation rejected correct
flag combinations, e.g. IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED |
IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT.

Doing just a range-check allows setting flags that don't exist (0x8)
and invalid flag combinations.

Implements some checks based on IEEE 802.11 2012 8.4.2.59 "HT
Operation element".

Signed-off-by: default avatarMasashi Honma <masashi.honma@gmail.com>
[reword commit message, simplify a bit]
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 71f2c347
Loading
Loading
Loading
Loading
+31 −3
Original line number Diff line number Diff line
@@ -5380,6 +5380,7 @@ static int nl80211_parse_mesh_config(struct genl_info *info,
{
	struct nlattr *tb[NL80211_MESHCONF_ATTR_MAX + 1];
	u32 mask = 0;
	u16 ht_opmode;

#define FILL_IN_MESH_PARAM_IF_SET(tb, cfg, param, min, max, mask, attr, fn) \
do {									    \
@@ -5471,9 +5472,36 @@ do { \
	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold, -255, 0,
				  mask, NL80211_MESHCONF_RSSI_THRESHOLD,
				  nl80211_check_s32);
	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, ht_opmode, 0, 16,
				  mask, NL80211_MESHCONF_HT_OPMODE,
				  nl80211_check_u16);
	/*
	 * Check HT operation mode based on
	 * IEEE 802.11 2012 8.4.2.59 HT Operation element.
	 */
	if (tb[NL80211_MESHCONF_HT_OPMODE]) {
		ht_opmode = nla_get_u16(tb[NL80211_MESHCONF_HT_OPMODE]);

		if (ht_opmode & ~(IEEE80211_HT_OP_MODE_PROTECTION |
				  IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT |
				  IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT))
			return -EINVAL;

		if ((ht_opmode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT) &&
		    (ht_opmode & IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT))
			return -EINVAL;

		switch (ht_opmode & IEEE80211_HT_OP_MODE_PROTECTION) {
		case IEEE80211_HT_OP_MODE_PROTECTION_NONE:
		case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ:
			if (ht_opmode & IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT)
				return -EINVAL;
			break;
		case IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER:
		case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED:
			if (!(ht_opmode & IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT))
				return -EINVAL;
			break;
		}
		cfg->ht_opmode = ht_opmode;
	}
	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathToRootTimeout,
				  1, 65535, mask,
				  NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,