⬢ DragonFlyBSD Kernel Audit
DF-5617 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-5617",
  "status": "reproduced",
  "reproduced": true,
  "impact": "panic",
  "confidence": "certain",
  "verdict": "ig4_acpi.cs attach-error unwinder re-enters the serializer leaked by ig4_iic.cs bus_setup_intr error path: ig4_acpi.c:127 sets pci_attached=1 before ig4iic_attach (ig4_acpi.c:132); when ig4iic_attach fails at bus_setup_intr it returns with sc->slz held (ig4_iic.c:648-655, no lwkt_serialize_exit on the error branch), and ig4_acpi.c:134 -> ig4_acpi.c:146-147 calls ig4iic_detach whose first lwkt_serialize_enter (ig4_iic.c:678) re-enters the self-held non-recursive serializer -> KKASSERT panic (INVARIANTS) / hard deadlock otherwise. Verified live: the real ig4_acpi.c path (probe/HID INT33C2 match, _CRS translation, MMIO alloc into a planted SSDT-backed register file, ig4iic_attach running to bus_setup_intr) was driven end-to-end with a planted ACPI device; the one non-natural input (bus_setup_intr failure - on real hardware any rman_activate/register_int failure, nexus.c:519-532) was injected with the proven DF-5601 pseudo-bus pattern, after which the production ig4iic_attach/ig4iic_detach panicked the guest exactly as the source predicts: panic: assertion !IS_SERIALIZED failed in lwkt_serialize_enter with backtrace ig4iic_detach <- attach unwinder. fix.diff (one-line lwkt_serialize_exit on ig4_iic.c:651-655 error path, same root fix as DF-5601) A/B validated: patched ig4.ko runs the identical scenario cleanly, guest stays up.",
  "exploit_chain": "",
  "evidence": "run.log/panic.txt: DF5617: serializer is HELD ... IS_SERIALIZED: 1 then panic: assertion \"!IS_SERIALIZED((s))\" failed in lwkt_serialize_enter at lwkt_serialize.c:107 with ig4iic_detach() at ig4iic_detach+0x1f backtrace; run-fixed.log: serializer is released ... IS_SERIALIZED: 0 + ig4iic_acpi_detach replay = 0 -- returned cleanly, NO PANIC (fix effective) with guest up; real-path proof: dance logs + run.log ig4iic0 attach lines (probe match, iomem 0xbffe1cdc irq N on acpi0, comp_version 3131352a, [attached!])",
  "kernel_refs": [
    "sys/bus/smbus/ichiic/ig4_acpi.c:127",
    "sys/bus/smbus/ichiic/ig4_acpi.c:132",
    "sys/bus/smbus/ichiic/ig4_acpi.c:134",
    "sys/bus/smbus/ichiic/ig4_acpi.c:146",
    "sys/bus/smbus/ichiic/ig4_acpi.c:147",
    "sys/bus/smbus/ichiic/ig4_iic.c:648",
    "sys/bus/smbus/ichiic/ig4_iic.c:655",
    "sys/bus/smbus/ichiic/ig4_iic.c:678",
    "sys/kern/lwkt_serialize.c:107",
    "sys/sys/serialize.h:41",
    "sys/platform/pc64/x86_64/nexus.c:519"
  ],
  "poc_changes": "The seed sketch was rewritten: (1) planted-ACPI rig with the register file embedded in the SSDTs own AML pad (SMAP-RAM windows are rman-refused; the fw_cfg table area is not); window >= 0x810 because ig4_iic.c:504-508 reads GENERAL at +0x808 (a 0x200 window page-faults); (2) host-side ENABLE_STATUS latch dance (gpa2hva + /proc/qemu/mem, pre-resolved hva) because DWs 0x6C->0x9C latch cannot exist in RAM; (3) no reachable GSI deterministically fails bus_setup_intr on QEMU (acpi_resource.c:599 drops GSIs above the legacy map; IOAPIC auto-router picks handler-free slots), so the failure is injected via the proven DF-5601 pseudo-bus (df56.c) while ig4_acpi.cs prologue (ig4_acpi.c:104-127) and unwinder semantics (ig4_acpi.c:141-169) are replayed line-for-line around the REAL production ig4iic_attach()/ig4iic_detach().",
  "attempts": 9,
  "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #0: Thu Jul  2 06:02:54 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64 (X86_64_GENERIC, options INVARIANTS config:56)",
  "runtime_sec": 5400,
  "guest_dirty": 0,
  "build_cmd": "findings/poc/DF-5617/build_kld.sh (guest: make in /root/df5617work{,/f2}; fixed ig4.ko: cd /usr/src/sys/bus/smbus/ichiic && patch < fix.diff && SYSDIR=/usr/src/sys make KERNBUILDDIR=/usr/obj/usr/src/sys/X86_64_GENERIC)",
  "run_cmd": "vm.sh run_root kldload ig4 && kldload /root/df5617work/df56.ko && kldload /root/df5617work/f2/df5617.ko  (see run.sh)",
  "code_hash": "fde6582d49e88a3d19f26b258adc34477c241c7ee12005a29c039b13942b1812",
  "notes": "ACPI sibling of DF-5601 (ig4_pci.c) sharing the DF-1049 root; file-specific defect is ig4_acpi.c:127/132-134s unwinder ordering. Real-hw trigger: any one-time IRQ-setup failure on an ACPI-enumerated ig4 (exclusive-owner GSI conflict etc.). Boot/kldload-time availability bug, not unprivileged-triggerable -> Low. Supplementary live observation in the pack: ig4_iic.c:504-508s unconditional GENERAL(0x808) read page-faults the kernel when the ACPI _CRS window is smaller than 0x80C (crafted-firmware DoS, generic _CRS-trust class, root cause in ig4_iic.c).",
  "recommended_fix": "Add lwkt_serialize_exit(&sc->slz) on ig4_iic.cs bus_setup_intr error path (ig4_iic.c:651-655) - one line, fixes both the PCI (DF-5601) and ACPI (DF-5617) unwinders at the root.",
  "fix_status": "fixed",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "fixed",
  "fix_evidence": "Baseline (run.log/panic.txt): panic assertion !IS_SERIALIZED in lwkt_serialize_enter, backtrace ig4iic_detach <- df5617_attach <- device_doattach, guest down in DDB. Patched (run-fixed.log, same kernel config, fix.diff applied to /usr/src ig4_iic.c, ig4.ko rebuilt in guest - fix_build.log): DF5617: serializer is released ... IS_SERIALIZED: 0, ig4iic_acpi_detach replay = 0 -- returned cleanly, NO PANIC (fix effective), vm.sh status = up."
}