]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
nl80211: Defragment MLE subelements in CONNECT event parsing
authorPooventhiran G <quic_pooventh@quicinc.com>
Fri, 11 Apr 2025 11:28:34 +0000 (16:58 +0530)
committerJouni Malinen <j@w1.fi>
Sat, 12 Apr 2025 10:39:18 +0000 (13:39 +0300)
While parsing the Multi-Link element in CONNECT event, subelements
carried in the Multi-Link element are not defragmented. Fix this by
defragmenting the subelement before processing to avoid parsing issues.

Fixes: cc2236299f99 ("nl80211: Get all requested MLO links information from (re)association events")
Reviewed-by: Rohan Dutta <quic_drohan@quicinc.com>
Signed-off-by: Pooventhiran G <quic_pooventh@quicinc.com>
src/drivers/driver_nl80211_event.c

index 40555c9577e4d0643a113ef0210e8c8cff60a38c..46e54009d4031a8c55eeb74dca267860d9f04f3d 100644 (file)
@@ -585,11 +585,13 @@ struct links_info {
 };
 
 
-static void nl80211_get_basic_mle_links_info(const u8 *mle, size_t mle_len,
+static void nl80211_get_basic_mle_links_info(struct wpabuf *mlbuf,
                                             struct links_info *info)
 {
        size_t rem_len;
        const u8 *pos;
+       const u8 *mle = wpabuf_head(mlbuf);
+       size_t mle_len = wpabuf_len(mlbuf);
 
        if (mle_len < MULTI_LINK_CONTROL_LEN + 1 ||
            mle_len - MULTI_LINK_CONTROL_LEN < mle[MULTI_LINK_CONTROL_LEN])
@@ -602,7 +604,20 @@ static void nl80211_get_basic_mle_links_info(const u8 *mle, size_t mle_len,
 
        /* Parse Subelements */
        while (rem_len > 2) {
-               size_t ie_len = 2 + pos[1];
+               size_t ie_len, subelem_defrag_len;
+               int num_frag_subelems;
+
+               num_frag_subelems =
+                       ieee802_11_defrag_mle_subelem(mlbuf, pos,
+                                                     &subelem_defrag_len);
+               if (num_frag_subelems < 0) {
+                       wpa_printf(MSG_DEBUG,
+                                  "nl80211: Failed to parse MLE subelem");
+                       break;
+               }
+
+               ie_len = 2 + subelem_defrag_len;
+               rem_len -= num_frag_subelems * 2;
 
                if (rem_len < ie_len)
                        break;
@@ -612,7 +627,8 @@ static void nl80211_get_basic_mle_links_info(const u8 *mle, size_t mle_len,
                        const u8 *sta_profile;
                        u16 sta_ctrl;
 
-                       if (pos[1] < BASIC_MLE_STA_PROF_STA_MAC_IDX + ETH_ALEN)
+                       if (subelem_defrag_len <
+                           BASIC_MLE_STA_PROF_STA_MAC_IDX + ETH_ALEN)
                                goto next_subelem;
 
                        sta_profile = &pos[2];
@@ -668,8 +684,7 @@ static int nl80211_update_rejected_links_info(struct driver_sta_mlo_info *mlo,
                return -1;
        }
        os_memset(&req_info, 0, sizeof(req_info));
-       nl80211_get_basic_mle_links_info(wpabuf_head(mle), wpabuf_len(mle),
-                                        &req_info);
+       nl80211_get_basic_mle_links_info(mle, &req_info);
        wpabuf_free(mle);
 
        mle = ieee802_11_defrag(resp_elems.basic_mle, resp_elems.basic_mle_len,
@@ -680,8 +695,7 @@ static int nl80211_update_rejected_links_info(struct driver_sta_mlo_info *mlo,
                return -1;
        }
        os_memset(&resp_info, 0, sizeof(resp_info));
-       nl80211_get_basic_mle_links_info(wpabuf_head(mle), wpabuf_len(mle),
-                                        &resp_info);
+       nl80211_get_basic_mle_links_info(mle, &resp_info);
        wpabuf_free(mle);
 
        if (req_info.non_assoc_links != resp_info.non_assoc_links) {