[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