wifi: mwifiex: validate scan response extents

mwifiex_ret_802_11_scan() subtracts the fixed response fields and the
firmware-provided BSS length from resp->size without first proving that
either extent fits. A short response or oversized BSS length can
therefore underflow tlv_buf_size and make the TLV parser walk beyond the
command response.

Compute the fixed extent from the selected normal or background scan
response. Validate that the fixed fields and BSS data fit before deriving
the TLV extent and entering the parser.

Fixes: 5e6e3a92b9 ("wireless: mwifiex: initial commit for Marvell mwifiex driver")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Link: https://patch.msgid.link/20260815135227.50392-1-pengpeng@iscas.ac.cn
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Pengpeng Hou 2026-08-15 21:52:27 +08:00 committed by Johannes Berg
parent 1c25bfad93
commit 3687d7d480

View File

@ -2115,6 +2115,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
u32 bytes_left;
u32 idx;
u32 tlv_buf_size;
size_t fixed_size;
struct mwifiex_ie_types_chan_band_list_param_set *chan_band_tlv;
struct chan_band_param_set *chan_band;
u8 is_bgscan_resp;
@ -2130,6 +2131,14 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
else
scan_rsp = &resp->params.scan_resp;
scan_resp_size = le16_to_cpu(resp->size);
fixed_size = scan_rsp->bss_desc_and_tlv_buffer - (u8 *)resp;
if (scan_resp_size < fixed_size) {
mwifiex_dbg(adapter, ERROR,
"SCAN_RESP: response is too short\n");
ret = -1;
goto check_next_scan;
}
if (scan_rsp->number_of_sets > MWIFIEX_MAX_AP) {
mwifiex_dbg(adapter, ERROR,
@ -2147,8 +2156,6 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
"info: SCAN_RESP: bss_descript_size %d\n",
bytes_left);
scan_resp_size = le16_to_cpu(resp->size);
mwifiex_dbg(adapter, INFO,
"info: SCAN_RESP: returned %d APs before parsing\n",
scan_rsp->number_of_sets);
@ -2156,15 +2163,17 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
bss_info = scan_rsp->bss_desc_and_tlv_buffer;
/*
* The size of the TLV buffer is equal to the entire command response
* size (scan_resp_size) minus the fixed fields (sizeof()'s), the
* BSS Descriptions (bss_descript_size as bytesLef) and the command
* response header (S_DS_GEN)
* The TLV buffer follows the command-specific fixed fields and the BSS
* descriptions. Background-scan responses have an additional fixed
* field before scan_rsp, which is included in fixed_size.
*/
tlv_buf_size = scan_resp_size - (bytes_left
+ sizeof(scan_rsp->bss_descript_size)
+ sizeof(scan_rsp->number_of_sets)
+ S_DS_GEN);
if (bytes_left > scan_resp_size - fixed_size) {
mwifiex_dbg(adapter, ERROR,
"SCAN_RESP: BSS data exceeds response\n");
ret = -1;
goto check_next_scan;
}
tlv_buf_size = scan_resp_size - fixed_size - bytes_left;
tlv_data = (struct mwifiex_ie_types_data *) (scan_rsp->
bss_desc_and_tlv_buffer +