Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH v2 2/3] wifi: wcn36xx: fix OOB read from firmware count in PRINT_REG_INFO indication
From: Tristan Madani @ 2026-04-15 22:23 UTC (permalink / raw)
  To: Loic Poulain; +Cc: Johannes Berg, wcn36xx, linux-wireless
In-Reply-To: <20260415222358.1541983-1-tristmd@gmail.com>

From: Tristan Madani <tristan@talencesecurity.com>

The firmware-controlled rsp->count field is used as the loop bound for
indexing into the flexible rsp->regs[] array without validation against
the message length. A count exceeding the actual data causes out-of-
bounds reads from the heap-allocated message buffer.

Add a check that count fits within the received message.

Fixes: 43efa3c0f241 ("wcn36xx: Implement print_reg indication")
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
---
drivers/net/wireless/ath/wcn36xx/smd.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c
index XXXXXXX..XXXXXXX 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.c
+++ b/drivers/net/wireless/ath/wcn36xx/smd.c
@@ -2803,6 +2803,12 @@ static int wcn36xx_smd_print_reg_info_ind(struct wcn36xx *wcn,
 		return -EIO;
 	}

+	if (rsp->count > (len - sizeof(*rsp)) / sizeof(rsp->regs[0])) {
+		wcn36xx_warn("Truncated print reg info indication: count %u, len %zu\n",
+			     rsp->count, len);
+		return -EIO;
+	}
+
 	wcn36xx_dbg(WCN36XX_DBG_HAL,
 		    "reginfo indication, scenario: 0x%x reason: 0x%x\n",
 		    rsp->scenario, rsp->reason);


^ permalink raw reply

* [PATCH v2 1/3] wifi: wcn36xx: fix heap overflow from oversized firmware HAL response
From: Tristan Madani @ 2026-04-15 22:23 UTC (permalink / raw)
  To: Loic Poulain; +Cc: Johannes Berg, wcn36xx, linux-wireless
In-Reply-To: <20260415222358.1541983-1-tristmd@gmail.com>

From: Tristan Madani <tristan@talencesecurity.com>

The firmware response dispatcher copies all synchronous HAL responses
into the 4096-byte hal_buf without validating the response length. A
response exceeding WCN36XX_HAL_BUF_SIZE causes a heap buffer overflow
with firmware-controlled content.

Add a bounds check on the response length.

Fixes: 8e84c2582169 ("wcn36xx: mac80211 driver for Qualcomm WCN3660/WCN3680 hardware")
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
---
drivers/net/wireless/ath/wcn36xx/smd.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c
index XXXXXXX..XXXXXXX 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.c
+++ b/drivers/net/wireless/ath/wcn36xx/smd.c
@@ -3296,6 +3296,11 @@ int wcn36xx_smd_rsp_process(struct rpmsg_device *rpdev,
 	case WCN36XX_HAL_ADD_BCN_FILTER_RSP:
+		if (len > WCN36XX_HAL_BUF_SIZE) {
+			wcn36xx_warn("HAL response too large: %d\n", len);
+			break;
+		}
 		memcpy(wcn->hal_buf, buf, len);
 		wcn->hal_rsp_len = len;
 		complete(&wcn->hal_rsp_compl);


^ permalink raw reply

* [PATCH v2 0/3] wifi: wcn36xx: fix OOB reads and heap overflow from firmware responses
From: Tristan Madani @ 2026-04-15 22:23 UTC (permalink / raw)
  To: Loic Poulain; +Cc: Johannes Berg, wcn36xx, linux-wireless

From: Tristan Madani <tristan@talencesecurity.com>

Hi Loic,

Note: this is a v2 resubmission. The original was sent via Gmail which
caused HTML rendering issues. This version uses git send-email for
proper plain-text formatting.

Three issues in wcn36xx HAL firmware response handling, including a heap
overflow in the main response dispatcher:

Proposed fixes in the following patches.

Thanks,
Tristan


^ permalink raw reply

* [PATCH v2 3/3] wifi: ath6kl: fix OOB read from firmware num_msg in TX complete handler
From: Tristan Madani @ 2026-04-15 22:23 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, linux-kernel
In-Reply-To: <20260415222349.1541181-1-tristmd@gmail.com>

From: Tristan Madani <tristan@talencesecurity.com>

The firmware-controlled num_msg field (u8, 0-255) drives the loop in
ath6kl_wmi_tx_complete_event_rx() without validation against the buffer
length. This allows out-of-bounds reads of up to 1020 bytes past the
WMI event buffer when the firmware sends an inflated num_msg.

Add a check that the buffer is large enough to hold num_msg entries.

Fixes: bdcd81707973 ("Add ath6kl cleaned up driver")
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
---
drivers/net/wireless/ath/ath6kl/wmi.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index XXXXXXX..XXXXXXX 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -485,6 +485,12 @@ static int ath6kl_wmi_tx_complete_event_rx(u8 *datap, int len)

 	evt = (struct wmi_tx_complete_event *) datap;

+	if (len < sizeof(*evt) ||
+	    len < sizeof(*evt) + evt->num_msg * sizeof(struct tx_complete_msg_v1)) {
+		ath6kl_dbg(ATH6KL_DBG_WMI, "tx complete: invalid len %d for %u msgs\n",
+			   len, evt->num_msg);
+		return -EINVAL;
+	}
 	ath6kl_dbg(ATH6KL_DBG_WMI, "comp: %d %d %d\n",
 		   evt->num_msg, evt->msg_len, evt->msg_type);


^ permalink raw reply

* [PATCH v2 2/3] wifi: ath6kl: fix OOB read from firmware IE lengths in connect event
From: Tristan Madani @ 2026-04-15 22:23 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, linux-kernel
In-Reply-To: <20260415222349.1541181-1-tristmd@gmail.com>

From: Tristan Madani <tristan@talencesecurity.com>

The firmware-controlled beacon_ie_len, assoc_req_len, and assoc_resp_len
fields in ath6kl_wmi_connect_event_rx() are not validated against the
buffer length. Their sum (up to 765) can exceed the actual WMI event
data, causing out-of-bounds reads during IE parsing and state corruption
of wmi->is_wmm_enabled.

Add a check that the total IE length fits within the buffer.

Fixes: bdcd81707973 ("Add ath6kl cleaned up driver")
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
---
drivers/net/wireless/ath/ath6kl/wmi.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index XXXXXXX..XXXXXXX 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -860,6 +860,13 @@ static int ath6kl_wmi_connect_event_rx(struct wmi *wmi, u8 *datap, int len,

 	ev = (struct wmi_connect_event *) datap;

+	if (len < sizeof(*ev) + ev->beacon_ie_len +
+	    ev->assoc_req_len + ev->assoc_resp_len) {
+		ath6kl_dbg(ATH6KL_DBG_WMI,
+			   "connect event: IE lengths %u+%u+%u exceed buffer %d\n",
+			   ev->beacon_ie_len, ev->assoc_req_len,
+			   ev->assoc_resp_len, len);
+		return -EINVAL;
+	}
 	if (vif->nw_type == AP_NETWORK) {
 		/* AP mode start/STA connected event */
 		struct net_device *dev = vif->ndev;


^ permalink raw reply

* [PATCH v2 1/3] wifi: ath6kl: fix OOB access from firmware ADDBA window size
From: Tristan Madani @ 2026-04-15 22:23 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, linux-kernel
In-Reply-To: <20260415222349.1541181-1-tristmd@gmail.com>

From: Tristan Madani <tristan@talencesecurity.com>

aggr_recv_addba_req_evt() logs a debug message when the firmware-supplied
win_sz is outside [AGGR_WIN_SZ_MIN, AGGR_WIN_SZ_MAX] but does not
return. The out-of-range win_sz is then used in TID_WINDOW_SZ() to
compute a kzalloc size and stored in rxtid->hold_q_sz, leading to
zero-size or overflowed allocations and subsequent OOB access.

Return early when win_sz is out of the valid range.

Fixes: bdcd81707973 ("Add ath6kl cleaned up driver")
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
---
drivers/net/wireless/ath/ath6kl/txrx.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c
index XXXXXXX..XXXXXXX 100644
--- a/drivers/net/wireless/ath/ath6kl/txrx.c
+++ b/drivers/net/wireless/ath/ath6kl/txrx.c
@@ -1725,8 +1725,10 @@ void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid_mux, u16 seq_no,
-	if (win_sz < AGGR_WIN_SZ_MIN || win_sz > AGGR_WIN_SZ_MAX)
+	if (win_sz < AGGR_WIN_SZ_MIN || win_sz > AGGR_WIN_SZ_MAX) {
 		ath6kl_dbg(ATH6KL_DBG_WLAN_RX, "%s: win_sz %d, tid %d\n",
 			   __func__, win_sz, tid);
+		return;
+	}

 	if (rxtid->aggr)
 		aggr_delete_tid_state(aggr_conn, tid);
--
2.43.0


^ permalink raw reply

* [PATCH v2 0/3] wifi: ath6kl: fix OOB accesses from firmware-controlled fields
From: Tristan Madani @ 2026-04-15 22:23 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, linux-kernel

From: Tristan Madani <tristan@talencesecurity.com>

Hi Johannes,

Note: this is a v2 resubmission. The original was sent via Gmail which
caused HTML rendering issues. This version uses git send-email for
proper plain-text formatting.

Three issues in ath6kl where firmware-controlled fields are used without
bounds checking:

Proposed fixes in the following patches.

Thanks,
Tristan


^ permalink raw reply

* [PATCH v2] wifi: ath9k: fix OOB access from firmware tx status queue ID
From: Tristan Madani @ 2026-04-15 22:23 UTC (permalink / raw)
  To: Toke Hoiland-Jorgensen; +Cc: Johannes Berg, linux-wireless, linux-kernel

From: Tristan Madani <tristan@talencesecurity.com>

ath_tx_edma_tasklet() accesses sc->tx.txq[ts.qid] where ts.qid is a
4-bit hardware field (0-15), but the txq array only has
ATH9K_NUM_TX_QUEUES (10) entries. A qid >= 10 causes an OOB array
access.

Add a bounds check on ts.qid before using it as an array index.

Fixes: fce041beb03f ("ath9k: unify edma and non-edma tx code, improve tx fifo handling")
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
---
Note: v2 resubmission -- original sent via Gmail had HTML rendering
issues. This version uses git send-email for plain-text formatting.

drivers/net/wireless/ath/ath9k/xmit.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index XXXXXXX..XXXXXXX 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -2755,6 +2755,11 @@ static void ath_tx_edma_tasklet(struct ath_softc *sc)
 			continue;
 		}

+		if (ts.qid >= ATH9K_NUM_TX_QUEUES) {
+			ath_dbg(common, XMIT, "invalid qid %d\n", ts.qid);
+			continue;
+		}
+
 		txq = &sc->tx.txq[ts.qid];

 		ath_txq_lock(sc, txq);
--
2.43.0


^ permalink raw reply

* [PATCH v2 6/6] wifi: mwifiex: fix OOB read from inflated TLV length in IBSS peer event
From: Tristan Madani @ 2026-04-15 22:23 UTC (permalink / raw)
  To: Brian Norris; +Cc: Johannes Berg, linux-wireless, linux-kernel
In-Reply-To: <20260415222327.1539269-1-tristmd@gmail.com>

From: Tristan Madani <tristan@talencesecurity.com>

The IBSS connected handler replaces the buffer-bounded evt_len with
the firmware-controlled TLV header length. An inflated value drives the
IE parsing loop past the event buffer into adjacent kernel heap memory.

Cap the TLV-derived length at the remaining event data size.

Fixes: 432da7d243da ("mwifiex: add HT aggregation support for adhoc mode")
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
---
drivers/net/wireless/marvell/mwifiex/sta_event.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/wireless/marvell/mwifiex/sta_event.c b/drivers/net/wireless/marvell/mwifiex/sta_event.c
index XXXXXXX..XXXXXXX 100644
--- a/drivers/net/wireless/marvell/mwifiex/sta_event.c
+++ b/drivers/net/wireless/marvell/mwifiex/sta_event.c
@@ -46,6 +46,10 @@ static int mwifiex_check_ibss_peer_capabilties(struct mwifiex_private *priv,
 		evt_len = le16_to_cpu(tlv_mgmt_frame->header.len);
 		curr += (sizeof(*tlv_mgmt_frame) + 12);
+		if (evt_len > event->len -
+		    (curr - event->data))
+			evt_len = event->len -
+				  (curr - event->data);
 	} else {
 		mwifiex_dbg(priv->adapter, MSG,


^ permalink raw reply

* [PATCH v2 5/6] wifi: mwifiex: fix OOB read from firmware intf_num in multichannel event
From: Tristan Madani @ 2026-04-15 22:23 UTC (permalink / raw)
  To: Brian Norris; +Cc: Johannes Berg, linux-wireless, linux-kernel
In-Reply-To: <20260415222327.1539269-1-tristmd@gmail.com>

From: Tristan Madani <tristan@talencesecurity.com>

The firmware-controlled intf_num is used to iterate the flexible array
bss_type_numlist[] without checking it against the TLV data length. An
inflated value causes out-of-bounds reads past the TLV data.

Clamp intf_num to the available TLV data.

Fixes: 8d6b538a5eac ("mwifiex: handle multichannel event")
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
---
drivers/net/wireless/marvell/mwifiex/sta_event.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/net/wireless/marvell/mwifiex/sta_event.c b/drivers/net/wireless/marvell/mwifiex/sta_event.c
index XXXXXXX..XXXXXXX 100644
--- a/drivers/net/wireless/marvell/mwifiex/sta_event.c
+++ b/drivers/net/wireless/marvell/mwifiex/sta_event.c
@@ -450,7 +450,15 @@ void mwifiex_process_multi_chan_event(struct mwifiex_private *priv,
 		grp_info = (struct mwifiex_ie_types_mc_group_info *)tlv;

 		intf_num = grp_info->intf_num;
+		{
+			u16 fixed_len = sizeof(*grp_info) -
+					sizeof(grp_info->header);
+			if (tlv_len < fixed_len ||
+			    intf_num > tlv_len - fixed_len)
+				intf_num = 0;
+		}
+
 		for (i = 0; i < intf_num; i++) {
 			bss_type = grp_info->bss_type_numlist[i] >> 4;


^ permalink raw reply

* [PATCH v2 4/6] wifi: mwifiex: fix OOB read in scan response from mismatched TLV data sizes
From: Tristan Madani @ 2026-04-15 22:23 UTC (permalink / raw)
  To: Brian Norris; +Cc: Johannes Berg, linux-wireless, linux-kernel
In-Reply-To: <20260415222327.1539269-1-tristmd@gmail.com>

From: Tristan Madani <tristan@talencesecurity.com>

The TSF and ChanBand TLV arrays are indexed by the firmware-controlled
number_of_sets without cross-checking against the TLV header length
fields. When number_of_sets exceeds the TLV data, the loop reads past
the TLV data into adjacent command response memory.

Stop using the TLV data once the index exceeds its reported length.

Fixes: 5e6e3a92b9a4 ("wireless: mwifiex: initial commit for Marvell mwifiex driver")
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
---
drivers/net/wireless/marvell/mwifiex/scan.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/scan.c b/drivers/net/wireless/marvell/mwifiex/scan.c
index XXXXXXX..XXXXXXX 100644
--- a/drivers/net/wireless/marvell/mwifiex/scan.c
+++ b/drivers/net/wireless/marvell/mwifiex/scan.c
@@ -2188,10 +2188,12 @@ static int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
 		 * received.
 		 */
 		if (tsf_tlv)
-			memcpy(&fw_tsf, &tsf_tlv->tsf_data[idx * TSF_DATA_SIZE],
+			if ((idx + 1) * TSF_DATA_SIZE <=
+			    le16_to_cpu(tsf_tlv->header.len))
+				memcpy(&fw_tsf, &tsf_tlv->tsf_data[idx * TSF_DATA_SIZE],
 			       sizeof(fw_tsf));

-		if (chan_band_tlv) {
+		if (chan_band_tlv && (idx + 1) * sizeof(*chan_band) <=
+		    le16_to_cpu(chan_band_tlv->header.len)) {
 			chan_band = &chan_band_tlv->chan_band_param[idx];
 			radio_type = &chan_band->radio_type;
 		} else {


^ permalink raw reply

* [PATCH v2 3/6] wifi: mwifiex: fix OOB read from firmware sta_count in station list response
From: Tristan Madani @ 2026-04-15 22:23 UTC (permalink / raw)
  To: Brian Norris; +Cc: Johannes Berg, linux-wireless, linux-kernel
In-Reply-To: <20260415222327.1539269-1-tristmd@gmail.com>

From: Tristan Madani <tristan@talencesecurity.com>

The firmware-controlled sta_count (u16) is used as an unbounded loop
counter for iterating station info entries. An inflated count drives
reads past the response buffer into kernel heap memory.

Add a check that sta_count fits within the response size.

Fixes: b21783e94e20 ("mwifiex: add sta_list firmware command")
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
---
drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c b/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c
index XXXXXXX..XXXXXXX 100644
--- a/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c
@@ -976,7 +976,15 @@ static int mwifiex_ret_uap_sta_list(struct mwifiex_private *priv,
 	struct mwifiex_ie_types_sta_info *sta_info = (void *)&sta_list->tlv;
 	int i;
 	struct mwifiex_sta_node *sta_node;
+	u16 resp_size = le16_to_cpu(resp->size);
+	u16 count = le16_to_cpu(sta_list->sta_count);
+	u16 max_count;

+	if (resp_size < sizeof(*resp) - sizeof(resp->params) + sizeof(*sta_list))
+		return -EINVAL;
+	max_count = (resp_size - sizeof(*resp) + sizeof(resp->params) -
+		     sizeof(*sta_list)) / sizeof(*sta_info);
+	count = min(count, max_count);
-	for (i = 0; i < (le16_to_cpu(sta_list->sta_count)); i++) {
+	for (i = 0; i < count; i++) {
 		sta_node = mwifiex_get_sta_entry(priv, sta_info->mac);
 		if (unlikely(!sta_node))
 			continue;


^ permalink raw reply

* [PATCH v2 2/6] wifi: mwifiex: fix OOB write from firmware TID in ADDBA response handler
From: Tristan Madani @ 2026-04-15 22:23 UTC (permalink / raw)
  To: Brian Norris; +Cc: Johannes Berg, linux-wireless, linux-kernel
In-Reply-To: <20260415222327.1539269-1-tristmd@gmail.com>

From: Tristan Madani <tristan@talencesecurity.com>

The TID value extracted from the Block Ack parameter set is a 4-bit
field (0-15), but aggr_prio_tbl[] has only 8 entries. A TID >= 8 causes
an out-of-bounds write to adjacent struct mwifiex_private fields.

Add a bounds check after extracting the TID.

Fixes: 5e6e3a92b9a4 ("wireless: mwifiex: initial commit for Marvell mwifiex driver")
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
---
drivers/net/wireless/marvell/mwifiex/11n.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/net/wireless/marvell/mwifiex/11n.c b/drivers/net/wireless/marvell/mwifiex/11n.c
index XXXXXXX..XXXXXXX 100644
--- a/drivers/net/wireless/marvell/mwifiex/11n.c
+++ b/drivers/net/wireless/marvell/mwifiex/11n.c
@@ -155,6 +155,11 @@ int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv,
 	tid = (block_ack_param_set & IEEE80211_ADDBA_PARAM_TID_MASK)
 	       >> BLOCKACKPARAM_TID_POS;

+	if (tid >= MAX_NUM_TID) {
+		mwifiex_dbg(priv->adapter, ERROR,
+			    "ADDBA RSP: invalid tid %d\n", tid);
+		return -EINVAL;
+	}
 	tid_down = mwifiex_wmm_downgrade_tid(priv, tid);
 	ra_list = mwifiex_wmm_get_ralist_node(priv, tid_down, add_ba_rsp->
 		peer_mac_addr);


^ permalink raw reply

* [PATCH v2 1/6] wifi: mwifiex: fix OOB write from firmware queue_index in WMM status response
From: Tristan Madani @ 2026-04-15 22:23 UTC (permalink / raw)
  To: Brian Norris; +Cc: Johannes Berg, linux-wireless, linux-kernel
In-Reply-To: <20260415222327.1539269-1-tristmd@gmail.com>

From: Tristan Madani <tristan@talencesecurity.com>

The firmware-controlled queue_index (u8) from the WMM queue status TLV
is used to index the 4-entry ac_status[] array without validation. An
out-of-range value causes out-of-bounds writes of three firmware-
controlled bytes into adjacent struct fields.

Add a bounds check before using queue_index as an array index.

Fixes: 5e6e3a92b9a4 ("wireless: mwifiex: initial commit for Marvell mwifiex driver")
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
---
drivers/net/wireless/marvell/mwifiex/wmm.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/net/wireless/marvell/mwifiex/wmm.c b/drivers/net/wireless/marvell/mwifiex/wmm.c
index XXXXXXX..XXXXXXX 100644
--- a/drivers/net/wireless/marvell/mwifiex/wmm.c
+++ b/drivers/net/wireless/marvell/mwifiex/wmm.c
@@ -945,6 +945,11 @@ int mwifiex_ret_wmm_get_status(struct mwifiex_private *priv,
 				    tlv_wmm_qstatus->disabled);

+			if (tlv_wmm_qstatus->queue_index >=
+			    IEEE80211_NUM_ACS) {
+				break;
+			}
+
 			ac_status = &priv->wmm.ac_status[tlv_wmm_qstatus->
 							 queue_index];
 			ac_status->disabled = tlv_wmm_qstatus->disabled;


^ permalink raw reply

* [PATCH v2 0/6] wifi: mwifiex: fix OOB reads and writes from firmware response fields
From: Tristan Madani @ 2026-04-15 22:23 UTC (permalink / raw)
  To: Brian Norris; +Cc: Johannes Berg, linux-wireless, linux-kernel

From: Tristan Madani <tristan@talencesecurity.com>

Hi Brian,

Note: this is a v2 resubmission. The original was sent via Gmail which
caused HTML rendering issues. This version uses git send-email for
proper plain-text formatting.

Six issues in mwifiex where firmware-controlled fields are used as array
indices or loop bounds without validation. Two are OOB writes, four are
OOB reads:

Proposed fixes in the following patches.

Thanks,
Tristan


^ permalink raw reply

* [PATCH v2 3/3] wifi: carl9170: fix buffer overflow in rx_stream failover path
From: Tristan Madani @ 2026-04-15 22:23 UTC (permalink / raw)
  To: Christian Lamparter; +Cc: Johannes Berg, linux-wireless, linux-kernel
In-Reply-To: <20260415222319.1538389-1-tristmd@gmail.com>

From: Tristan Madani <tristan@talencesecurity.com>

The failover continuation in carl9170_rx_stream() copies the full tlen
from the second USB transfer instead of capping at rx_failover_missing
bytes. When both transfers are near maximum size, the total exceeds the
65535-byte failover SKB, triggering skb_over_panic.

Limit the copy size to the missing byte count.

Fixes: a84fab3cbfdc ("carl9170: 802.11 rx/tx processing and usb backend")
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
---
drivers/net/wireless/ath/carl9170/rx.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/carl9170/rx.c b/drivers/net/wireless/ath/carl9170/rx.c
index XXXXXXX..XXXXXXX 100644
--- a/drivers/net/wireless/ath/carl9170/rx.c
+++ b/drivers/net/wireless/ath/carl9170/rx.c
@@ -918,7 +918,9 @@ static void carl9170_rx_stream(struct ar9170 *ar, void *buf, unsigned int len)
 			}
 		}

-		skb_put_data(ar->rx_failover, tbuf, tlen);
+		skb_put_data(ar->rx_failover, tbuf,
+			     min_t(unsigned int, tlen,
+				   ar->rx_failover_missing));
 		ar->rx_failover_missing -= tlen;

 		if (ar->rx_failover_missing <= 0) {


^ permalink raw reply

* [PATCH v2 2/3] wifi: carl9170: fix OOB read from off-by-two in TX status handler
From: Tristan Madani @ 2026-04-15 22:23 UTC (permalink / raw)
  To: Christian Lamparter; +Cc: Johannes Berg, linux-wireless, linux-kernel
In-Reply-To: <20260415222319.1538389-1-tristmd@gmail.com>

From: Tristan Madani <tristan@talencesecurity.com>

The bounds check in carl9170_tx_process_status() uses
`i > ((cmd->hdr.len / 2) + 1)` which is off by two, allowing
2 extra iterations past valid _tx_status entries when the firmware-
controlled hdr.ext exceeds hdr.len/2. Fix by using the correct
comparison `i >= (cmd->hdr.len / 2)`.

Fixes: a84fab3cbfdc ("carl9170: 802.11 rx/tx processing and usb backend")
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
---
drivers/net/wireless/ath/carl9170/tx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c
index XXXXXXX..XXXXXXX 100644
--- a/drivers/net/wireless/ath/carl9170/tx.c
+++ b/drivers/net/wireless/ath/carl9170/tx.c
@@ -695,7 +695,7 @@ static void carl9170_tx_process_status(struct ar9170 *ar,
 	unsigned int i;

 	for (i = 0;  i < cmd->hdr.ext; i++) {
-		if (WARN_ON(i > ((cmd->hdr.len / 2) + 1))) {
+		if (WARN_ON(i >= (cmd->hdr.len / 2))) {
 			print_hex_dump_bytes("UU:", DUMP_PREFIX_NONE,
 					     (void *) cmd, cmd->hdr.len + 4);
 			break;


^ permalink raw reply

* [PATCH v2 1/3] wifi: carl9170: bound memcpy length in cmd callback to prevent OOB read
From: Tristan Madani @ 2026-04-15 22:23 UTC (permalink / raw)
  To: Christian Lamparter; +Cc: Johannes Berg, linux-wireless, linux-kernel
In-Reply-To: <20260415222319.1538389-1-tristmd@gmail.com>

From: Tristan Madani <tristan@talencesecurity.com>

When the firmware sends a command response with a length mismatch,
carl9170_cmd_callback() logs the mismatch and calls carl9170_restart()
but then falls through to memcpy(ar->readbuf, buffer + 4, len - 4).
Since len comes from the firmware and can exceed ar->readlen, this
copies more data than the readbuf was allocated for.

Bound the memcpy to min(len - 4, ar->readlen) so that the response
is still completed -- avoiding repeated restarts from queued garbage --
while preventing an overread past the response buffer.

Fixes: a84fab3cbfdc ("carl9170: 802.11 rx/tx processing and usb backend")
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
---
Changes in v2:
  - v2: bound memcpy with min_t() instead of adding early return after
    carl9170_restart(), per Christian Lamparter's feedback. The restart
    path must handle queued responses gracefully.

drivers/net/wireless/ath/carl9170/rx.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/carl9170/rx.c b/drivers/net/wireless/ath/carl9170/rx.c
index XXXXXXX..XXXXXXX 100644
--- a/drivers/net/wireless/ath/carl9170/rx.c
+++ b/drivers/net/wireless/ath/carl9170/rx.c
@@ -151,7 +151,8 @@ static void carl9170_cmd_callback(struct ar9170 *ar, u32 len, void *buffer)
 	spin_lock(&ar->cmd_lock);
 	if (ar->readbuf) {
 		if (len >= 4)
-			memcpy(ar->readbuf, buffer + 4, len - 4);
+			memcpy(ar->readbuf, buffer + 4,
+			       min_t(u32, len - 4, ar->readlen));

 		ar->readbuf = NULL;
 	}
--
2.43.0


^ permalink raw reply

* [PATCH v2 0/3] wifi: carl9170: fix buffer overflow and OOB reads in firmware response handling
From: Tristan Madani @ 2026-04-15 22:23 UTC (permalink / raw)
  To: Christian Lamparter; +Cc: Johannes Berg, linux-wireless, linux-kernel

From: Tristan Madani <tristan@talencesecurity.com>

Hi Christian,

Note: this is a v2 resubmission. The original was sent via Gmail which
caused HTML rendering issues. This version uses git send-email for
proper plain-text formatting.

Three issues in carl9170 firmware response handling.

Changes since v1:
- Patch 1/3 (cmd_callback memcpy): bound with min_t() instead of early
  return after carl9170_restart(), per your feedback.

Proposed fixes in the following patches.

Thanks,
Tristan


^ permalink raw reply

* [PATCH v2 5/5] wifi: rsi: fix infinite loop when firmware sends zero-length packet
From: Tristan Madani @ 2026-04-15 22:23 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, linux-kernel
In-Reply-To: <20260415222307.1537309-1-tristmd@gmail.com>

From: Tristan Madani <tristan@talencesecurity.com>

rsi_read_pkt() reads actual_length from the frame descriptor as a u16.
When the firmware returns actual_length == 0, the loop's index and
rcv_pkt_len counters never change, creating an infinite kernel loop.

Check for zero actual_length immediately after reading it from the
descriptor and bail out if invalid.

Fixes: dad0d04fa7ba ("rsi: Add RS9113 wireless driver")
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
---
drivers/net/wireless/rsi/rsi_91x_main.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/wireless/rsi/rsi_91x_main.c b/drivers/net/wireless/rsi/rsi_91x_main.c
index XXXXXXX..XXXXXXX 100644
--- a/drivers/net/wireless/rsi/rsi_91x_main.c
+++ b/drivers/net/wireless/rsi/rsi_91x_main.c
@@ -168,6 +168,9 @@ int rsi_read_pkt(struct rsi_common *common, u8 *rx_pkt, s32 rcv_pkt_len)
 	do {
 		frame_desc = &rx_pkt[index];
 		actual_length = *(u16 *)&frame_desc[0];
+		if (!actual_length)
+			goto fail;
+
 		offset = *(u16 *)&frame_desc[2];
 		if (!rcv_pkt_len && offset >
 			RSI_MAX_RX_USB_PKT_SIZE - FRAME_DESC_SZ)
--
2.43.0


^ permalink raw reply

* [PATCH v2 4/5] wifi: rsi: fix OOB read from firmware pad_bytes in management RX path
From: Tristan Madani @ 2026-04-15 22:23 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, linux-kernel
In-Reply-To: <20260415222307.1537309-1-tristmd@gmail.com>

From: Tristan Madani <tristan@talencesecurity.com>

The firmware-controlled pad_bytes value (u8, from descriptor byte 4) is
used to shift the skb_put_data() source pointer forward in
rsi_mgmt_pkt_to_core(). While the existing msg_len -= pad_bytes check
catches the case where pad_bytes >= msg_len, it does not prevent a large
pad_bytes from shifting the read window into heap memory beyond the
actual packet data. The resulting kernel heap contents are delivered to
mac80211 as a management frame.

Add validation that pad_bytes does not exceed half of msg_len. Alignment
padding in 802.11 management frames is typically 0-3 bytes, so any
value exceeding msg_len / 2 indicates a corrupted descriptor.

Fixes: dad0d04fa7ba ("rsi: Add RS9113 wireless driver")
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
---
drivers/net/wireless/rsi/rsi_91x_mgmt.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/wireless/rsi/rsi_91x_mgmt.c b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
index XXXXXXX..XXXXXXX 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
@@ -490,6 +490,12 @@ static int rsi_mgmt_pkt_to_core(struct rsi_common *common,
 	u8 pad_bytes = msg[4];
 	struct sk_buff *skb;

+	if (pad_bytes > msg_len / 2) {
+		rsi_dbg(MGMT_RX_ZONE,
+			"%s: pad_bytes %u too large for msg_len %d\n",
+			__func__, pad_bytes, msg_len);
+		return -EINVAL;
+	}
 	if (!adapter->sc_nvifs)
 		return -ENOLINK;


^ permalink raw reply

* [PATCH v2 3/5] wifi: rsi: fix OOB read from firmware-claimed length exceeding actual frame size
From: Tristan Madani @ 2026-04-15 22:23 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, linux-kernel
In-Reply-To: <20260415222307.1537309-1-tristmd@gmail.com>

From: Tristan Madani <tristan@talencesecurity.com>

The firmware-controlled length field (12-bit, up to 4095) from the RX
descriptor is used as the memcpy size in rsi_prepare_skb(). No check
ensures this claimed length fits within the actual received data.
A malicious or malfunctioning firmware can cause out-of-bounds reads
past the RX buffer, leaking kernel heap contents into skbs delivered
to mac80211.

Add a bounds check in rsi_read_pkt() to reject frames where offset +
length exceeds actual_length.

Fixes: dad0d04fa7ba ("rsi: data and management rx path")
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
---
drivers/net/wireless/rsi/rsi_91x_main.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/wireless/rsi/rsi_91x_main.c b/drivers/net/wireless/rsi/rsi_91x_main.c
index XXXXXXX..XXXXXXX 100644
--- a/drivers/net/wireless/rsi/rsi_91x_main.c
+++ b/drivers/net/wireless/rsi/rsi_91x_main.c
@@ -179,6 +179,12 @@ int rsi_read_pkt(struct rsi_common *common, u8 *rx_pkt, s32 rcv_pkt_len)
 		queueno = rsi_get_queueno(frame_desc, offset);
 		length = rsi_get_length(frame_desc, offset);

+		if (offset + length > actual_length) {
+			rsi_dbg(ERR_ZONE,
+				"%s: frame overflows: offset %u + len %u > actual %u\n",
+				__func__, offset, length, actual_length);
+			goto fail;
+		}
 		/* Extended descriptor is valid for WLAN queues only */
 		if (queueno == RSI_WIFI_DATA_Q || queueno == RSI_WIFI_MGMT_Q)
 			extended_desc = rsi_get_extended_desc(frame_desc,


^ permalink raw reply

* [PATCH v2 2/5] wifi: rsi: fix integer underflow from firmware extended_desc in rsi_prepare_skb()
From: Tristan Madani @ 2026-04-15 22:23 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, linux-kernel
In-Reply-To: <20260415222307.1537309-1-tristmd@gmail.com>

From: Tristan Madani <tristan@talencesecurity.com>

The firmware-controlled extended_desc value is subtracted from pkt_len
without bounds checking. When extended_desc exceeds pkt_len, the u32
subtraction wraps, causing either a failed allocation (DoS) or an
out-of-bounds heap read via the subsequent memcpy from buffer +
payload_offset. Both SDIO and USB paths are affected.

Add a bounds check to reject packets where extended_desc exceeds
pkt_len.

Fixes: dad0d04fa7ba ("rsi: data and management rx path")
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
---
drivers/net/wireless/rsi/rsi_91x_main.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/net/wireless/rsi/rsi_91x_main.c b/drivers/net/wireless/rsi/rsi_91x_main.c
index XXXXXXX..XXXXXXX 100644
--- a/drivers/net/wireless/rsi/rsi_91x_main.c
+++ b/drivers/net/wireless/rsi/rsi_91x_main.c
@@ -136,6 +136,11 @@ static struct sk_buff *rsi_prepare_skb(struct rsi_common *common,
 		pkt_len = RSI_RCV_BUFFER_LEN * 4;
 	}

+	if (extended_desc > pkt_len) {
+		rsi_dbg(ERR_ZONE, "%s: extended_desc %u > pkt_len %u\n",
+			__func__, extended_desc, pkt_len);
+		return NULL;
+	}
 	pkt_len -= extended_desc;
 	skb = dev_alloc_skb(pkt_len + FRAME_DESC_SZ);
 	if (skb == NULL)


^ permalink raw reply

* [PATCH v2 1/5] wifi: rsi: fix OOB read from firmware offset field in SDIO RX path
From: Tristan Madani @ 2026-04-15 22:23 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, linux-kernel
In-Reply-To: <20260415222307.1537309-1-tristmd@gmail.com>

From: Tristan Madani <tristan@talencesecurity.com>

The firmware-controlled offset field in rsi_read_pkt() is validated only
when rcv_pkt_len is zero (USB path). For the SDIO path, rcv_pkt_len is
always positive, so the check is skipped entirely. A crafted offset can
cause out-of-bounds reads past the 8192-byte pktbuffer when computing
queue number, length, extended descriptor, and data pointers.

Add a transport-independent bounds check to reject offset values that
exceed the frame's actual_length.

Fixes: dad0d04fa7ba ("rsi: data and management rx path")
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
---
drivers/net/wireless/rsi/rsi_91x_main.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/net/wireless/rsi/rsi_91x_main.c b/drivers/net/wireless/rsi/rsi_91x_main.c
index XXXXXXX..XXXXXXX 100644
--- a/drivers/net/wireless/rsi/rsi_91x_main.c
+++ b/drivers/net/wireless/rsi/rsi_91x_main.c
@@ -171,6 +171,11 @@ int rsi_read_pkt(struct rsi_common *common, u8 *rx_pkt, s32 rcv_pkt_len)
 		if (!rcv_pkt_len && offset >
 			RSI_MAX_RX_USB_PKT_SIZE - FRAME_DESC_SZ)
 			goto fail;
+		if (offset > actual_length) {
+			rsi_dbg(ERR_ZONE,
+				"%s: offset %u exceeds length %u\n",
+				__func__, offset, actual_length);
+			goto fail;
+		}

 		queueno = rsi_get_queueno(frame_desc, offset);
 		length = rsi_get_length(frame_desc, offset);


^ permalink raw reply

* [PATCH v2 0/5] wifi: rsi: fix multiple firmware descriptor validation issues
From: Tristan Madani @ 2026-04-15 22:23 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, linux-kernel

From: Tristan Madani <tristan@talencesecurity.com>

Hi Johannes,

Note: this is a v2 resubmission. The original was sent via Gmail which
caused HTML rendering issues. This version uses git send-email for
proper plain-text formatting.

The rsi91x driver trusts several firmware-controlled fields without
validation across SDIO and USB transport paths. Five issues found:

Proposed fixes in the following patches.

Thanks,
Tristan


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox