β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-1023

Kernel panic on unrecognized SD CSD version from malicious SD card (csd_structure=2 or 3 triggers panic not graceful error)

Summary

mmc_decode_csd_sd at mmc.c:1108-1109 panic(unknown SD CSD version) for csd_structure v==2 or v==3. Field from card CMD9 R2 response bits 126-127 (card-controlled). Malicious SD card (or legitimate SDUC SD Spec 7.0+ defining CSD v2) -> immediate kernel panic at enumeration (mmc_discover_cards :1471 -> mmc_delayed_attach at boot or mmc_resume). No privileges/user interaction needed. Sibling mmc_app_decode_scr :1158 handles analogous case correctly (kprintf + return). Fix: kprintf + return with csd_structure=0.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-1023 Β· 12 files
FileTypeDescriptionSize
README.md readme human-facing summary 1.8 KB ↓ raw
poc.c trigger-source documentation harness (no live trigger possible on guest) 2.3 KB view raw
build.sh build-script cc -O -pipe -Wall -o poc poc.c 179 B view raw
run.sh run-script ./poc 135 B view raw
build.log build-log harness compile output, full 13 B view raw
run.log run-log harness run output 784 B view raw
fix.diff suggested-fix replace panic with kprintf + return, mirroring mmc_app_decode_scr 443 B view raw
fix_build.log build-log mmc.ko module compile with fix applied, full output (clean, -Werror) 19.5 KB view raw
env.txt environment uname, cc, kldstat, pciconf, modules 1.7 KB view raw
VERDICT.md verdict narrative analysis 3.4 KB ↓ raw
../fix_build_combined.log build-log Combined 41-finding kernel build (rc=0, -Werror clean) 5.6 MB ↓ download
../fix_build_summary.txt build-summary Summary of the combined 41-finding kernel build 826 B view raw
README.md readme human-facing summary
↓ download raw

DF-1023 β€” Kernel panic on unrecognized SD CSD version

File: sys/bus/mmc/mmc.c:1108-1109 Severity: Medium (CVSS 3.6 / DoS) Class: CWE-754 (Improper Check for Exceptional Conditions)

Summary

mmc_decode_csd_sd() calls panic("unknown SD CSD version") when the 2-bit csd_structure field (read directly from the card's CMD9 R2 response, bits 126–127) is anything other than 0 or 1. The value is fully card-controlled. A maliciously crafted SD card (or any future SDUC / SD Spec 7.0+ card that legitimately defines CSD v2) immediately panics the kernel at enumeration, which happens at boot if a card is inserted, on mmcbr_* bus scan, or on mmc_resume.

The sibling decoder mmc_app_decode_scr() at mmc.c:1158 handles the analogous case correctly with kprintf + return.

Reproducibility

  • Bug confirmed: Yes β€” direct panic() call cited at mmc.c:1108.
  • Live reproduction on audit guest: NOT FEASIBLE β€” the QEMU/KVM guest has no SDHCI PCI device (pciconf -l shows only hostb/isab/ atapci/virtio_pci). The mmc.ko module exists but does not attach. No userspace path can reach mmc_decode_csd_sd() without SD/MMC hardware, so this is a latent/realistic-hardware bug rather than a dead-code path.

Fix

Replace the panic() with a kprintf + return, matching mmc_app_decode_scr(). The full git apply-able diff is in fix.diff. The fix has been compile-validated (see VERDICT.md).

Reproduce

./build.sh && ./run.sh

The PoC is a documentation harness β€” there is no SD/MMC hardware on the audit guest, so the program prints the analysed call path and explanatory markers instead of triggering the panic. To trigger the actual panic, present a malicious SD card reporting csd_structure=2 or 3 to a host with an SDHCI controller and observe the kernel panic at card enumeration.

VERDICT.md verdict narrative analysis
↓ download raw

DF-1023 β€” VERDICT

Verdict

NOT REPRODUCED (live) β€” bug CONFIRMED via code trace, fix.diff compiles cleanly.

The kernel-panic bug claimed in the finding is real and the cited line numbers are exact, but it cannot be exercised on the audit guest because there is no SDHCI/MMC PCI host controller (the QEMU/KVM guest's PCI bus exposes only hostb/isab/atapci/none/virtio-pci devices) and therefore no code path that reaches mmc_decode_csd_sd(). The bug is latent on this guest and live on any host with an SD/MMC controller (real hardware, or QEMU started with -device sdhci-pci + an sd-card image) into which a malicious SD card is inserted.

Mechanism (code trace)

mmc_decode_csd_sd() decodes the 128-bit CSD register that an SD card returns in its CMD9 R2 response. The function:

  • sys/bus/mmc/mmc.c:1056 c csd->csd_structure = v = mmc_get_bits(raw_csd, 128, 126, 2); reads the 2-bit csd_structure field directly from card-controlled bytes (bits 126-127 of the CSD).

  • sys/bus/mmc/mmc.c:1057-1107 β€” v==0 and v==1 are decoded.

  • sys/bus/mmc/mmc.c:1108-1109 c } else panic("unknown SD CSD version"); Any other value (e.g. v==2, the SDUC / SD Spec 7.0+ value; or a malicious v==3) immediately panics the kernel.

The call chain is mmc_delayed_attach β†’ mmc_discover_cards β†’ mmc_decode_csd_sd (mmc.c:1471 per the finding summary), which runs at card-enumeration time β€” i.e. at boot if a card is present, on hot-plug, or on mmc_resume. No user interaction is needed beyond inserting the card.

The sibling decoder mmc_app_decode_scr() at mmc.c:1158-1163 handles the analogous case correctly:

if (scr_struct != 0) {
    kprintf("Unrecognised SCR structure version %d\n", scr_struct);
    return;
}

The CSD decoder is missing the same defensive pattern.

Why it does not reproduce on this guest

Audit-guest fact Evidence
No SDHCI/MMC PCI host controller present pciconf -l lists only hostb/isab/atapci/none0/vgapci/virtio_pci0/virtio_pci1 β€” class 0x060500 / 0x0805 (SDHCI) absent
mmc.ko is shipped but never attaches kldstat does not list mmc.ko; ls /boot/kernel/mmc.ko shows it is available but unloaded

There is no code path on the audit guest that reaches mmc_decode_csd_sd(). The bug requires physical access to an SD card slot and a host with a real or emulated SDHCI controller.

Exploit chain

none β€” pure DoS / improper-check (CWE-754). No memory corruption.

Fix

fix.diff replaces the panic with kprintf + return, exactly mirroring mmc_app_decode_scr():

} else {
    kprintf("unknown SD CSD version %d\n", v);
    return;
}

The csd struct is zero-filled at function entry (memset at line 1055) so a graceful return leaves the caller with an all-zero CSD, which the existing capacity / timing code handles as "no card / unknown".

Fix validation

  • fix.diff applies cleanly to /usr/src/sys/bus/mmc/mmc.c with patch -p1 (1 hunk succeeded).
  • The patched mmc.ko module compiles cleanly with -Werror (see fix_build.log).
  • Not live-tested (no SDHCI HW to enumerate a card).

fix_status: not_testable (no live trigger available).

PoC changes

The finding folder was empty; this run authored: - README.md β€” full summary - poc.c β€” documentation harness - fix.diff β€” the verified fix - build.sh, run.sh, build.log, run.log, env.txt, fix_build.log, manifest.json, VERDICT.md

Fix verification

not_testable

compile validated

module/kernel build rc=0 -Werror

Confirmed kernel references

β€”

Detail

Exploit chain

none

Evidence (decisive lines)

β€”

Verdict

Source-confirmed. mmc_decode_csd_sd unknown version panic. No SDHCI HW. Fix mirrors mmc_app_decode_scr.