From f8770d9a41e90b1e0f344b2d975b011af6895f14 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 31 Mar 2026 16:05:42 +0000 Subject: [PATCH 1/3] Fix bugs in mt76x02/mt76x2 code: VIF WCID collision, unchecked MCU returns, firmware validation overflow Agent-Logs-Url: https://github.com/HiGarfield/mt76/sessions/c3ba98dd-c66d-4a8f-83b4-d405222de6f8 Co-authored-by: HiGarfield <32226909+HiGarfield@users.noreply.github.com> --- mt76x02_mac.h | 4 ++-- mt76x2/mcu.c | 7 ++++++- mt76x2/pci_mcu.c | 22 ++++++++++------------ mt76x2/usb_mcu.c | 8 +++++--- 4 files changed, 23 insertions(+), 18 deletions(-) diff --git a/mt76x02_mac.h b/mt76x02_mac.h index c70d17b2..e597a246 100644 --- a/mt76x02_mac.h +++ b/mt76x02_mac.h @@ -20,8 +20,8 @@ struct mt76x02_tx_status { u16 rate; } __packed __aligned(2); -#define MT_VIF_WCID(_n) (254 - ((_n) & 7)) -#define MT_MAX_VIFS 8 +#define MT_VIF_WCID(_n) (254 - ((_n) & 0xf)) +#define MT_MAX_VIFS 16 #define MT_PKTID_RATE GENMASK(4, 0) #define MT_PKTID_AC GENMASK(6, 5) diff --git a/mt76x2/mcu.c b/mt76x2/mcu.c index 9635c04c..62214606 100644 --- a/mt76x2/mcu.c +++ b/mt76x2/mcu.c @@ -32,8 +32,13 @@ int mt76x2_mcu_set_channel(struct mt76x02_dev *dev, u8 channel, u8 bw, .chainmask = cpu_to_le16(dev->chainmask), }; + int ret; + /* first set the channel without the extension channel info */ - mt76_mcu_send_msg(dev, CMD_SWITCH_CHANNEL_OP, &msg, sizeof(msg), true); + ret = mt76_mcu_send_msg(dev, CMD_SWITCH_CHANNEL_OP, &msg, sizeof(msg), + true); + if (ret) + return ret; usleep_range(5000, 10000); diff --git a/mt76x2/pci_mcu.c b/mt76x2/pci_mcu.c index ec64bd8b..ef7a1fe7 100644 --- a/mt76x2/pci_mcu.c +++ b/mt76x2/pci_mcu.c @@ -82,7 +82,8 @@ mt76pci_load_firmware(struct mt76x02_dev *dev) { const struct firmware *fw; const struct mt76x02_fw_header *hdr; - int len, ret; + int ret; + u32 ilm_len, dlm_len; __le32 *cur; u32 offset, val; @@ -95,11 +96,11 @@ mt76pci_load_firmware(struct mt76x02_dev *dev) hdr = (const struct mt76x02_fw_header *)fw->data; - len = sizeof(*hdr); - len += le32_to_cpu(hdr->ilm_len); - len += le32_to_cpu(hdr->dlm_len); + ilm_len = le32_to_cpu(hdr->ilm_len); + dlm_len = le32_to_cpu(hdr->dlm_len); - if (fw->size != len) + if (ilm_len > fw->size - sizeof(*hdr) || + dlm_len != fw->size - sizeof(*hdr) - ilm_len) goto error; val = le16_to_cpu(hdr->fw_ver); @@ -111,13 +112,11 @@ mt76pci_load_firmware(struct mt76x02_dev *dev) dev_info(dev->mt76.dev, "Build Time: %.16s\n", hdr->build_time); cur = (__le32 *)(fw->data + sizeof(*hdr)); - len = le32_to_cpu(hdr->ilm_len); mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, MT_MCU_ILM_OFFSET); - mt76_wr_copy(dev, MT_MCU_ILM_ADDR, cur, len); + mt76_wr_copy(dev, MT_MCU_ILM_ADDR, cur, ilm_len); - cur += len / sizeof(*cur); - len = le32_to_cpu(hdr->dlm_len); + cur += ilm_len / sizeof(*cur); if (mt76xx_rev(dev) >= MT76XX_REV_E3) offset = MT_MCU_DLM_ADDR_E3; @@ -125,7 +124,7 @@ mt76pci_load_firmware(struct mt76x02_dev *dev) offset = MT_MCU_DLM_ADDR; mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, MT_MCU_DLM_OFFSET); - mt76_wr_copy(dev, offset, cur, len); + mt76_wr_copy(dev, offset, cur, dlm_len); mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, 0); @@ -192,6 +191,5 @@ int mt76x2_mcu_init(struct mt76x02_dev *dev) if (ret) return ret; - mt76x02_mcu_function_select(dev, Q_SELECT, 1); - return 0; + return mt76x02_mcu_function_select(dev, Q_SELECT, 1); } diff --git a/mt76x2/usb_mcu.c b/mt76x2/usb_mcu.c index dd22d8af..0a9534ad 100644 --- a/mt76x2/usb_mcu.c +++ b/mt76x2/usb_mcu.c @@ -145,7 +145,8 @@ static int mt76x2u_mcu_load_firmware(struct mt76x02_dev *dev) { u32 val, dlm_offset = MT76U_MCU_DLM_OFFSET; const struct mt76x02_fw_header *hdr; - int err, len, ilm_len, dlm_len; + int err; + u32 ilm_len, dlm_len; const struct firmware *fw; err = request_firmware(&fw, MT7662_FIRMWARE, dev->mt76.dev); @@ -160,8 +161,9 @@ static int mt76x2u_mcu_load_firmware(struct mt76x02_dev *dev) hdr = (const struct mt76x02_fw_header *)fw->data; ilm_len = le32_to_cpu(hdr->ilm_len); dlm_len = le32_to_cpu(hdr->dlm_len); - len = sizeof(*hdr) + ilm_len + dlm_len; - if (fw->size != len) { + + if (ilm_len > fw->size - sizeof(*hdr) || + dlm_len != fw->size - sizeof(*hdr) - ilm_len) { err = -EINVAL; goto out; } From df6dad5867d9023a50924314112990138affad32 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 31 Mar 2026 16:43:15 +0000 Subject: [PATCH 2/3] Add firmware length alignment and INT_MAX bounds checks for ilm_len/dlm_len Agent-Logs-Url: https://github.com/HiGarfield/mt76/sessions/9ef155e1-f7ec-4760-afd0-8957b7dc1525 Co-authored-by: HiGarfield <32226909+HiGarfield@users.noreply.github.com> --- mt76x2/pci_mcu.c | 4 +++- mt76x2/usb_mcu.c | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/mt76x2/pci_mcu.c b/mt76x2/pci_mcu.c index ef7a1fe7..1d517191 100644 --- a/mt76x2/pci_mcu.c +++ b/mt76x2/pci_mcu.c @@ -99,7 +99,9 @@ mt76pci_load_firmware(struct mt76x02_dev *dev) ilm_len = le32_to_cpu(hdr->ilm_len); dlm_len = le32_to_cpu(hdr->dlm_len); - if (ilm_len > fw->size - sizeof(*hdr) || + if ((ilm_len | dlm_len) & 3 || + ilm_len > INT_MAX || dlm_len > INT_MAX || + ilm_len > fw->size - sizeof(*hdr) || dlm_len != fw->size - sizeof(*hdr) - ilm_len) goto error; diff --git a/mt76x2/usb_mcu.c b/mt76x2/usb_mcu.c index 0a9534ad..e7876087 100644 --- a/mt76x2/usb_mcu.c +++ b/mt76x2/usb_mcu.c @@ -162,7 +162,8 @@ static int mt76x2u_mcu_load_firmware(struct mt76x02_dev *dev) ilm_len = le32_to_cpu(hdr->ilm_len); dlm_len = le32_to_cpu(hdr->dlm_len); - if (ilm_len > fw->size - sizeof(*hdr) || + if (ilm_len > INT_MAX || dlm_len > INT_MAX || + ilm_len > fw->size - sizeof(*hdr) || dlm_len != fw->size - sizeof(*hdr) - ilm_len) { err = -EINVAL; goto out; From 3b23a2aec954767fd6ed794bd68e024a76c86075 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 31 Mar 2026 16:43:55 +0000 Subject: [PATCH 3/3] Reorder firmware validation: bounds checks before alignment check Agent-Logs-Url: https://github.com/HiGarfield/mt76/sessions/9ef155e1-f7ec-4760-afd0-8957b7dc1525 Co-authored-by: HiGarfield <32226909+HiGarfield@users.noreply.github.com> --- mt76x2/pci_mcu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mt76x2/pci_mcu.c b/mt76x2/pci_mcu.c index 1d517191..e6abb335 100644 --- a/mt76x2/pci_mcu.c +++ b/mt76x2/pci_mcu.c @@ -99,8 +99,8 @@ mt76pci_load_firmware(struct mt76x02_dev *dev) ilm_len = le32_to_cpu(hdr->ilm_len); dlm_len = le32_to_cpu(hdr->dlm_len); - if ((ilm_len | dlm_len) & 3 || - ilm_len > INT_MAX || dlm_len > INT_MAX || + if (ilm_len > INT_MAX || dlm_len > INT_MAX || + (ilm_len | dlm_len) & 3 || ilm_len > fw->size - sizeof(*hdr) || dlm_len != fw->size - sizeof(*hdr) - ilm_len) goto error;