From: Masashi Honma Date: Fri, 29 May 2026 23:09:47 +0000 (+0900) Subject: wifi: mac80211: Fix overread in PREP frame processing X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=d158e54476ea9667c33dfa2c8d87c7cc32b40f1b;p=thirdparty%2Flinux.git wifi: mac80211: Fix overread in PREP frame processing When the AF flag is enabled, hwmp_prep_frame_process() overreads orig_addr by 2 bytes. Since this occurs within the socket buffer, it does not read across memory boundaries and therefore poses no security risk; however, we will fix it as a precaution. In this fix, a new function mesh_path_parse_reply_frame() is established to separate the implementation of frame format validation and the check for unsupported features. This is intended to facilitate future work when implementing the currently unsupported parts. Assisted-by: Claude:Sonnet 4.6 Signed-off-by: Masashi Honma Link: https://patch.msgid.link/20260529230952.124754-5-masashi.honma@gmail.com Signed-off-by: Johannes Berg --- diff --git a/include/linux/ieee80211-mesh.h b/include/linux/ieee80211-mesh.h index 8fbd31d9538d3..482ac0c6d759c 100644 --- a/include/linux/ieee80211-mesh.h +++ b/include/linux/ieee80211-mesh.h @@ -387,4 +387,20 @@ static inline bool ieee80211_mesh_preq_size_ok(const u8 *pos, u8 elen) return elen == needed; } +/* IEEE Std 802.11-2016 9.4.2.114 PREP element */ +static inline bool ieee80211_mesh_prep_size_ok(const u8 *pos, u8 elen) +{ + u8 needed; + + /* Check if the element contains flags */ + needed = sizeof(struct ieee80211_mesh_hwmp_prep_top); + if (elen < needed) + return false; + + needed += (ieee80211_mesh_preq_prep_ae_enabled(pos) ? ETH_ALEN : 0) + /* Target External Address */ + + sizeof(struct ieee80211_mesh_hwmp_prep_bottom); + return elen == needed; +} + #endif /* LINUX_IEEE80211_MESH_H */ diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index ef6eff52f32a3..f07e57d5568ae 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c @@ -947,8 +947,8 @@ void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata, path_metric); } if (elems->prep) { - if (elems->prep_len != 31) - /* Right now we support no AE */ + /* Right now we do not support AE (Address Extension) */ + if (ieee80211_mesh_preq_prep_ae_enabled(elems->prep)) goto free; path_metric = hwmp_route_info_get(sdata, mgmt, elems->prep, MPATH_PREP); diff --git a/net/mac80211/parse.c b/net/mac80211/parse.c index 3d441ff9593d6..97508b141b8cc 100644 --- a/net/mac80211/parse.c +++ b/net/mac80211/parse.c @@ -572,8 +572,13 @@ _ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params, } break; case WLAN_EID_PREP: - elems->prep = pos; - elems->prep_len = elen; + if (ieee80211_mesh_prep_size_ok(pos, elen)) { + elems->prep = pos; + elems->prep_len = elen; + } else { + elem_parse_failed = + IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; + } break; case WLAN_EID_PERR: elems->perr = pos;