* [PATCH v2 3/3] wifi: wcn36xx: fix OOB read from short trigger BA firmware response
From: Tristan Madani @ 2026-04-15 22:37 UTC (permalink / raw)
To: Loic Poulain; +Cc: Johannes Berg, wcn36xx, linux-wireless
In-Reply-To: <20260415223710.1616925-1-tristmd@gmail.com>
From: Tristan Madani <tristan@talencesecurity.com>
The firmware response length is only checked against sizeof(*rsp) (20
bytes), but when candidate_cnt >= 1, a 22-byte candidate struct is read
at buf + 20 without verifying the response contains it. This causes an
out-of-bounds read of stale heap data, corrupting the BA session state.
Add validation that the response includes the candidate data.
Fixes: 16be1ac55944 ("wcn36xx: Parse trigger_ba response properly")
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
---
drivers/net/wireless/ath/wcn36xx/smd.c | 3 +++
1 file changed, 3 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
@@ -2599,6 +2599,9 @@ static int wcn36xx_smd_trigger_ba_rsp(void *buf, int len, struct add_ba_info *ba
if (rsp->candidate_cnt < 1)
return rsp->status ? rsp->status : -EINVAL;
+ if (len < sizeof(*rsp) + sizeof(*candidate))
+ return -EINVAL;
+
candidate = (struct wcn36xx_hal_trigger_ba_rsp_candidate *)(buf + sizeof(*rsp));
for (i = 0; i < STACFG_MAX_TC; i++) {
^ permalink raw reply
* [PATCH v2 2/3] wifi: wcn36xx: fix OOB read from firmware count in PRINT_REG_INFO indication
From: Tristan Madani @ 2026-04-15 22:37 UTC (permalink / raw)
To: Loic Poulain; +Cc: Johannes Berg, wcn36xx, linux-wireless
In-Reply-To: <20260415223710.1616925-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:37 UTC (permalink / raw)
To: Loic Poulain; +Cc: Johannes Berg, wcn36xx, linux-wireless
In-Reply-To: <20260415223710.1616925-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:37 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 2/2] wifi: libertas: fix OOB read from firmware bssdescriptsize in scan response
From: Tristan Madani @ 2026-04-15 22:24 UTC (permalink / raw)
To: Johannes Berg; +Cc: libertas-dev, linux-wireless
In-Reply-To: <20260415222446.1546616-1-tristmd@gmail.com>
From: Tristan Madani <tristan@talencesecurity.com>
The firmware-controlled bssdescriptsize field in lbs_ret_scan() is used
to compute the TSF descriptor position without validation against the
response buffer size. An inflated value causes out-of-bounds reads from
the 2312-byte response buffer into adjacent struct lbs_private members.
Add a check that bssdescriptsize fits within the response data.
Fixes: ff9fc791940f ("libertas: first stab at cfg80211 support")
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
---
drivers/net/wireless/marvell/libertas/cfg.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/net/wireless/marvell/libertas/cfg.c b/drivers/net/wireless/marvell/libertas/cfg.c
index XXXXXXX..XXXXXXX 100644
--- a/drivers/net/wireless/marvell/libertas/cfg.c
+++ b/drivers/net/wireless/marvell/libertas/cfg.c
@@ -555,6 +555,14 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy,
bsssize = get_unaligned_le16(&scanresp->bssdescriptsize);
+ if (bsssize > le16_to_cpu(resp->size) -
+ sizeof(struct cmd_ds_802_11_scan_rsp)) {
+ lbs_deb_scan(
+ "scan response: bssdescriptsize %d exceeds response\n",
+ bsssize);
+ goto done;
+ }
+
lbs_deb_scan("scan response: %d BSSs (%d bytes); resp size %d bytes\n",
scanresp->nr_sets, bsssize, le16_to_cpu(resp->size));
^ permalink raw reply
* [PATCH v2 1/2] wifi: libertas: fix OOB read from firmware pkt_ptr offset in RX path
From: Tristan Madani @ 2026-04-15 22:24 UTC (permalink / raw)
To: Johannes Berg; +Cc: libertas-dev, linux-wireless
In-Reply-To: <20260415222446.1546616-1-tristmd@gmail.com>
From: Tristan Madani <tristan@talencesecurity.com>
lbs_process_rxed_packet() uses the firmware-supplied pkt_ptr as an
offset into the skb data without validating that it falls within the
skb buffer bounds. A malicious pkt_ptr value causes out-of-bounds
memory access when the function subsequently reads ethernet header
fields from p_rx_pkt.
Add a bounds check to ensure pkt_ptr plus the minimum packet header
size does not exceed skb->len.
Fixes: e45d8e534b67 ("libertas: add support for Marvell SD8688 chip")
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
---
drivers/net/wireless/marvell/libertas/rx.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/net/wireless/marvell/libertas/rx.c b/drivers/net/wireless/marvell/libertas/rx.c
index XXXXXXX..XXXXXXX 100644
--- a/drivers/net/wireless/marvell/libertas/rx.c
+++ b/drivers/net/wireless/marvell/libertas/rx.c
@@ -75,6 +75,14 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb)
p_rx_pd = (struct rxpd *) skb->data;
+
+ if (le32_to_cpu(p_rx_pd->pkt_ptr) + sizeof(struct rxpackethdr) >
+ skb->len) {
+ lbs_deb_rx("rx err: pkt_ptr %u beyond skb len %u\n",
+ le32_to_cpu(p_rx_pd->pkt_ptr), skb->len);
+ ret = -EINVAL;
+ dev_kfree_skb(skb);
+ goto done;
+ }
p_rx_pkt = (struct rxpackethdr *) ((u8 *)p_rx_pd +
le32_to_cpu(p_rx_pd->pkt_ptr));
--
2.43.0
^ permalink raw reply
* [PATCH v2 0/2] wifi: libertas: fix OOB reads from firmware response fields
From: Tristan Madani @ 2026-04-15 22:24 UTC (permalink / raw)
To: Johannes Berg; +Cc: libertas-dev, linux-wireless
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.
Two issues in libertas where firmware-controlled fields are used as
buffer offsets without validation:
Proposed fixes in the following patches.
Thanks,
Tristan
^ permalink raw reply
* [PATCH v2] wifi: rtw88: fix OOB read from firmware RX descriptor exceeding DMA buffer
From: Tristan Madani @ 2026-04-15 22:24 UTC (permalink / raw)
To: Ping-Ke Shih; +Cc: Johannes Berg, linux-wireless
From: Tristan Madani <tristan@talencesecurity.com>
In rtw_pci_rx_napi(), new_len is computed as the sum of pkt_len (14-bit
descriptor field, max 16383) and pkt_offset (drv_info_sz + shift, both
firmware-controlled). The result can exceed RTK_PCI_RX_BUF_SIZE (11478),
causing an out-of-bounds read from the pre-allocated DMA buffer when
skb_put_data copies new_len bytes. The USB transport already validates
this (rtw_usb_rx_data_put checks against RTW_USB_MAX_RECVBUF_SZ); the
PCIe path does not.
Add a check that new_len does not exceed the DMA buffer size.
Fixes: e3037485c68e ("rtw88: new Realtek 802.11ac driver")
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.
Changes in v2:
- v2: clarify field widths and maximum new_len derivation in commit
message, per Ping-Ke Shih's feedback.
drivers/net/wireless/realtek/rtw88/pci.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/realtek/rtw88/pci.c
index XXXXXXX..XXXXXXX 100644
--- a/drivers/net/wireless/realtek/rtw88/pci.c
+++ b/drivers/net/wireless/realtek/rtw88/pci.c
@@ -1078,6 +1078,11 @@ static int rtw_pci_rx_napi(struct rtw_dev *rtwdev, struct rtw_pci *rtwpci,
new_len = pkt_stat.pkt_len + pkt_offset;
+ if (new_len > RTK_PCI_RX_BUF_SIZE) {
+ rtw_dbg(rtwdev, RTW_DBG_RX,
+ "oversized RX packet: %u\n", new_len);
+ goto next_rp;
+ }
new = dev_alloc_skb(new_len);
if (WARN_ONCE(!new, "rx routine starvation\n"))
goto next_rp;
^ permalink raw reply
* [PATCH v2] wifi: rtw89: add bounds check on firmware mac_id in link lookup
From: Tristan Madani @ 2026-04-15 22:24 UTC (permalink / raw)
To: Ping-Ke Shih; +Cc: Johannes Berg, linux-wireless
From: Tristan Madani <tristan@talencesecurity.com>
The mac_id field in RX descriptors is 8 bits wide (0-255), but
assoc_link_on_macid[] has only RTW89_MAX_MAC_ID_NUM (128) entries.
While the driver currently assigns mac_id values below 128, the
descriptor value comes from firmware and is not validated before use
as an array index. Add a defensive bounds check in
rtw89_assoc_link_rcu_dereference() to guard against out-of-range
firmware values.
Fixes: 144c6cd24b35 ("wifi: rtw89: 8922a: configure AP_LINK_PS if FW supports")
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.
Changes in v2:
- v2: reframe as defensive bounds check. The driver assigns mac_id
values below 128, but the RX descriptor field is 8-bit.
drivers/net/wireless/realtek/rtw89/core.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index XXXXXXX..XXXXXXX 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -6435,6 +6435,9 @@ static inline struct rtw89_sta_link *
rtw89_assoc_link_rcu_dereference(struct rtw89_dev *rtwdev, u8 macid)
{
+ if (macid >= RTW89_MAX_MAC_ID_NUM)
+ return NULL;
+
return rcu_dereference(rtwdev->assoc_link_on_macid[macid]);
}
^ permalink raw reply
* [PATCH v2 2/2] wifi: b43: fix OOB read from hardware key index in b43_rx()
From: Tristan Madani @ 2026-04-15 22:24 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, b43-dev, linux-kernel
In-Reply-To: <20260415222425.1544638-1-tristmd@gmail.com>
From: Tristan Madani <tristan@talencesecurity.com>
The firmware-controlled key index in b43_rx() can exceed the dev->key[]
array size (58 entries). The existing B43_WARN_ON is non-enforcing in
production builds, allowing an out-of-bounds read of 1 byte from struct
b43_firmware. A non-zero OOB value causes RX_FLAG_DECRYPTED to be
incorrectly set on un-decrypted frames.
Replace with an enforcing check that skips the key lookup for invalid
indices.
Fixes: e4d6b7951812 ("[B43]: add mac80211-based driver for modern BCM43xx devices")
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
---
drivers/net/wireless/broadcom/b43/xmit.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/broadcom/b43/xmit.c b/drivers/net/wireless/broadcom/b43/xmit.c
index XXXXXXX..XXXXXXX 100644
--- a/drivers/net/wireless/broadcom/b43/xmit.c
+++ b/drivers/net/wireless/broadcom/b43/xmit.c
@@ -704,7 +704,10 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
*/
keyidx = b43_kidx_to_raw(dev, keyidx);
- B43_WARN_ON(keyidx >= ARRAY_SIZE(dev->key));
+ if (keyidx >= ARRAY_SIZE(dev->key)) {
+ b43dbg(dev->wl, "RX: invalid key index %u\n", keyidx);
+ goto drop;
+ }
if (dev->key[keyidx].algorithm != B43_SEC_ALGO_NONE) {
wlhdr_len = ieee80211_hdrlen(fctl);
^ permalink raw reply
* [PATCH v2 1/2] wifi: b43: fix infinite loop from invalid hardware DMA RX slot
From: Tristan Madani @ 2026-04-15 22:24 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, b43-dev, linux-kernel
In-Reply-To: <20260415222425.1544638-1-tristmd@gmail.com>
From: Tristan Madani <tristan@talencesecurity.com>
b43_dma_rx() reads current_slot from hardware via get_current_rxslot().
If the value is >= ring->nr_slots, the B43_WARN_ON only warns but
continues. The for loop then never terminates because next_slot() wraps
modulo nr_slots and can never reach the out-of-range current_slot.
Replace the B43_WARN_ON with an explicit bounds check that returns
early when the hardware reports an invalid slot index.
Fixes: e4d6b7951812 ("[B43]: add mac80211-based driver for modern BCM43xx devices")
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
---
drivers/net/wireless/broadcom/b43/dma.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/broadcom/b43/dma.c b/drivers/net/wireless/broadcom/b43/dma.c
index XXXXXXX..XXXXXXX 100644
--- a/drivers/net/wireless/broadcom/b43/dma.c
+++ b/drivers/net/wireless/broadcom/b43/dma.c
@@ -1693,7 +1693,10 @@ void b43_dma_rx(struct b43_dmaring *ring)
B43_WARN_ON(ring->tx);
current_slot = ops->get_current_rxslot(ring);
- B43_WARN_ON(!(current_slot >= 0 && current_slot < ring->nr_slots));
+ if (!(current_slot >= 0 && current_slot < ring->nr_slots)) {
+ B43_WARN_ON(1);
+ return;
+ }
slot = ring->current_slot;
for (; slot != current_slot; slot = next_slot(ring, slot)) {
--
2.43.0
^ permalink raw reply
* [PATCH v2 0/2] wifi: b43: fix OOB read and infinite loop from hardware-reported values
From: Tristan Madani @ 2026-04-15 22:24 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, b43-dev, 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.
Two issues in b43 where hardware-reported values are used without
bounds checking:
Proposed fixes in the following patches.
Thanks,
Tristan
^ permalink raw reply
* [PATCH v2 2/2] wifi: wilc1000: fix OOB read from firmware RX packet header fields
From: Tristan Madani @ 2026-04-15 22:24 UTC (permalink / raw)
To: Ajay Singh, Claudiu Beznea; +Cc: Johannes Berg, linux-wireless
In-Reply-To: <20260415222418.1543832-1-tristmd@gmail.com>
From: Tristan Madani <tristan@talencesecurity.com>
The firmware-controlled pkt_len, tp_len, and pkt_offset fields from RX
frame headers are used without validation against the buffer size. This
allows a malicious or malfunctioning firmware to cause out-of-bounds
reads from the RX buffer via wilc_frmw_to_host() and
wilc_wfi_mgmt_rx() memcpy operations.
Add bounds checks to ensure tp_len does not exceed remaining buffer
space, and pkt_len + pkt_offset fits within tp_len.
Fixes: c5c77ba18ea6 ("staging: wilc1000: Add SDIO/SPI 802.11 driver")
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
---
drivers/net/wireless/microchip/wilc1000/wlan.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/net/wireless/microchip/wilc1000/wlan.c b/drivers/net/wireless/microchip/wilc1000/wlan.c
index XXXXXXX..XXXXXXX 100644
--- a/drivers/net/wireless/microchip/wilc1000/wlan.c
+++ b/drivers/net/wireless/microchip/wilc1000/wlan.c
@@ -1122,6 +1122,12 @@ static void wilc_wlan_handle_rx_buff(struct wilc *wilc, u8 *buffer, int size)
if (pkt_len == 0 || tp_len == 0)
break;
+ if (tp_len > size - offset || pkt_len > tp_len) {
+ dev_err(wilc->dev, "invalid RX header: tp=%u pkt=%u remain=%d\n",
+ tp_len, pkt_len, size - offset);
+ break;
+ }
if (pkt_offset & IS_MANAGMEMENT) {
buff_ptr += HOST_HDR_OFFSET;
wilc_wfi_mgmt_rx(wilc, buff_ptr, pkt_len,
^ permalink raw reply
* [PATCH v2 1/2] wifi: wilc1000: fix integer underflow in wilc_network_info_received()
From: Tristan Madani @ 2026-04-15 22:24 UTC (permalink / raw)
To: Ajay Singh, Claudiu Beznea; +Cc: Johannes Berg, linux-wireless
In-Reply-To: <20260415222418.1543832-1-tristmd@gmail.com>
From: Tristan Madani <tristan@talencesecurity.com>
The firmware-controlled frame length at buffer[6..7] is decremented by 1
and used as the kmemdup size without validating the value. When the
firmware sends 0, the u16 subtraction wraps to 65535, causing a 64KB
out-of-bounds read from the RX buffer. For non-zero but inflated values,
the read exceeds the actual packet data.
Add validation that the frame length is at least 1 and fits within the
available buffer.
Fixes: c5c77ba18ea6 ("staging: wilc1000: Add SDIO/SPI 802.11 driver")
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
---
drivers/net/wireless/microchip/wilc1000/hif.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/net/wireless/microchip/wilc1000/hif.c b/drivers/net/wireless/microchip/wilc1000/hif.c
index XXXXXXX..XXXXXXX 100644
--- a/drivers/net/wireless/microchip/wilc1000/hif.c
+++ b/drivers/net/wireless/microchip/wilc1000/hif.c
@@ -1572,6 +1572,7 @@ void wilc_network_info_received(struct wilc *wilc, u8 *buffer, u32 length)
struct wilc_vif *vif;
int srcu_idx;
int result;
+ u16 frame_len;
int id;
id = get_unaligned_le32(&buffer[length - 4]);
@@ -1595,7 +1596,14 @@ void wilc_network_info_received(struct wilc *wilc, u8 *buffer, u32 length)
if (IS_ERR(msg))
goto out;
- msg->body.net_info.frame_len = get_unaligned_le16(&buffer[6]) - 1;
+ frame_len = get_unaligned_le16(&buffer[6]);
+ if (frame_len == 0 || frame_len > length - 9) {
+ netdev_err(vif->ndev,
+ "%s: invalid frame_len %u (buffer %u)\n",
+ __func__, frame_len, length);
+ kfree(msg);
+ goto out;
+ }
+ msg->body.net_info.frame_len = frame_len - 1;
msg->body.net_info.rssi = buffer[8];
msg->body.net_info.mgmt = kmemdup(&buffer[9],
msg->body.net_info.frame_len,
^ permalink raw reply
* [PATCH v2 0/2] wifi: wilc1000: fix integer underflow and OOB read from firmware packets
From: Tristan Madani @ 2026-04-15 22:24 UTC (permalink / raw)
To: Ajay Singh, Claudiu Beznea; +Cc: Johannes Berg, linux-wireless
From: Tristan Madani <tristan@talencesecurity.com>
Hi Ajay, Claudiu,
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.
Two issues in wilc1000 where firmware-controlled packet fields are used
without validation:
Proposed fixes in the following patches.
Thanks,
Tristan
^ permalink raw reply
* [PATCH v2 3/3] wifi: wl18xx: fix OOB read from firmware SSID/password lengths in smart config event
From: Tristan Madani @ 2026-04-15 22:24 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, linux-kernel
In-Reply-To: <20260415222409.1542989-1-tristmd@gmail.com>
From: Tristan Madani <tristan@talencesecurity.com>
The firmware-controlled sc_ssid_len and sc_pwd_len values are used as
nla_put sizes from fixed-size mailbox buffers (32 and 64 bytes) without
bounds checking. Values exceeding the buffer sizes cause out-of-bounds
reads delivered to userspace via nl80211 vendor events.
Clamp the lengths to the mailbox buffer sizes before use.
Fixes: e93e15fb47e5 ("wlcore/wl18xx: handle smart config events")
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
---
drivers/net/wireless/ti/wl18xx/event.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/wireless/ti/wl18xx/event.c b/drivers/net/wireless/ti/wl18xx/event.c
index XXXXXXX..XXXXXXX 100644
--- a/drivers/net/wireless/ti/wl18xx/event.c
+++ b/drivers/net/wireless/ti/wl18xx/event.c
@@ -82,6 +82,9 @@ static int wlcore_smart_config_decode_event(struct wl1271 *wl,
{
struct sk_buff *skb;
+ ssid_len = min_t(u8, ssid_len, 32);
+ pwd_len = min_t(u8, pwd_len, 64);
+
wl1271_debug(DEBUG_EVENT, "SMART_CONFIG_DECODE_EVENT_ID");
wl1271_dump_ascii(DEBUG_EVENT, "SSID:", ssid, ssid_len);
^ permalink raw reply
* [PATCH v2 2/3] wifi: wlcore: fix OOB read from firmware max_buff_size in logger handler
From: Tristan Madani @ 2026-04-15 22:24 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, linux-kernel
In-Reply-To: <20260415222409.1542989-1-tristmd@gmail.com>
From: Tristan Madani <tristan@talencesecurity.com>
The firmware-controlled max_buff_size field is used to compute buffer
offsets in wlcore_event_fw_logger() without validation against the
4128-byte kernel allocation. An inflated value causes out-of-bounds
reads from kernel heap, with the data written to the debugfs-accessible
fwlog ring buffer.
Cap max_buff_size at the allocation size minus the header offset.
Fixes: 3719c17e1816 ("wlcore/wl18xx: fw logger over sdio")
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
---
drivers/net/wireless/ti/wlcore/event.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/net/wireless/ti/wlcore/event.c b/drivers/net/wireless/ti/wlcore/event.c
index XXXXXXX..XXXXXXX 100644
--- a/drivers/net/wireless/ti/wlcore/event.c
+++ b/drivers/net/wireless/ti/wlcore/event.c
@@ -62,6 +62,13 @@ void wlcore_event_fw_logger(struct wl1271 *wl)
if (actual_len == 0)
goto free_out;
+ if (le32_to_cpu(fw_log.max_buff_size) >
+ WL18XX_LOGGER_SDIO_BUFF_MAX - WL18XX_LOGGER_BUFF_OFFSET) {
+ wl1271_error("fw logger: max_buff_size %u exceeds buffer\n",
+ le32_to_cpu(fw_log.max_buff_size));
+ goto free_out;
+ }
+
/* Calculate the internal pointer to the fwlog structure */
addr_ptr = internal_fw_addrbase + addr;
^ permalink raw reply
* [PATCH v2 1/3] wifi: wl18xx: fix OOB read from firmware rx_ba_link_id in BA event handler
From: Tristan Madani @ 2026-04-15 22:24 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, linux-kernel
In-Reply-To: <20260415222409.1542989-1-tristmd@gmail.com>
From: Tristan Madani <tristan@talencesecurity.com>
The firmware-controlled rx_ba_link_id (u8) is used to index the 16-entry
wl->links[] array without bounds checking in the BA window size change
event handler. An out-of-range value causes OOB reads and an immediate
pointer dereference of the OOB wlvif field.
Add bounds validation consistent with all other HLID consumers in the
driver.
Fixes: d4392269f7ce ("wlcore: Add RX_BA_WIN_SIZE_CHANGE_EVENT event")
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
---
drivers/net/wireless/ti/wl18xx/event.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/net/wireless/ti/wl18xx/event.c b/drivers/net/wireless/ti/wl18xx/event.c
index XXXXXXX..XXXXXXX 100644
--- a/drivers/net/wireless/ti/wl18xx/event.c
+++ b/drivers/net/wireless/ti/wl18xx/event.c
@@ -211,6 +211,12 @@ int wl18xx_process_mailbox_events(struct wl1271 *wl)
u8 win_size = mbox->rx_ba_win_size;
const u8 *addr;
+ if (link_id >= WLCORE_MAX_LINKS) {
+ wl1271_error("BA event: invalid link_id %u\n",
+ link_id);
+ goto out;
+ }
+
wlvif = wl->links[link_id].wlvif;
vif = wl12xx_wlvif_to_vif(wlvif);
^ permalink raw reply
* [PATCH v2 0/3] wifi: wlcore: fix OOB reads from firmware event fields
From: Tristan Madani @ 2026-04-15 22:24 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 wlcore/wl18xx where firmware-controlled fields are used
as array indices or buffer offsets without validation:
Proposed fixes in the following patches.
Thanks,
Tristan
^ permalink raw reply
* [PATCH v2 3/3] wifi: wcn36xx: fix OOB read from short trigger BA firmware 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 length is only checked against sizeof(*rsp) (20
bytes), but when candidate_cnt >= 1, a 22-byte candidate struct is read
at buf + 20 without verifying the response contains it. This causes an
out-of-bounds read of stale heap data, corrupting the BA session state.
Add validation that the response includes the candidate data.
Fixes: 16be1ac55944 ("wcn36xx: Parse trigger_ba response properly")
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
---
drivers/net/wireless/ath/wcn36xx/smd.c | 3 +++
1 file changed, 3 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
@@ -2599,6 +2599,9 @@ static int wcn36xx_smd_trigger_ba_rsp(void *buf, int len, struct add_ba_info *ba
if (rsp->candidate_cnt < 1)
return rsp->status ? rsp->status : -EINVAL;
+ if (len < sizeof(*rsp) + sizeof(*candidate))
+ return -EINVAL;
+
candidate = (struct wcn36xx_hal_trigger_ba_rsp_candidate *)(buf + sizeof(*rsp));
for (i = 0; i < STACFG_MAX_TC; i++) {
^ permalink raw reply
* [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
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