# DF-4620 — ar5413 zero-gain path: uint32 index underflows → **+8.6 GB wild reads** + uninitialized stack read

## What
When the EEPROM provides no pd-gain data for the calibration channel
(`xpd_mask == 0` → `ar2413SetupRawDataset` sets every `numVpd = 0`,
ah_eeprom_v3.c:656-673), `ar5413getGainBoundariesAndPdadcsForPowers()` runs
with `numPdGainsUsed == 0` and:

- **ar5413.c:528** `pPdGainBoundaries[ii] = pPdGainBoundaries[ii-1];` with
  `ii == 0`. `ii` is **uint32_t** → `ii-1` = 0xFFFFFFFF → the array subscript
  reads at `gainBoundaries + 0x1FFFFFFFE` bytes (**+8.59 GB**) — *not* a
  2-byte under-read. The value then fills `gainBoundaries[0..3]` and is
  programmed into `AR_PHY_TPCRG5` by `ar5413SetPowerTable` (ar5413.c:639-644).
- **ar5413.c:532** `pPDADCValues[kk] = pPDADCValues[kk-1];` with `kk == 0`
  (same uint32 wrap from the `pcdacTable` base) — the wild value is replicated
  across the whole 128-entry pdadc table and written to 32 PHY registers
  (ar5413.c:630-637).
- **ar5413.c:468** `*pMinCalPower = Pmin_t2[0];` reads uninitialized stack
  (`Pmin_t2[]` is only written inside the `numVpd > 0` branch, :435-445);
  the garbage propagates into `ah_txPowerIndexOffset` (:623-626).

The `HALASSERT(1 <= numPdGainsUsed && ...)` at :580 is compiled out in release
builds (`AH_ASSERT` undefined; HALASSERT is a no-op, ah_internal.h:665-676;
option exists at sys/conf/options:549 but is not in GENERIC), so nothing stops
this path.

In the kernel the +8.6 GB reads land in the direct map: either mapped RAM
(garbage value survives and is programmed to hardware) or a KVA hole
(**kernel panic**).

## Reproduce
```
cd findings/poc/DF-4620
./build.sh && ./ar5413_harness 2    # maps the exact wild pages (kernel-survival emulation)
./ar5413_harness 2                  # again: uninit minPower differs run to run
```
Expected decisive lines (run.log):
```
gainBoundaries[0] = 0x5a5a (wild read at gb+0x1FFFFFFFE, ar5413.c:528 ...)
pcdacTable[0] = 0x5a5a (wild read at pcdacTable+0x1FFFFFFFE, ar5413.c:532 ...)
minPower out = 0xd320 (uninitialized Pmin_t2[0] stack read at ar5413.c:468 ...)
DF-4620 REPRODUCED: uint32-underflow wild reads at ar5413.c:528/:532 + uninit stack read at :468
```
(An earlier unmapped variant faulted at exactly `gb + 0x1FFFFFFFE`
(si_addr 0xa004902c2 == 0x8004902c4 + 0x1FFFFFFFE) — same primitive,
fault flavor.)

## Fix validation
`fix.diff` returns early when `numPdGainsUsed == 0` (and makes
`ar5413SetPowerTable` fail). Patched run: `gainBoundaries[0]=0x0000`,
`pcdacTable[0]=0xaaaa` (untouched), `minPower=0x7c7c` (sentinel intact — the
uninit read never happens). See fix_run.log.

## Threat model
Crafted EEPROM (xpd_mask = 0) on AR5413 hardware → wild KVA reads and/or
panic on every channel set. No unprivileged-host path.
