# DF-5001 VERDICT — REPRODUCED (panic, replay of the hub statements)

**Bottom line:** `miibus_mediainit()` (mii.c:227-245) unconditionally ends
in `ifmedia_set(&mii->mii_media, media)` (mii.c:244). On an empty media
list `media` is still 0 (mii.c:232) and DragonFly's `ifmedia_set()`
executes `panic("ifmedia_set")` (sys/net/if_media.c:166-174, panic at :174)
— taking the whole system down at NIC attach time. The walk was executed
verbatim on the running guest kernel (KLD replay via sysctl) and panicked
exactly as predicted, killing the guest; the fixed walk (fix.diff) survives
the identical scenario and leaves `ifm_cur` non-NULL.

## How it was reproduced

`miihub.c` contains a verbatim copy of the hub walk (mii.c:238-244)
operating on a real `struct ifmedia` initialized with `ifmedia_init()` —
the exact state of `mii->mii_media` after `miibus_attach()` (mii.c:180-181)
when every probed PHY has taken its "no media present" branch (family:
atphy.c DF-4930, ciphy.c DF-4957, jmphy.c DF-4981, truephy.c DF-5003, plus
the `ukphy_attach`-shaped siblings — ukphy.c:166-170, amphy, brgphy, ...)
and the parent NIC's MIIBUS_MEDIAINIT method added nothing (mii.c:235).

1. `sh build.sh` — builds `miihub.ko` on the guest with the kernel's full
   `-Werror` warning set (build.log). Needed `SRCS+= device_if.h bus_if.h`
   (the generated-interface headers are absent from the guest's /sys after
   `vm.sh reset with-src`; DF-4930's run had them pre-generated).
2. `sh run.sh` → `sysctl hw.miihub_fire=1` — **panic**:
   `ifmedia_set: no match for 0x0/0xfffffff` → `panic: ifmedia_set`,
   trace `ifmedia_set() <- miihub_fire() <- sysctl_root <- userland_sysctl
   <- sys___sysctl`, guest down (panic.txt, full serial-console capture;
   vm.sh status = down immediately after).
3. `vm.sh reset with-src`; `sh run_fix.sh` → `sysctl hw.miihub_fixcheck=1`
   — the FIXED walk (fix.diff shape: empty list →
   `ifmedia_add(IFM_ETHER|IFM_AUTO)` → `ifmedia_set`) **survives**:
   `miihub-fix: survived; ifm_cur=0xfffff8008d481d60 media=0x20` and
   `ifm_cur->ifm_media=0x20` — 0x20 = IFM_ETHER|IFM_AUTO — proving the
   `ife = mii->mii_media.ifm_cur; IFM_INST(ife->ifm_media)` dereference
   every `*_service()` performs on the next tick (e.g. truephy.c:185)
   stays safe (run.2.log).
4. The patched `mii.c` itself (fix.diff applied) compiles clean under
   `-Werror` as a KLD source on the guest (fixcheck-build.log) —
   `LIST_EMPTY`/`ifmedia_add` are already in mii.c's include set.

## Why the end-to-end path is hardware-preconditioned (severity Low)

`mii_probe()` (mii.c:258-282) only creates the miibus when at least one
PHY address passes `miibus_no_phy()` (mii.c:105-116) — which requires a
BMSR with *some* media/EXTSTAT bits — and `ukphy` always attaches
(ukphy.c:126-131). The empty-list state therefore requires a PHY that
PASSES the probe (BMSR_MEDIAMASK|BMSR_EXTSTAT != 0 at mii.c:113-115) but
then reports zero media capabilities when its driver re-reads BMSR/EXTSR
at attach (e.g. truephy.c:163-172). That is faulty or
malicious-hardware-in-the-loop behavior, not an unprivileged userland
input. Consequence: attach/boot-time kernel panic (full DoS of the node),
same class and severity as the family findings (DF-4930/4957/4981, all
Low). No escalation angle exists: the primitive is a deterministic
`panic()` on a failed list match — no memory unsafety, no controllable
write.

## Why the hub fix is the right family fix

- One guard in `miibus_mediainit` covers every current and future PHY
  driver that can add zero media (atphy, ciphy, jmphy, truephy, ukphy
  shape, and the ~20 siblings).
- It is the ONLY fix that covers the `MIIF_NOISOLATE` drivers: the
  `mii_phy_add_media()` IFM_NONE fallback is gated on MIIF_NOISOLATE being
  CLEAR (mii_physubr.c:230-232), but ciphy (ciphy.c:132) and truephy
  (truephy.c:157) always set MIIF_NOISOLATE — for them, "just call
  mii_phy_add_media unconditionally" adds nothing and the panic remains.
  (DF-4957's pack already works around this with an explicit
  `ifmedia_add`; DF-4930's atphy leaf fix works only because atphy does
  not set MIIF_NOISOLATE.)
- Non-empty-but-no-AUTO lists keep the existing behavior (set the last
  entry's media), which always self-matches.

## Fix

`fix.diff` — in `miibus_mediainit()`, after the walk: if no entry was
found and the list is empty, `ifmedia_add(IFM_ETHER|IFM_AUTO)` and set
`media` accordingly, then `ifmedia_set()` as before. The bus then attaches
(degraded, autoselect-only) instead of panicking the system.

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