diff options
author | Johannes Berg <johannes.berg@intel.com> | 2014-10-27 14:03:19 +0300 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2014-11-04 15:18:21 +0300 |
commit | 8ed2874715c17f27bb7b9bacbcfa41bc88a64476 (patch) | |
tree | c284ccc7f2fc1e420ffa2d9a1949adf5f43e182a /net/mac80211/util.c | |
parent | 239281f803e2efdb77d906ef296086b6917e5d71 (diff) | |
download | linux-8ed2874715c17f27bb7b9bacbcfa41bc88a64476.tar.xz |
mac80211: handle RIC data element in reassociation request
When the RIC data element (RDE) is included in the IEs coming
from userspace for an association request, its handling is
currently broken as any IEs that are contained within it would
be split off from it and inserted again after all the IEs that
mac80211 generates (e.g. HT, VHT.)
To fix this, treat the RIC element specially, and stop after
it only when we find something that doesn't actually belong to
it. This assumes userspace is actually correctly building it,
directly after the fast BSS transition IE and before all the
others like extended capabilities.
This leaves as a potential problem the case where userspace is
building the following IEs:
[RDE] [vendor resource description] [vendor non-resource IE]
In this case, we'd erroneously consider all three IEs to be
part of the RIC data together, and not split them between the
two vendor IEs. Unfortunately, it isn't easily possible to
distinguish vendor IEs, so this isn't easy to fix. Luckily,
this case is rare as normally wpa_supplicant will include an
extended capabilities IE in the IEs, and that certainly will
break the two vendor IEs apart correctly.
Reviewed-by: Eliad Peller <eliad@wizery.com>
Reviewed-by: Beni Lev <beni.lev@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/util.c')
-rw-r--r-- | net/mac80211/util.c | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 91e16b4d4e3c..5f7b0e935b65 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -2101,16 +2101,34 @@ static bool ieee80211_id_in_list(const u8 *ids, int n_ids, u8 id) return false; } -size_t ieee80211_ie_split(const u8 *ies, size_t ielen, - const u8 *ids, int n_ids, size_t offset) +size_t ieee80211_ie_split_ric(const u8 *ies, size_t ielen, + const u8 *ids, int n_ids, + const u8 *after_ric, int n_after_ric, + size_t offset) { size_t pos = offset; - while (pos < ielen && ieee80211_id_in_list(ids, n_ids, ies[pos])) - pos += 2 + ies[pos + 1]; + while (pos < ielen && ieee80211_id_in_list(ids, n_ids, ies[pos])) { + if (ies[pos] == WLAN_EID_RIC_DATA && n_after_ric) { + pos += 2 + ies[pos + 1]; + + while (pos < ielen && + !ieee80211_id_in_list(after_ric, n_after_ric, + ies[pos])) + pos += 2 + ies[pos + 1]; + } else { + pos += 2 + ies[pos + 1]; + } + } return pos; } + +size_t ieee80211_ie_split(const u8 *ies, size_t ielen, + const u8 *ids, int n_ids, size_t offset) +{ + return ieee80211_ie_split_ric(ies, ielen, ids, n_ids, NULL, 0, offset); +} EXPORT_SYMBOL(ieee80211_ie_split); size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset) |