DF-1023 / poc.c
/* * DF-1023 — Kernel panic on unrecognized SD CSD version * Documentation / trigger harness. * * The bug: mmc_decode_csd_sd() at sys/bus/mmc/mmc.c:1056 reads the 2-bit * csd_structure field (bits 126-127 of the card's CMD9 R2 response — fully * card-controlled) and at mmc.c:1108-1109 panics when v != 0 and v != 1: * * } else * panic("unknown SD CSD version"); * * Reachability (per the audit guest): * - pciconf -l on the audit QEMU/KVM guest shows NO SDHCI/MMC host * controller (only hostb/isab/atapci/virtio_pci/vgapci). * - mmc.ko is shipped as a loadable module but never attaches. * - There is no userspace path to reach mmc_decode_csd_sd() without SD * hardware, so the bug is latent on this guest. * * To trigger the panic for real: * 1. Be on a host with an SDHCI PCI controller (e.g. real hardware or * QEMU's `-device sdhci-pci` + an sd-card image). * 2. Insert an SD-card image whose CSD bits 126-127 == 2 or 3. * 3. Card enumeration (mmc_discover_cards -> mmc_decode_csd_sd at * mmc.c:1471) immediately calls panic("unknown SD CSD version"). * * This harness documents the path and the expected behaviour so a * maintainer can verify the fix without needing real hardware. */ #include <stdio.h> int main(void) { printf("=== DF-1023 trigger documentation ===\n"); printf("\n"); printf("Vulnerable code path:\n"); printf(" mmc_delayed_attach (mmc.c)\n"); printf(" -> mmc_discover_cards\n"); printf(" -> mmc_decode_csd_sd (mmc.c:1056)\n"); printf(" v = mmc_get_bits(raw_csd, 128, 126, 2); // card-controlled\n"); printf(" if (v == 0) { ... } else if (v == 1) { ... }\n"); printf(" else panic(\"unknown SD CSD version\"); // mmc.c:1108-1109\n"); printf("\n"); printf("Trigger precondition: a (potentially malicious) SD card whose CSD\n"); printf(" bits 126-127 == 2 or 3 (csd_structure).\n"); printf("Effect: immediate kernel panic at card enumeration.\n"); printf("\n"); printf("Status on this audit guest (no SDHCI PCI device, mmc.ko does not\n"); printf("attach): NOT REACHABLE. Bug is confirmed by code trace at\n"); printf("sys/bus/mmc/mmc.c:1108-1109 and fixed by replacing the panic() with\n"); printf("kprintf + return (mirroring mmc_app_decode_scr at mmc.c:1158-1163).\n"); return 0; } |