# DF-4930 VERDICT — atphy no-media attach → panic("ifmedia_set")

**Status: NOT REPRODUCED end-to-end (hardware absent on guest); kernel-side sink PROVEN to panic on this exact kernel; fix mechanism validated.**

## Root cause (source trace)

- `atphy_attach` (sys/dev/netif/mii_layer/atphy.c:135-144): if the PHY's
  BMSR reports no 10/100 media bits and EXTSR no gigabit bits, the driver
  prints "no media present" and **skips `mii_phy_add_media`** — the only
  routine that would have installed the IFM_NONE fallback entry
  (mii_physubr.c mii_phy_add_media: `if ((sc->mii_flags & MIIF_NOISOLATE)
  == 0) ADD(IFM_ETHER|IFM_NONE, ...)`).
- atphy.c:149 still calls `MIIBUS_MEDIAINIT(sc->mii_dev)` →
  `miibus_mediainit` (sys/dev/netif/mii_layer/mii.c:229-246), which walks
  the (now EMPTY) ifm_list, leaves `media = 0`, and calls
  `ifmedia_set(&mii->mii_media, 0)`.
- DragonFly's `ifmedia_set` (sys/net/if_media.c) has NO no-match fallback:
  `ifmedia_match` returns NULL on the empty list → `kprintf("ifmedia_set:
  no match ...")` → **`panic("ifmedia_set")`**. (FreeBSD's version prints
  and returns; the panic is a DragonFly-specific divergence.)
- Neither parent driver (age, ale) implements a `miibus_mediainit` hook
  that could add fallback media (grep: no MEDIAINIT in if_age.c/if_ale.c).
- Secondary effect of the same branch: had the boot survived,
  `atphy_service` dereferences `mii->mii_media.ifm_cur` (atphy.c:156→164,
  224) which would be NULL; the attach-time panic preempts this.

Precondition: an Attansic/Atheros F1/F1_7/F2 PHY whose ID registers match
(so atphy attaches) but whose BMSR/EXTSR report zero media capability — a
broken/partially-fried PHY or flaky MDIO. Not attacker-craftable in
software; it is a hardware-fault boot/attach-time panic (auto-attach at
boot or kldload). Same family and severity class as DF-1973 (mlphy
KKASSERT) and DF-4923 (tlphy NULL-deref), and the "no media present"
branch exists in ~20 sibling PHY drivers — the fix belongs in each
driver's attach (this pack fixes atphy; siblings should get the same
one-liner).

## Verification on the guest

No Attansic PHY hardware exists under QEMU and PHY register behavior cannot
be emulated, so the atphy path itself could not be exercised (honest
not_reproduced). The kernel-side sink WAS executed with the real kernel
functions via the `uafsink` KLD (run.sh → `sysctl hw.uafsink_fire=1`):

    ifmedia_set: no match for 0x0/0xffffffff
    panic: ifmedia_set
    ifmedia_set() at ifmedia_set+0x53
    uafsink_fire() at uafsink_fire+0x8e ...

Guest down (see panic.txt). This is byte-for-byte the terminal behavior the
atphy chain would produce.

## Fix

`fix.diff` (atphy.c): call `mii_phy_add_media(sc)` unconditionally after
the "no media present" print (restores the FreeBSD parent behavior; with
zero capabilities it adds exactly the IFM_NONE fallback entry).
Mechanism validated on the guest with the real kernel functions
(`sysctl hw.uafsink_fixcheck=1`): with the fallback entry present,
`ifmedia_set(IFM_ETHER|IFM_NONE)` finds its match, does not panic, and
leaves `ifm_cur` non-NULL (protecting atphy_service). The atphy.c edit
itself was not exercised end-to-end (no PHY hardware) — fix_status
not_testable with the mechanism demonstrated.

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