* [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
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox