β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-2355

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)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-2355 Β· 10 files
FileTypeDescriptionSize
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_testable
↓ fix.diffper-fix-DF-2355

Confirmed 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.