{
  "finding_id": "DF-5768",
  "status": "reproduced",
  "reproduced": true,
  "impact": "panic",
  "confidence": "certain",
  "verdict": "Card-derived ivar->erase_sector == 0 (mmc.c:1476-1477 SD / 1595-1596 MMC: erase_sector * write_bl_len / 512 truncates to 0 for a CSD with WRITE_BL_LEN bits=0) reaches production mmcsd_delete() (mmcsd.c:407-411) via MMC_IVAR_ERASE_SECTOR; the first BIO_FREEBLKS (kernel TRIM path, devfs_spec_freeblks devfs_vnops.c:2028-2049) executes `start % erase_sector` == %0 and panics the kernel. Reproduced deterministically (2/2 runs) end-to-end on the stock INVARIANTS kernel with a KLD harness that compiles the production mmc.c in and drives it with a synthetic malicious MMC card (fake mmcbr bridge); the builtin production mmcsd attached /dev/mmcsd0 and the panic fired inside it: Fatal trap 18: integer divide fault, Stopped at mmcsd_task+0x6cb: idivl %ecx,%eax. Fix validated on a rebuilt kernel: MAX(...,1) clamp at both derivation sites -> erase_sector=1, TRIM completes, clean kldunload, guest stays up. DoS only: the idiv traps before any memory misuse; no escalation path.",
  "exploit_chain": "malicious SD/MMC card -> CSD WRITE_BL_LEN=0 bits -> ivar->erase_sector=0 at discovery -> mmcsd0 attaches -> first BIO_FREEBLKS (TRIM via VOP_FREEBLKS/devfs_spec_freeblks or root-issued freeblks) -> mmcsd_delete modulo by zero -> Fatal trap 18 integer divide fault -> kernel panic / system down. (No memory-corruption primitive: trap fires before any misuse; impact ceiling is denial of service.)",
  "evidence": "panic.txt (full trap record incl. DF-5768: csd.erase_sector=1 csd.write_bl_len=1 -> ivar->erase_sector=0 then Fatal trap 18 and idivl %ecx,%eax in mmcsd_task+0x6cb); run.log (2 baseline runs); fix.log (patched kernel: erase_sector=1, biowait returns, kldunload rc=0); VERDICT.md; dfh_harness.c; build.log",
  "kernel_refs": [
    "sys/bus/mmc/mmc.c:1476",
    "sys/bus/mmc/mmc.c:1595",
    "sys/bus/mmc/mmc.c:1142",
    "sys/bus/mmc/mmc.c:1147",
    "sys/bus/mmc/mmc.c:1538",
    "sys/bus/mmc/mmc.c:1669",
    "sys/bus/mmc/mmc.c:1949",
    "sys/dev/disk/mmcsd/mmcsd.c:407",
    "sys/dev/disk/mmcsd/mmcsd.c:408",
    "sys/dev/disk/mmcsd/mmcsd.c:409",
    "sys/dev/disk/mmcsd/mmcsd.c:411",
    "sys/vfs/devfs/devfs_vnops.c:2028",
    "sys/kern/subr_disk.c:701"
  ],
  "poc_changes": "The findings PoC sketch (direct syscall/ioctl trigger) was not viable: DragonFly has no DIOCGDELETE userland ioctl for this path. Replaced with the family-standard KLD harness: production sys/bus/mmc/mmc.c compiled verbatim into the module (SYSCTL/DRIVER_MODULE neutered with macro save/restore), registered on a synthetic mmcbr bridge implementing a JEDEC-conformant fake card (state machine: CMD2 stops answering after RCA assignment so production discovery terminates; SD probe fails -> mode_mmc; CSD with WRITE_BL_LEN bits=0, spec_vers=5, EXT_CSD SEC_CNT=4096/ERASE_GRP_SIZE=0). The trigger mirrors devfs_spec_freeblks() line-for-line (getpbuf + BUF_CMD_FREEBLKS + dev_dstrategy on the mmcsd0 cdev). Also fixed: module-init ordering (dfhbr devclass must exist before device_add_child -> deferred to a kthread), -Werror macro redefinitions, duplicate case labels (CMD3/SD_CMD3), and R1 status construction.",
  "attempts": 4,
  "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Thu Jul  2 06:02:54 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64",
  "runtime_sec": 1560,
  "guest_dirty": 0,
  "build_cmd": "cd /tmp/df5768 && SYSDIR=/usr/src/sys make",
  "run_cmd": "kldload /tmp/df5768/df5768.ko   # expect: Fatal trap 18 integer divide fault, guest down",
  "code_hash": "de7a085076ecf9b02e206e81fd702ebda7a9a6a5eb79d1829468c35fdd91b054",
  "notes": "Baseline panicked identically on 2 runs. Fix kernel #1: Sun Oct 11 18:02:40 UTC 2026 (nativekernel X86_64_GENERIC, both DF-5768+DF-5769 hunks applied to the guest /usr/src copy only; sys/ tree untouched on the host). Guest reset to the clean with-src snapshot after the runs. SD path equally affected (mmc.c:1476-1477); PoC exercised the MMC path. Card must also keep EXT_CSD[224]=0 / au_size=0 for the zero to survive the overrides - trivial for the card attacker. Raw mmcsd nodes are root:operator 0640 (subr_disk.c:701); the realistic trigger is filesystem-level TRIM on the mounted malicious card.",
  "recommended_fix": "Clamp the card-derived erase sector at both CSD-derivation sites: ivar->erase_sector = MAX(ivar->csd.erase_sector * ivar->csd.write_bl_len / MMC_SECTOR_SIZE, 1); (SD mmc.c:1476-1477 and MMC mmc.c:1595-1596) - see fix.diff, validated end-to-end.",
  "fix_status": "fixed",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "Patched kernel (kernel #1 Sun Oct 11 18:02:40 UTC 2026, guest /usr/src only) with MAX(...,1) at mmc.c:1478/1597: identical PoC prints ivar->erase_sector=1, the FREEBLKS bio completes through the normal production erase path, divide-by-zero did NOT occur, kldunload rc=0, guest stays up. Baseline panic eliminated.",
  "fix_evidence": "fix.log (full patched-run console output incl. erase_sector=1, biowait return, clean kldunload); fix.diff (git apply --check clean against sys/)"
}