Unbounded linear search in mt7601_set_chan reads past mt7601_rf_chan[14]
Summary
mt7601_set_chan finds per-channel RF settings with for(i=0 mt7601_rf_chan[i].chan!=chan i++) no upper-bound test. mt7601_rf_chan has exactly 14 entries (channels 1-14). If chan anything other than 1-14 loop walks off end of static const array into adjacent .rodata until matches garbage word (programs radio with garbage) or runs into unmapped page panics. Caller mtw_set_chan only rejects chan==0 and chan==IEEE80211_CHAN_ANY(255) permits any chan 1..254. Defense-in-depth failure - driver advertises only 2GHz channels via mtw_get_radiocaps so normally constrained to 1..14. [VERIFIED pass2: reproduced - chan 15 walks off the 14-entry rf table SIGSEGVing verbatim and guard-page variants, crafted row programs RF with garbage at i 14; nitems bound fix-validated, unreachable via normal radiocaps 1-14]
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-2355 Β· 10 files| File | Type | Description | Size | |
|---|---|---|---|---|
| build.log | β | 204 B | view raw | |
| build.sh | β | 91 B | view raw | |
| env.txt | β | 412 B | view raw | |
| fix.diff | β | 547 B | view raw | |
| mtw_rig.c | β | 8.4 KB | view raw | |
| run.log | β | 642 B | view raw | |
| run.sh | β | 125 B | view raw | |
| run_fixed.log | β | 318 B | view raw | |
| verdict.json | β | 2.0 KB | view raw | |
| fix.diff | β | 547 B | view raw |
Fix verification
not_testableConfirmed kernel references
Detail
Evidence (decisive lines)
run.log (guard SIGSEGV 0x800474000; walk-real SIGSEGV 0x403000; sentinel i=14 garbage row; control row 6), run_fixed.log (walk-real child_exit=0), fix.diff
PoC changes
guard/sentinel scenarios use a relocated copy with the verbatim loop shape (deterministic placement); the walk-real scenario calls the untouched verbatim function on the real static table
Verified recommended fix
bound the channel search with nitems() and refuse unsupported channels
Verdict
mt7601_set_chan (if_mtw.c:3692-3734) verbatim rig: chan=15 walks mt7601_rf_chan[14] off the end - the verbatim function on the real table SIGSEGVs (0x403000) in the userspace twin, the relocated-table variant SIGSEGVs at the guard page, and the crafted-15th-row variant shows the other outcome: the walk stops at i=14 and programs the RF registers plus TX power with garbage. chan=6 hits the correct row. With the nitems-bounded loop the verbatim function returns cleanly past the table (unsupported-channel print) and the control is unchanged. Reachability is the defense-in-depth failure the finding states: radiocaps only advertises channels 1-14, so this needs a driver-level caller bug to reach.
No comments yet.