]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: mac80211: fix vendor-specific inheritance
authorJohannes Berg <johannes.berg@intel.com>
Fri, 21 Feb 2025 10:24:51 +0000 (11:24 +0100)
committerJohannes Berg <johannes.berg@intel.com>
Wed, 26 Feb 2025 14:07:34 +0000 (15:07 +0100)
If there's any vendor-specific element in the subelements
then the outer element parsing must not parse any vendor
element at all. This isn't implemented correctly now due
to parsing into the pointers and then overriding them, so
explicitly skip vendor elements if any exist in the sub-
elements (non-transmitted profile or per-STA profile).

Fixes: 671042a4fb77 ("mac80211: support non-inheritance element")
Reviewed-by: Ilan Peer <ilan.peer@intel.com>
Reviewed-by: Miriam Rachel Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20250221112451.fd71e5268840.I9db3e6a3367e6ff38d052d07dc07005f0dd3bd5c@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/mac80211/parse.c

index 3d5d6658fe8d5216f291bdfe77085206ac030207..6da39c864f45ba6840648adcf0469a7a54035b64 100644 (file)
@@ -48,6 +48,7 @@ struct ieee80211_elems_parse {
        const struct element *ml_epcs_elem;
 
        bool multi_link_inner;
+       bool skip_vendor;
 
        /*
         * scratch buffer that can be used for various element parsing related
@@ -400,6 +401,9 @@ _ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params,
                                        IEEE80211_PARSE_ERR_BAD_ELEM_SIZE;
                        break;
                case WLAN_EID_VENDOR_SPECIFIC:
+                       if (elems_parse->skip_vendor)
+                               break;
+
                        if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 &&
                            pos[2] == 0xf2) {
                                /* Microsoft OUI (00:50:F2) */
@@ -1054,12 +1058,16 @@ ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params)
                multi_link_inner = true;
        }
 
+       elems_parse->skip_vendor =
+               cfg80211_find_elem(WLAN_EID_VENDOR_SPECIFIC,
+                                  sub.start, sub.len);
        elems->crc = _ieee802_11_parse_elems_full(params, elems_parse,
                                                  non_inherit);
 
        /* Override with nontransmitted/per-STA profile if found */
        if (sub.len) {
                elems_parse->multi_link_inner = multi_link_inner;
+               elems_parse->skip_vendor = false;
                _ieee802_11_parse_elems_full(&sub, elems_parse, NULL);
        }