From: Pooventhiran G Date: Fri, 11 Apr 2025 11:28:32 +0000 (+0530) Subject: AP MLD: Defragment MLE subelements in (Re)Association Request X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=21daf558936cc94c5a6d77edc76657bc2afcd3f7;p=thirdparty%2Fhostap.git AP MLD: Defragment MLE subelements in (Re)Association Request The subelements carried within a Multi-Link element can pack more than 255 bytes, and this is achieved using Fragment subelement similar to how the Multi-Link element uses Fragment element. However, the current implementation does not defragment the Fragment subelements and hence when encountered, parsing fails leading to failing connection. Fix this by defragmenting the subelements before processing to get a complete stream of subelement data. Fixes: 7a7a2256c0ea ("common: Support parsing link specific association request") Fixes: 5f5db9366cde ("AP: MLO: Process Multi-Link element from (Re)Association Request frame") Co-developed-by: Rohan Dutta Signed-off-by: Rohan Dutta Signed-off-by: Pooventhiran G --- diff --git a/src/ap/ieee802_11_eht.c b/src/ap/ieee802_11_eht.c index 577fa563b..b61a94fa8 100644 --- a/src/ap/ieee802_11_eht.c +++ b/src/ap/ieee802_11_eht.c @@ -1278,13 +1278,26 @@ u16 hostapd_process_ml_assoc_req(struct hostapd_data *hapd, * length Common Info field. */ pos = end; while (ml_end - pos > 2) { - size_t sub_elem_len = *(pos + 1); - size_t sta_info_len; + size_t sub_elem_len, sta_info_len; u16 control; const u8 *sub_elem_end; + int num_frag_subelems; - wpa_printf(MSG_DEBUG, "MLD: sub element len=%zu", - sub_elem_len); + num_frag_subelems = + ieee802_11_defrag_mle_subelem(mlbuf, pos, + &sub_elem_len); + if (num_frag_subelems < 0) { + wpa_printf(MSG_DEBUG, + "MLD: Failed to parse MLE subelem"); + goto out; + } + + ml_len -= num_frag_subelems * 2; + ml_end = ((const u8 *) ml) + ml_len; + + wpa_printf(MSG_DEBUG, + "MLD: sub element len=%zu, Fragment subelems=%u", + sub_elem_len, num_frag_subelems); if (2 + sub_elem_len > (size_t) (ml_end - pos)) { wpa_printf(MSG_DEBUG, diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c index 1adb08eaf..838869a03 100644 --- a/src/common/ieee802_11_common.c +++ b/src/common/ieee802_11_common.c @@ -1016,14 +1016,25 @@ ParseRes ieee802_11_parse_link_assoc_req(struct ieee802_11_elems *elems, pos += sizeof(*ml) + pos[sizeof(*ml)]; while (len > 2) { - size_t sub_elem_len = *(pos + 1); - size_t sta_info_len; + size_t sub_elem_len, sta_info_len; u16 link_info_control; const u8 *non_inherit; + int num_frag_subelems; + + num_frag_subelems = + ieee802_11_defrag_mle_subelem(mlbuf, pos, + &sub_elem_len); + if (num_frag_subelems < 0) { + wpa_printf(MSG_DEBUG, + "MLD: Failed to parse MLE subelem"); + goto out; + } + + len -= num_frag_subelems * 2; wpa_printf(MSG_DEBUG, - "MLD: sub element: len=%zu, sub_elem_len=%zu", - len, sub_elem_len); + "MLD: sub element: len=%zu, sub_elem_len=%zu, Fragment subelems=%u", + len, sub_elem_len, num_frag_subelems); if (2 + sub_elem_len > len) { if (show_errors)