⬢ DragonFlyBSD Kernel Audit
DF-5769 / fix.diff
← back to finding ↓ download raw
fix.diff for DF-5769 — bound the card-enumeration loop.

Root cause: mmc_discover_cards() (sys/bus/mmc/mmc.c:1413) iterates
`while (1)` and its ONLY exit conditions are CMD2 (ALL_SEND_CID) failures
(mmc.c:1417-1422) or one of the per-card error breaks.  Per JEDEC, a real
card stops answering CMD2 once it owns an RCA, so termination is delegated
entirely to the card.  A card that keeps answering CMD2:

  - with a mutating CID: allocates one mmc_ivars (~0.7 kB) + one bus
    child per iteration, forever (unbounded kernel-memory consumption);
  - with a static CID: re-enumerates the same card forever (ivar->rca =
    rca++ each pass), still never terminating.
--- a/sys/bus/mmc/mmc.c	2026-10-11 17:59:34.066180923 +0000
+++ b/sys/bus/mmc/mmc.c	2026-10-11 17:59:34.086180663 +0000
@@ -1404,13 +1404,15 @@
 	device_t *devlist;
 	device_t child;
 	int devcount, err, host_caps, i, newcard;
+	int iter;
 	uint32_t resp, sec_count, status;
 	uint16_t rca = 2;
 
 	host_caps = mmcbr_get_caps(sc->dev);
+	iter = 0;
 	if (bootverbose || mmc_debug)
 		device_printf(sc->dev, "Probing cards\n");
-	while (1) {
+	while (iter++ < 32) {
 		sc->squelched++; /* Errors are expected, squelch reporting. */
 		err = mmc_all_send_cid(sc, raw_cid);
 		sc->squelched--;