[PATCH] wifi: mt76: mt7921: validate CLC firmware records
Mikhail Gavrilov
mikhail.v.gavrilov at gmail.com
Sun Aug 16 06:23:25 PDT 2026
This patch is in linux-next as 9417c5818a01, and on current shipping
firmware it stops mt7921e from probing at all.
An unknown clc->idx is treated as fatal:
if (clc_len < sizeof(*clc) || clc_len > len - offset ||
clc->idx >= ARRAY_SIZE(phy->clc)) {
ret = -EINVAL;
goto out;
}
but linux-firmware 20260810 ships an MT7922 image that legitimately
carries records with idx 3. Dumping the CLC region of
WIFI_RAM_CODE_MT7922_1.bin before and after that firmware update:
20260622, region len 366448:
idx=0 ver=1 nr_country=255 type=0 len=179384
idx=0 ver=1 nr_country=255 type=1 len=187064
20260810, region len 475488:
idx=0 ver=1 nr_country=255 type=0 len=179384
idx=0 ver=1 nr_country=255 type=1 len=187054
idx=3 ver=1 nr_country=0 type=0 len=54520
idx=3 ver=1 nr_country=0 type=1 len=54530
So mt7921_load_clc() returns -EINVAL, mt7921_run_firmware() fails, and
the probe retries the firmware ten times before giving up:
mt7921e 0000:0b:00.0: ASIC revision: 79220010
mt7921e 0000:0b:00.0: HW/SW Version: 0x8a108a10, Build Time: 20260724143257a
mt7921e 0000:0b:00.0: WM Firmware Version: ____000000, Build Time: 20260724143402
[ ... nine more identical pairs ... ]
mt7921e 0000:0b:00.0: hardware init failed
No interface is created. There is no dev_err on this path, so the only
clue is the retry loop. Loading mt7921_common with disable_clc=1, which
makes mt7921_load_clc() return before any of this, brings the device up
normally and the firmware is loaded once rather than ten times.
The rest of the patch is a real improvement - bounds-checking the region
table and each record length also closes an infinite loop on a
zero-length record. Only the handling of an unknown index needs to
change: an index the driver does not know about is not a malformed
image, it is a newer firmware, and the record should be skipped:
if (clc_len < sizeof(*clc) || clc_len > len - offset) {
ret = -EINVAL;
goto out;
}
if (clc->idx >= ARRAY_SIZE(phy->clc))
continue;
I sent an overlapping patch yesterday, "wifi: mt76: mt7921: fix
array-index-out-of-bounds in mt7921_load_clc()", before I found this one
in linux-next; I will mark mine superseded, since this patch is the
broader fix. Happy to send the one-line change above as a follow-up
patch and test it here, or leave it to you to fold in before this
reaches mainline.
Separately, it would be useful to know what CLC index 3 actually
contains - roughly 109 KB of payload in two hw_encap variants that the
driver currently discards either way.
More information about the Linux-mediatek
mailing list