⬢ DragonFlyBSD Kernel Audit
DF-5582 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-5582",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "panic",
  "confidence": "certain",
  "verdict": "smbus_acpi_detach() (sys/bus/smbus/smbacpi/smbacpi.c:268-276) removes the GSBUS address-space handler without quiescing in-flight smbus_acpi_space_handler() dispatches, which ACPICA runs with the interpreter exited and the handler-object ContextMutex held. AcpiRemoveAddressSpaceHandler frees the HandlerObj and that ContextMutex under the running dispatch, and newbus then frees the softc (the handler Context) and the parent ig4iic device. Reproduced 3/3 stock boots with a rig driving the real production path (fake ACPI-ivared ig4iic parent + AcpiLoadTable SSDT + AcpiEvaluateObject): two AcpiOsSignalSemaphore indefinite-wait panics (freed ContextMutex release, trace through AcpiEvAddressSpaceDispatch/AcpiExReadSerialBus) and one chunk_mark_free slab assertion (heap metadata corruption from the write through the freed semaphore). Root-gated trigger (ig4/smbacpi teardown racing concurrent AML), so Low severity, memcorrupt family \u2014 same defect class as verified DF-5518 (gpio_acpi) and DF-5521/DF-5563 (iic). fix.diff (busy/detaching drain before handler removal) validated with an in-kernel ordering witness: stock parked_at_detach=1 + panic; fixed kernel parked_at_detach=0, drain held, guest alive, identical schedule.",
  "exploit_chain": "",
  "evidence": "panic.txt (slab-corruption panic: chunk_mark_free assertion, kern_slaballoc.c:1675); panic.spin.txt (spin panic: panic: spin_lock_ex: AcpiOsSignalSemaphore, indefinite wait! with the AcpiExReadSerialBus->AcpiEvAddressSpaceDispatch->AcpiOsSignalSemaphore trace); run.race.stock.log (-- detached=2 parked_at_detach=1); run.race.fixed.log (-- detached=2 parked_at_detach=0 + STILL ALIVE); run.control.log (real-handler dispatch proof: TRANS slave=0x10 cmd=0 op=0xc rcount=16); VERDICT.md (full trace + negative results); fix.diff (drain patch)",
  "kernel_refs": [
    "sys/bus/smbus/smbacpi/smbacpi.c:268-276",
    "sys/bus/smbus/smbacpi/smbacpi.c:120-141",
    "sys/bus/smbus/smbacpi/smbacpi.c:89-103",
    "sys/contrib/dev/acpica/source/components/events/evregion.c:399-447",
    "sys/contrib/dev/acpica/source/components/events/evxfregn.c:290-408",
    "sys/contrib/dev/acpica/source/components/events/evhandler.c:680-695",
    "sys/dev/acpica/Osd/OsdSynch.c:80-121",
    "sys/bus/smbus/ichiic/ig4_iic.c:607"
  ],
  "poc_changes": "Replaced the pass-1-style sketch entirely: rig kld instantiates the REAL smbacpi under a fake ig4iic device whose bus_read_ivar answers ACPI_IVAR_HANDLE (what ig4_acpi provides on hardware), loads a crafted SSDT via AcpiLoadTable (GSBUS opregion + I2cSerialBus Connection + AttribBytes(16)/AttribBlock fields + TST0/TST1), evaluates TST0 from a kthread, parks the fake SMBUS_TRANS mid-dispatch, and tears the device down via /dev/df5582 ioctl (sysctl-triggered teardown deadlocks on DFs per-CPU sysctl locks \u2014 rig artifact). In-kernel parked_at_detach witness added because DF console prints reorder across CPUs. Fix validation required a kernel rebuild (guest X86_64_GENERIC has device smbacpi compiled in; a module-only install silently changed nothing \u2014 caught by the witness).",
  "attempts": 3,
  "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 (stock) / #1: Thu Oct  8 02:57:28 UTC 2026 (fixed)",
  "runtime_sec": 8100,
  "guest_dirty": 0,
  "build_cmd": "sh build.sh  # guest: iasl df5582.dsl; od/awk aml->header; make -f Makefile.rig; cc trigger.c",
  "run_cmd": "sh run.sh control; sh run.sh race  # stock: panic; fixed: STILL ALIVE",
  "code_hash": "1c69b678a2a9bba787f61b26b89546dd03b98d1bea8980404dd70b8703bf6942",
  "notes": "Known findings DF-1112/DF-2332 (buf[32] GSBUS BLOCK/BYTES stack overflow) NOT re-reported; run.sh bonus scenario can re-demonstrate them live via TST1. Negative results with path:line in VERDICT.md: destination writes bounded by ACPICA per-protocol buffers (exfield.c:170-188, exserial.c:320-355); ig4 caps BLOCK read count at 32 (ig4_iic.c:474-475); unsupported attributes rejected; no WORD swap bug; ContextMutex kills the shared-info race; iiconf ownership classes (DF-5563/5564) not applicable (single-shot SMBUS_* calls, ig4-internal serializer). The smbacpi.ko/module-auto-unload and sysctl-xlock wedges encountered while building the rig are guest/rig artifacts, documented in VERDICT.md.",
  "recommended_fix": "Drain in-flight GSBUS dispatches in smbus_acpi_detach before removing the handler: busy/detaching accounting in struct acpi_i2c_handler_data, handler refuses new dispatches once detaching, detach waits for busy==0 then calls AcpiRemoveAddressSpaceHandler (fix.diff).",
  "fix_status": "fixed",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "Baseline (stock kernel): parked_at_detach=1 and panic in 3/3 boots (AcpiOsSignalSemaphore indefinite-wait x2, chunk_mark_free slab assertion x1). Patched (fix.diff applied to guest /usr/src, kernel rebuilt as #1 Oct 8 02:57:28 UTC 2026, rebooted): identical rig schedule, parked_at_detach=0 \u2014 smbus_acpi_detach waited for the parked dispatch to complete before removing the handler \u2014 no panic, guest alive, eval returned AE_OK.",
  "fix_evidence": "run.race.stock.log vs run.race.fixed.log (parked_at_detach 1 -> 0); panic.txt + panic.spin.txt (baseline panics); fix.diff; VERDICT.md Fixed kernel section"
}