Fix VIF WCID collision, unchecked MCU returns, and firmware validation overflow in mt76x02/mt76x2#12
Conversation
…turns, 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>
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
There was a problem hiding this comment.
Pull request overview
Fixes multiple robustness and correctness issues in the mt76x02/mt76x2 WiFi driver family, covering VIF WCID allocation, MCU error propagation, and firmware image validation.
Changes:
- Prevent VIF WCID collisions by expanding
MT_VIF_WCID()masking and increasingMT_MAX_VIFSto 16. - Propagate previously ignored MCU command failures in
mt76x2_mcu_set_channel()andmt76x2_mcu_init(). - Make USB/PCI firmware length validation overflow-safe by avoiding unchecked additive length computations.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| mt76x2/usb_mcu.c | Hardens USB firmware size validation against integer overflow. |
| mt76x2/pci_mcu.c | Hardens PCI firmware size validation; propagates MCU function-select failure; uses validated segment lengths for copying. |
| mt76x2/mcu.c | Returns early when initial channel-switch MCU message fails. |
| mt76x02_mac.h | Expands VIF WCID mapping and maximum VIF count to cover indices 0–15 uniquely. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| 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) |
There was a problem hiding this comment.
The firmware header length fields are still not validated for 4-byte alignment or for fitting into the int len that mt76_wr_copy() ultimately takes. If dlm_len is not a multiple of 4, mt76_mmio_write_copy() will read up to ALIGN(dlm_len, 4) bytes and can read past the end of the firmware buffer; additionally cur += ilm_len / sizeof(*cur) becomes incorrect when ilm_len is not 4-byte aligned. Please reject firmware where ilm_len/dlm_len are not 4-byte aligned and where either length exceeds INT_MAX (or the bus copy API is updated to take size_t).
| 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; |
There was a problem hiding this comment.
mt76x02u_mcu_fw_send_data() takes an int data_len, but ilm_len/dlm_len are now u32 from an untrusted firmware header. Even with the total-size check, values > INT_MAX will truncate when passed as int, potentially turning into negative/short lengths and causing incorrect behavior. Please add explicit bounds checks that both lengths are <= INT_MAX before calling the upload helper (or change the helper signature to size_t).
|
@copilot apply changes based on the comments in this thread |
…lm_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>
Agent-Logs-Url: https://github.com/HiGarfield/mt76/sessions/9ef155e1-f7ec-4760-afd0-8957b7dc1525 Co-authored-by: HiGarfield <32226909+HiGarfield@users.noreply.github.com>
Applied both review changes in commits
|
|
@copilot apply changes based on the comments in this thread |
These changes are already applied in commits
|
Comprehensive bug audit of mt7603/mt76x02/mt76x2 driver code. Six bugs fixed across four files.
VIF WCID collision (
mt76x02_mac.h)MT_VIF_WCIDused& 7mask, causing station VIFs (idx 8–15) to collide with AP VIFs (idx 0–7):Unchecked MCU return values
mt76x2_mcu_set_channel()— firstmt76_mcu_send_msg()result was silently discarded; failure in the initial channel switch was maskedmt76x2_mcu_init()—mt76x02_mcu_function_select()result was ignoredInteger overflow in firmware size validation (
pci_mcu.c,usb_mcu.c)Both PCI and USB firmware loaders accumulated sizes into
int lenviasizeof(*hdr) + ilm_len + dlm_len, which overflows on 32-bit when fed crafted firmware. Replaced with overflow-safe sequential subtraction againstfw->sizeusingu32types, along withINT_MAXbounds checks (since downstream copy APIs takeint len/int data_len) and 4-byte alignment validation for PCI (sincemt76_mmio_write_copyusesALIGN(len, 4)which can read past the firmware buffer):