⬢ DragonFlyBSD Kernel Audit
DF-5597 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-5597",
  "status": "reproduced",
  "reproduced": true,
  "impact": "none",
  "confidence": "certain",
  "verdict": "genassym.c:276-277 publishes both halves of the ioapic_irqs[] stride contract (IOAPIC_IRQI_SIZE=sizeof and IOAPIC_IRQI_SZSHIFT=hand constant from ioapic_abi.h:58) but nothing at build time relates them; the invariant is enforced only by a comment (ioapic_abi.h:50-51). Demonstrated on the guest: today sizeof==16==1<<4 (drift_now.log, matching the shipped kernels assym.s), while a one-field drift (drift_sim.log, 24 vs 16) makes the two assembly consumers index ioapic_irqs[] differently (ioapic_ipl.s:80,97 vs apic_vector.s:55-59) with the kernel still building cleanly -- a silent interrupt-routing corruption mode. The proposed _Static_assert (fix.diff) compiles clean on the current layout and fails the build on the drifted layout (guard_drift.log), converting the drift to a loud build break. Impact today: none (invariant holds); filed as verified hardening.",
  "exploit_chain": "",
  "evidence": "drift_now.log (16==16 holds, matches shipped assym.s IOAPIC_IRQI_SIZE 0x10 / SZSHIFT 0x4); drift_sim.log (24 vs 16, consumer divergence, no build error today); guard_ok.log (rc=0 current layout); guard_drift.log (static assertion failed: stride drifted)",
  "kernel_refs": [
    "sys/platform/pc64/x86_64/genassym.c:273-278",
    "sys/platform/pc64/apic/ioapic_abi.h:50-58",
    "sys/platform/pc64/apic/ioapic_ipl.s:80",
    "sys/platform/pc64/apic/ioapic_ipl.s:97",
    "sys/platform/pc64/apic/apic_vector.s:55-59"
  ],
  "poc_changes": "authored from scratch: ioapic_drift.c (verbatim struct copy + DRIFT variant), guard_ok.c/guard_drift.c (proposed _Static_assert against current/drifted layout)",
  "attempts": 1,
  "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": 120,
  "guest_dirty": 0,
  "build_cmd": "cc -o ioapic_drift_now ioapic_drift.c && cc -DDRIFT -o ioapic_drift_sim ioapic_drift.c && cc -c guard_ok.c && cc -c guard_drift.c",
  "run_cmd": "sh run.sh",
  "code_hash": "8540c70d30b23062f6f792c42f57c12b4e5aa42f6c3b7d1a4baa3e7280414d6b",
  "notes": "Info/hardening severity: no runtime defect exists today. Filed against genassym.c because it is the publisher of both contract halves (checklist d: sizes emitted vs consumer assumptions).",
  "recommended_fix": "Add _Static_assert(sizeof(struct ioapic_irqinfo) == 1u << IOAPIC_IRQI_SZSHIFT, ...) under the SZSHIFT define in ioapic_abi.h (fix.diff).",
  "fix_status": "fixed",
  "fix_baseline_reproduced": true,
  "fix_patched_reproduced": true,
  "fix_verdict": "Baseline: drifted layout compiles with zero diagnostics (invariant unenforced). Patched guard: current layout compiles clean, drifted layout fails with static assertion failed: ioapic_irqinfo size drifted from IOAPIC_IRQI_SZSHIFT.",
  "fix_evidence": "guard_ok.log, guard_drift.log, drift_now.log, drift_sim.log"
}