⬢ DragonFlyBSD Kernel Audit
DF-4918 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-4918",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "dos",
  "confidence": "certain",
  "verdict": "Deterministic permanent kernel-thread/workqueue deadlock reproduced on the audit guest: drain_workqueue() (linux_workqueue.c:276-281) tsleep()s holding worker_lock, starving the very worker that must drain the queue. Baseline: drain_done=0/filler_done=0 forever, worker blocked in wchan lwq, drainer asleep in wkdrain holding the lock (ps proof in run.log); the wedge also hung a guest shutdown once. Fix (lksleep) validated on rebuilt drm.ko: identical test completes (drain_done=1, filler_done=1), guest healthy. Distinct failure mode and root cause from DF-1977 (premature return / missing in-flight wait).",
  "exploit_chain": "",
  "evidence": "run.log (DEADLOCK CONFIRMED + ps wchan lines: df4918wq blocked in lwq, df4918drain in wkdrain); run_fixed.log (drain_done=1 filler_done=1 on patched drm.ko); fix.diff",
  "kernel_refs": [
    "sys/dev/drm/linux_workqueue.c:276",
    "sys/dev/drm/linux_workqueue.c:279",
    "sys/dev/drm/linux_workqueue.c:91",
    "sys/dev/drm/linux_workqueue.c:134",
    "sys/dev/drm/linux_workqueue.c:220"
  ],
  "poc_changes": "seed was a concept only; module written from scratch: own single-worker workqueue, slow(3s)+filler works, dedicated drain and probe lwkt threads, sysctl hw.df4918_test/hw.df4918_status reporting; module refuses unload after the test (threads wedged)",
  "attempts": 2,
  "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": 600,
  "guest_dirty": 0,
  "build_cmd": "kldload drm; cd /tmp/df4918 && make",
  "run_cmd": "kldload /tmp/df4918/df4918.ko; sysctl hw.df4918_test=1; sysctl hw.df4918_status",
  "code_hash": "b7e714f3996bf8ad4705e4800825cde59791919fd5faaefa00f28d13029106d6",
  "notes": "Two baseline runs identical; one baseline run also wedged the guest shutdown path (ended at db>) - the wedge cascades beyond the wq. Fixed-kernel rerun on the same both3-patched drm.ko (which also carries the DF-4919 fix) completed cleanly.",
  "recommended_fix": "Replace the tsleep() in drain_workqueue() with lksleep(&drain_workqueue, &worker->worker_lock, 0, \"wkdrain\", 1) so the worker can drain while the drainer sleeps",
  "fix_status": "fixed",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "Patched drm.ko (lksleep) completes the identical test: drain_done=1 filler_done=1 within seconds, no wedge, guest healthy (run_fixed.log).",
  "fix_evidence": "findings/poc/DF-4918/run_fixed.log; findings/poc/DF-4918/fix.diff"
}