# DF-3970 verdict — certain unbounded table walk; default-config-safe, admin-gated trigger

## Reproduced?
No Ralink NIC on the audit guest (env.txt), and the trigger additionally
needs a privileged regdomain install — so not exercised at runtime.
Source-level certainty is complete:

- rt2560.c:2210: `for (i = 0; rt2560_rf5222[i].chan != chan; i++);`
  — no loop bound; `i` is u_int, the walk can run to the end of the
  kernel image if no byte ever equals `chan` (chan≥1 always, so a zero
  byte terminates it — in practice within a few KB, still past the end
  of the 41-entry table).
- rt2560reg.h:449-489: `RT2560_RF5222` table has no {0,…} terminator row.
- Safe-by-accident today: ieee80211_init_channels (ieee80211_regdomain.c:101-108)
  builds exactly {1..14, 36..64 step 4, 100..140 step 4, 149,153,157,161} —
  all present in the table. `ic_curchan` always comes from ic_channels
  (ieee80211_set_channel / setupcurchan), so out-of-the-box the walk always
  terminates in-bounds.
- Reachable channel numbers outside the table: IEEE80211_IOC_REGDOMAIN
  (ieee80211_ioctl.c:2126-2162) copies an admin channel array in and only
  validates freq/flags/maxregpower (ieee80211_regdomain.c:342+); the ral
  driver's ic_setregdomain is null_setregdomain (regdomain.c:59-65) which
  accepts anything, and the table is memcpy'd into ic->ic_channels
  (regdomain.c, "channel table" commit block). ieee=165/34/184… then select
  cleanly via `ifconfig wlan0 channel N`.

Impact ceiling: OOB read over kernel .rodata (no disclosure channel — the
read values go into RF registers, not to userspace) + wrong RF programming
(radio DoS). Admin-only trigger ⇒ Low.

## Fix
fix.diff bounds the walk with `i < nitems(rt2560_rf5222)` and on miss logs
"unknown channel %u for RF5222" and breaks out (BBP path still runs, RF
left untouched — same behavior as the unknown-rf_rev default arm at
rt2560.c:2217-2218). `git apply --check` clean; if_ral.ko rebuilt with
-Werror on the guest (build.log). Runtime validation needs the NIC.

## Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest `make -j6 nativekernel KERNCONF=X86_64_GENERIC` completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
