* [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
* Re: mt7996e kernel panic
From: Matteo Croce @ 2026-04-15 19:53 UTC (permalink / raw)
To: Felix Fietkau, Lorenzo Bianconi, Ryder Lee; +Cc: linux-wireless, linux-kernel
In-Reply-To: <afefde93-1f6a-4b3b-976b-87105615f931@gmail.com>
Hi,
I confirm that the router keeps on crashing even with 6.12.80 and latest mt76.
As I workaround I'm loading mt7996e with wed_enable=0 and i'ts been
stable since a week.
Regards,
--
Matteo Croce
perl -e 'for($t=0;;$t++){print chr($t*($t>>8|$t>>13)&255)}' |aplay
^ permalink raw reply
* Re: Firmware for reverse engineering b43?
From: Joshua Peisach @ 2026-04-15 18:58 UTC (permalink / raw)
To: Michael Büsch, Joshua Peisach
Cc: Jonas Gorski, Johannes Berg, linux-wireless, b43-dev, b43-dev
In-Reply-To: <20260415194150.291dbe2d@barney>
On Wed Apr 15, 2026 at 1:41 PM EDT, Michael Büsch wrote:
>
> Well, it probably still works well on the (few) devices it worked well on,
> because it basically hasn't changed.
> There are many devices which were never supported at all or were never supported
> properly. It's not that just your device is missing to complete
> the perfect picture :-)
>
Of course - but I don't currently feel like bending over backwards for
this one chip. Keep the working stuff working.
> There might be better uses of your time than working on this legacy stuff.
> For example working on the microcode reverse engineering and tools and
> get them updated for the current generation of devices is probably
> much more useful. And I think much more fun, too.
> Or something else altogether.
I can gladly say that using Ghidra on the firmware, v4, v5, and v6 is
amazing. Export symbols help a lot, and it gives you a good idea of what
is going on; with the exception of the decompiler giving goto statements
that jump all over the place and make things confusing :/
But again, it's legacy.
As for newer gens - I thought they are already provided by Broadcom
devs in the kernel? I may be wrong, I can look later.
Thanks :)
-Josh
^ permalink raw reply
* [PATCH] ssb: fix reference leaks on failed flash device registration
From: Guangshuo Li @ 2026-04-15 18:30 UTC (permalink / raw)
To: Michael Buesch, Rafał Miłecki, John W. Linville,
linux-wireless, linux-kernel
Cc: Guangshuo Li, stable
When platform_device_register() fails in ssb_devices_register(), the
embedded struct device in ssb_pflash_dev or ssb_sflash_dev has already
been initialized by device_initialize(), but the failure paths only
report the error and do not drop the device reference for the current
platform device:
ssb_devices_register()
-> platform_device_register(&ssb_pflash_dev)
-> device_initialize(&ssb_pflash_dev.dev)
-> setup_pdev_dma_masks(&ssb_pflash_dev)
-> platform_device_add(&ssb_pflash_dev)
ssb_devices_register()
-> platform_device_register(&ssb_sflash_dev)
-> device_initialize(&ssb_sflash_dev.dev)
-> setup_pdev_dma_masks(&ssb_sflash_dev)
-> platform_device_add(&ssb_sflash_dev)
This leads to reference leaks when platform_device_register() fails.
Fix this by calling platform_device_put() after reporting the error.
The issue was identified by a static analysis tool I developed and
confirmed by manual review.
Fixes: c7a4a9e3880cc ("ssb: register platform device for parallel flash")
Fixes: 7b5d6043de312 ("ssb: register serial flash as platform device")
Cc: stable@vger.kernel.org
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
---
drivers/ssb/main.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index b2d339eb57d5..5cdf612a8516 100644
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
@@ -535,16 +535,20 @@ static int ssb_devices_register(struct ssb_bus *bus)
#ifdef CONFIG_SSB_DRIVER_MIPS
if (bus->mipscore.pflash.present) {
err = platform_device_register(&ssb_pflash_dev);
- if (err)
+ if (err) {
pr_err("Error registering parallel flash\n");
+ platform_device_put(&ssb_pflash_dev);
+ }
}
#endif
#ifdef CONFIG_SSB_SFLASH
if (bus->mipscore.sflash.present) {
err = platform_device_register(&ssb_sflash_dev);
- if (err)
+ if (err) {
pr_err("Error registering serial flash\n");
+ platform_device_put(&ssb_sflash_dev);
+ }
}
#endif
--
2.43.0
^ permalink raw reply related
* Re: Firmware for reverse engineering b43?
From: Joshua Peisach @ 2026-04-15 17:04 UTC (permalink / raw)
To: Michael Büsch, Jonas Gorski
Cc: Johannes Berg, linux-wireless, b43-dev, b43-dev
In-Reply-To: <20260415175748.61aa7993@barney>
On Wed Apr 15, 2026 at 11:57 AM EDT, Michael Büsch wrote:
> On Wed, 15 Apr 2026 13:54:31 +0200
> Jonas Gorski <jonas.gorski@gmail.com> wrote:
>
>> On Wed, Apr 15, 2026 at 1:44 PM Joshua Peisach <jpeisach@ubuntu.com> wrote:
>> > It does appear to be similar - even the current brcm80211. So much so
>> > that I sometimes need to think about whether b43 is actually a
>> > duplicated driver.
>> >
>> > Since b43 is in an orphan state, I thought it would be a great place to
>> > start for kernel development. 5G doesn't work on that iMac, some of the
>> > PHYs, like the AC PHYs appear to be incomplete - it felt reasonable.
>> >
>> > Because I'm one of those "there's always room for improvement people",
>> > I was going to try to improve the driver, filling out TODOs, fixing
>> > hardcoded register numbers, etc. But if it's best left alone.. then I
>> > guess we can do that.
>> >
>> > That is, assuming b43 is actually supposed to be a separate driver,
>> > because if brcmsmac basically has the same code, then maybe we should
>> > focus to centralizing everything? But then there's b43legacy.. hm...
>>
>> It is/was intentionally a separate driver: Broadcom didn't want to
>> maintain support for obsolete chips (anything SSB, anything older than
>> BCM43224), so the decision was to have b43 support all the "legacy"
>> chips, while brcm80211 supports everything never. Since they were both
>> based on the same driver, they are (more or less) the same
>> architecture.
>>
>> But now that Broadcom has essentially abandoned the softmac part of
>> brcm80211 since several years, I don't think there would be many
>> objections on unifying it with b43.
>
> The hardest part in the b43 development always was not to break already
> working stuff. There are many different types and revisions of the hardware
> out there. Probably in the order of many dozens of variants.
>
> Please keep in mind that changing code means mostly testing.
> Which is hard, if you don't have the hardware variants and basically no
> users exist anymore. Just implementing random TODOs and missing pieces
> will break things. (e.g. not doing some HW calibration or workaround might
> be better than only partially doing it or doing it wrong).
>
Well, if the regression risk is that high, then I guess I'll let it be.
> I would personally not touch this thing anymore, except for security fixes and such.
>
Sure. I might just make sure everything is using register definitions
instead of hardcoded values, but then leave it there.
> But if you want to work on the code, long term, I would welcome that.
> We could even arrange that I ship you some hardware.
> But keep in mind, it's all almost 20 years old legacy stuff.
The only b43 devices I have are the aforementioned iMac, and also the
Wii. And unless the hardware is unique in some other way, I don't think
its worth sending it to me. Besides, if the code is so risky to touch,
then the only technical change I make should just be to fix my 5G
situation.
I didn't intend to become a b43 maintainer, and given where I currently
am lifewise, I don't think it's worth trying to fulfill that role long
term. Hopefully I'll find areas of work in brcm80211 to work in. It
just so happened that "make sure the kernel works on everything you can
get your hands on" stumbled across b43, which I thought would be a good
starting point.
So I guess this driver just sits here.. not quite pointless to be
removed from the main tree, but not quite worth the effort to bring it
up to speed.
^ 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