# DF-5769 — `mmc_discover_cards()` never terminates / unbounded child+ivar allocation for a card that keeps answering CMD2

**File:** `sys/bus/mmc/mmc.c` (pass 2, GLM 5.3)
**Class:** CWE-400 (uncontrolled resource consumption) + CWE-835 (loop with unreachable exit condition)

## What

`mmc_discover_cards()` (`sys/bus/mmc/mmc.c:1413`) enumerates cards in a
`while (1)` loop whose **only** exits are CMD2 (ALL_SEND_CID) errors
(mmc.c:1415-1422: `err == MMC_ERR_TIMEOUT` / `err != MMC_ERR_NONE`) and
per-card error breaks. Per JEDEC, a *real* card leaves the identification
state (stops answering CMD2) once it owns an RCA — termination is
delegated entirely to the card. A crafted card that keeps answering CMD2:

* **mutating CID** — every pass looks like a new card
  (`mmc.c:1426-1432` CID match loop never hits) → `kmalloc(struct
  mmc_ivars)` (`mmc.c:1440-1441`, ~0.7 kB, M_DEVBUF) plus
  `device_add_child()` (`mmc.c:1704-1707`, unnamed child, no unit
  ceiling) per iteration, **forever**: unbounded kernel-memory
  consumption, no path ever frees them (children are only attached at
  `bus_generic_attach`, `mmc.c:1908`, which is never reached);
* **static CID** — the same card is re-enumerated forever
  (`ivar->rca = rca++` each pass, `mmc.c:1572`, wrapping uint16_t),
  discovery never returns.

Either way: the discovery context (config_intrhook /
`mmc_delayed_attach`) is permanently wedged, the mmc bus is unusable,
`kldunload` is impossible, and with mutating CIDs the kernel leaks
memory without bound until the system degrades/dies. Reachable at boot
or card-insertion/resume by any malicious MMC-mode card (SD probe is
made to fail → `mode_mmc`, `mmc.c:1779-1786`).

## How to reproduce (no SD hardware needed)

Same harness family as DF-5768 (production `mmc.c` compiled into the
KLD, fake `mmcbr` bridge), built with `DFH_MUTATING_CID`: every CMD2 is
answered with success and a fresh CID.

```sh
# guest (root), from a clean boot:
cd /tmp/df5769 && SYSDIR=/usr/src/sys make
sh ./run.sh          # kldloads in background, samples vmstat -m
```

**Expected (stock kernel):** `mmc0` attaches, discovery loops forever in
the `dfh_boot` thread; M_DEVBUF grows monotonically without bound
(measured: 102 K → 89.1 M → 94.1 M over ~8 min, ≈110k allocations,
still climbing; the O(N²) CID-match/device_get_children cost slows but
never stops it); the guest eventually stops accepting ssh sessions; no
crash — a pure wedge/exhaustion DoS. With the fix (fix.diff), discovery
stops after 32 iterations, 32 mmcsd children attach, `kldunload` is
clean and the guest stays healthy.
