# DF-4956 — ath_hal_v4kEepromAttach error-path leak (eeprom-attach family, 3rd twin)

## What

`ath_hal_v4kEepromAttach()` (sys/dev/netif/ath/ath_hal/ah_eeprom_v4k.c:282-399)
mallocs `HAL_EEPROM_v4k` (1152 bytes, `M_ATH_HAL`, zeroed — ah_osdep.c:121-124)
at :311 and has **three post-malloc error returns that neither free the object
nor install it**:

* :324 `return HAL_EEREAD;` — mid-image EEPROM read failure
* :366 `return HAL_EEBADSUM;` — XOR checksum != 0xffff
* :385 `return HAL_EEBADSUM;` — EEPROM version nibble != AR5416_EEP_VER (14)

The eeprom only becomes reachable at :390-396
(`AH_PRIVATE(ah)->ah_eeprom = ee`, `ah_eepromDetach = v4kEepromDetach`), after
every error return. The caller (ar9285_attach.c:246-248 `goto bad` →
`ah->ah_detach` → ar5416Detach (ar5416/ar5416_attach.c:490-508) →
`ath_hal_eepromDetach` macro (ah_internal.h:474-477)) is a **no-op** when
`ah_eepromDetach` was never installed → the 1152-byte block is permanently
orphaned.

Third and final member of the family: DF-4873 (ar9287, ~1KB), DF-4913 (v14,
4.8KB, verified live), DF-1995 (ar5210 v1). Both prior verdicts predicted this
file carries the same bug.

## Build (on the DragonFly guest, as root, in this directory)

    ./build.sh        # make - builds v4kleak.ko KLD against the running kernel

Requires the kernel source tree at /usr/src and built kernel headers at
/usr/obj/usr/src/sys/X86_64_GENERIC (both present on the audit guest).
`ath_hal_v4kEepromAttach` is compiled into the guest kernel
(`nm /boot/kernel/kernel` → `ffffffff8034f1a0 T ath_hal_v4kEepromAttach`).

## Run (as root)

    ./run.sh

## Expected output

    --- vmstat -m ath_hal BEFORE ---
    (no ath_hal line — 0 in-use blocks)
    ...
                ath_hal     600    675K       0    390M      800      <- after trigger
                ath_hal     600    675K       0    390M      800      <- after kldunload (unchanged: permanent)

Serial console (`vm.sh log`):

    DF-4956 PoC loaded (inert): sizeof(HAL_EEPROM_v4k)=1152 sizeof(ar5416eeprom_4k)=376 NWORDS=188 owl_eep_start_loc=64
    DF-4956[EEREAD@324]:   200 attaches, 0 HAL_OK, 200 with ah_eeprom==NULL (orphaned mallocs)
    DF-4956[EEBADSUM@366]: 200 attaches, 0 HAL_OK, 200 with ah_eeprom==NULL (orphaned mallocs)
    DF-4956[BADVER@385]:   200 attaches, 0 HAL_OK, 200 with ah_eeprom==NULL (orphaned mallocs)
    DF-4956[control]:      200 attaches, 200 HAL_OK, each detached (balanced; expect no ath_hal growth)

Second trigger round stacks: 600 blocks/675K → 1.17K blocks/1.32M (run.2.log).
Success criterion: ≥1 failed attach mode orphans its block permanently
(vmstat ath_hal in-use grows by exactly NFAIL per mode and survives kldunload),
while the valid-image control leaves in-use unchanged.

## Fix

`fix.diff`: `ath_hal_free(ee)` before each of the three error returns —
identical to the DF-4873/DF-4913 family fix.
