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)
PoC verification
Evidence pack
findings/poc/DF-1023 Β· 12 files| File | Type | Description | Size | |
|---|---|---|---|---|
| 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 |
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 atmmc.c:1108. - Live reproduction on audit guest: NOT FEASIBLE β the QEMU/KVM
guest has no SDHCI PCI device (
pciconf -lshows only hostb/isab/ atapci/virtio_pci). Themmc.komodule exists but does not attach. No userspace path can reachmmc_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.
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:1056c csd->csd_structure = v = mmc_get_bits(raw_csd, 128, 126, 2);reads the 2-bitcsd_structurefield directly from card-controlled bytes (bits 126-127 of the CSD). -
sys/bus/mmc/mmc.c:1057-1107βv==0andv==1are decoded. -
sys/bus/mmc/mmc.c:1108-1109c } else panic("unknown SD CSD version");Any other value (e.g.v==2, the SDUC / SD Spec 7.0+ value; or a maliciousv==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.diffapplies cleanly to/usr/src/sys/bus/mmc/mmc.cwithpatch -p1(1 hunk succeeded).- The patched
mmc.komodule compiles cleanly with-Werror(seefix_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_testablecompile 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.
No comments yet.