Re: [PATCH v2] wifi: mwifiex: bound the pairwise-cipher OUI walk to the IE length

Brian Norris <[email protected]>
Newsgroups org.kernel.vger.linux-wireless,org.kernel.vger.linux-kernel,org.kernel.vger.stable
Message-ID <[email protected]>
Hi,

On Wed, Jul 15, 2026 at 08:55:41PM +0200, Doruk Tan Ozturk wrote:
> mwifiex_search_oui_in_ie() reads the pairwise-cipher (PTK) count from a
> beacon/probe-response RSN or WPA information element:
> 
> 	count = iebody->ptk_cnt[0];
> 
> and then walks "count" 4-byte OUIs from the element, comparing each with
> memcmp(). The count byte comes straight from the (attacker-supplied) IE
> and is never checked against the element's own length. The callers admit
> the element on element_id alone (has_ieee_hdr() / has_vendor_hdr(), no
> length check), so a crafted RSN/WPA IE with a large pairwise count makes
> the walk read up to 255 * 4 bytes past the element -- an out-of-bounds
> read of the kmemdup()'d beacon buffer, reachable from any AP whose
> beacon/probe response is processed during scan result parsing.
> 
> Pass the number of available IE bytes to the walk and reject a count
> whose OUI list would not fit, keeping the loop within the element.
> 
> Found by 0sec automated security-research tooling (https://0sec.ai).
> 
> Fixes: 5e6e3a92b9a4 ("wireless: mwifiex: initial commit for Marvell mwifiex driver")
> Cc: [email protected]
> Assisted-by: 0sec:multi-model
> Signed-off-by: Doruk Tan Ozturk <[email protected]>
> ---
> 
> Changes in v2 (per Francesco Dolcini's review):
>  - store offsetof(struct ie_body, ptk_body) in a named variable
>    (ptk_body_offset) and reuse it in both bounds checks; no
>    functional change.
>  - switch the Assisted-by trailer to 0sec:multi-model.
>  drivers/net/wireless/marvell/mwifiex/scan.c | 22 ++++++++++++++++++---
>  1 file changed, 19 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/net/wireless/marvell/mwifiex/scan.c b/drivers/net/wireless/marvell/mwifiex/scan.c
> index 97c0ec3b822e..33ef8af0a5e1 100644
> --- a/drivers/net/wireless/marvell/mwifiex/scan.c
> +++ b/drivers/net/wireless/marvell/mwifiex/scan.c
> @@ -104,12 +104,21 @@ has_vendor_hdr(struct ieee_types_vendor_specific *ie, u8 key)
>   * a given oui in PTK.
>   */
>  static u8
> -mwifiex_search_oui_in_ie(struct ie_body *iebody, u8 *oui)
> +mwifiex_search_oui_in_ie(struct ie_body *iebody, u8 *oui, int ie_len)
>  {
> +	const size_t ptk_body_offset = offsetof(struct ie_body, ptk_body);
>  	u8 count;
>  
> +	/* Need grp_key_oui[4] + ptk_cnt[2] before reading the OUI count. */
> +	if (ie_len < (int)ptk_body_offset)
> +		return MWIFIEX_OUI_NOT_PRESENT;
> +
>  	count = iebody->ptk_cnt[0];
>  
> +	/* Reject an OUI count whose list would run past the element. */
> +	if (ptk_body_offset + count * sizeof(iebody->ptk_body) > (size_t)ie_len)
> +		return MWIFIEX_OUI_NOT_PRESENT;
> +
>  	/* There could be multiple OUIs for PTK hence
>  	   1) Take the length.
>  	   2) Check all the OUIs for AES.
> @@ -143,11 +152,14 @@ mwifiex_is_rsn_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher)
>  	u8 ret = MWIFIEX_OUI_NOT_PRESENT;
>  
>  	if (has_ieee_hdr(bss_desc->bcn_rsn_ie, WLAN_EID_RSN)) {
> +		int ie_len = (int)bss_desc->bcn_rsn_ie->ieee_hdr.len -
> +			     RSN_GTK_OUI_OFFSET;

Are you ensuring you don't underflow when computing ie_len here? What if
bss_desc->bcn_rsn_ie->ieee_hdr.len is small / zero?

> +
>  		iebody = (struct ie_body *)
>  			 (((u8 *) bss_desc->bcn_rsn_ie->data) +
>  			  RSN_GTK_OUI_OFFSET);
>  		oui = &mwifiex_rsn_oui[cipher][0];
> -		ret = mwifiex_search_oui_in_ie(iebody, oui);
> +		ret = mwifiex_search_oui_in_ie(iebody, oui, ie_len);
>  		if (ret)
>  			return ret;
>  	}
> @@ -169,10 +181,14 @@ mwifiex_is_wpa_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher)
>  	u8 ret = MWIFIEX_OUI_NOT_PRESENT;
>  
>  	if (has_vendor_hdr(bss_desc->bcn_wpa_ie, WLAN_EID_VENDOR_SPECIFIC)) {
> +		int ie_len = (int)bss_desc->bcn_wpa_ie->vend_hdr.len -
> +			     (int)sizeof(bss_desc->bcn_wpa_ie->vend_hdr.oui) -
> +			     WPA_GTK_OUI_OFFSET;

Same question.

Brian

> +
>  		iebody = (struct ie_body *)((u8 *)bss_desc->bcn_wpa_ie->data +
>  					    WPA_GTK_OUI_OFFSET);
>  		oui = &mwifiex_wpa_oui[cipher][0];
> -		ret = mwifiex_search_oui_in_ie(iebody, oui);
> +		ret = mwifiex_search_oui_in_ie(iebody, oui, ie_len);
>  		if (ret)
>  			return ret;
>  	}
> -- 
> 2.43.0
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.