⬢ DragonFlyBSD Kernel Audit
DF-5487 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-5487",
  "status": "reproduced",
  "reproduced": true,
  "impact": "dos",
  "confidence": "certain",
  "verdict": "Mechanism-level reproduction with production machinery (same evidence class as the proven family findings DF-5367/5383/5421/5424/5425/5449/5456/5476): uvisor_cfg_close() issues the drivers ONLY cfg-path EP0 request -- one CLOSE_NOTIFICATION vendor control-IN at a 1000 ms timeout with the usb_error_t discarded (uvisor.c:529-545, request at 539-540, error at 541-544) -- and close(2) waits for it uninterruptibly (ucom_queue_command -> usb_proc_mwait, usb_serial.c:671-672 + 955-957). uvisors cfg surface is the familys smallest: uvisor_cfg_open() is empty (uvisor.c:519-523, open chain = 0 requests + core hz/10 pause usb_serial.c:777) and there are no param/status/line callbacks (uvisor.c:224-231), so tcsetattr is free. Harness on the real usb_process taskqueue: a close(2) issued 50 ms behind an open blocks ELAPSED=1080/1093 ms across two runs (SIGKILL-immune) while the evil Visor NAKs the vendor data stage (WXFER cost, usb_request.c:642-644); unplug stalls the hub event thread identically via usb_proc_drain (usb_serial.c:394) plus the per-device enum lock (usb_request.c:467). Fix mechanism (UVISOR_CFG_TIMEOUT 250 ms bound) demonstrated at ELAPSED=346/363 ms and the fully patched production uvisor.ko compiled -Werror-clean RC=0 on the guest.",
  "exploit_chain": "Evil USB adapter with a Handspring/Palm VID:PID from uvisor_devs[] (e.g. HANDSPRING 082d:0100, uvisor.c:254) enumerates as uvisor and NAKs the CLOSE_NOTIFICATION vendor data stage -> the single cfg-close request eats its full 1000 ms timeout -> every close(2) of /dev/ttyUxx blocks ~1 s SIGKILL-immune behind usb_proc_mwait; yanking the device mid-cycle stalls the per-bus USB hub event thread the same ~1 s via ucom_detach -> usb_proc_drain; repeatable per open/close cycle but bounded at ~1 s -- the weakest member of the family (DF-5476 ~10 s, DF-5456 ~14 s, DF-5449 ~6.1 s, all Low).",
  "evidence": "run.log/run.2.log: HX5487[A]: closer: unblocked ELAPSED=1080 ms / 1093 ms (baseline) and HX5487[B]: ... ELAPSED=346 ms / 363 ms (fix mechanism); task-level trace shows cfg-open (EMPTY, 0 reqs + hz/10 pause) -> line tasks (0 reqs) -> cfg-close (1 x 1000 ms, error DISCARDED) with the closer in usb_proc_mwait throughout; build.log: -Werror kmod build; fix_compile.log: patched production uvisor.ko RC=0.",
  "kernel_refs": [
    "sys/bus/u4b/serial/uvisor.c:529-545",
    "sys/bus/u4b/serial/uvisor.c:519-523",
    "sys/bus/u4b/serial/uvisor.c:224-231",
    "sys/bus/u4b/serial/usb_serial.c:671-672",
    "sys/bus/u4b/serial/usb_serial.c:955-957",
    "sys/bus/u4b/serial/usb_serial.c:394",
    "sys/bus/u4b/serial/usb_serial.h:220-221",
    "sys/bus/u4b/usb_request.c:642-644",
    "sys/bus/u4b/usb_request.c:467"
  ],
  "poc_changes": "No seed PoC existed; authored from scratch on the DF-5449 harness pattern with uvisors production chain shape (0 requests per open chain, 1 per close chain, 1000 ms). One bring-up iteration: none needed beyond the pattern (first build -Werror clean).",
  "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": 90,
  "guest_dirty": 0,
  "build_cmd": "cd /usr/src/sys/bus/u4b/serial/hx5487 && make (in-tree kmod build, -Werror clean; see build.sh)",
  "run_cmd": "kldload /root/df5487/uvisorcfgstall.ko; kldunload uvisorcfgstall; dmesg | grep HX5487 (see run.sh)",
  "code_hash": "f73a9c3d3bdaf1a272f02d82fdb0bb491d8b8dc0b30898a69fbc03fc0b2195d1",
  "notes": "Guest cleaned after runs (harness dirs removed, uvisor.c md5 restored/unchanged 28d0d390d06dd00f9dbfc03106b453a7). Severity Low, consistent with family: bounded ~1 s per close cycle, requires an evil/malfunctioning Visor-VID:PID device. Negative results recorded in VERDICT.md: no DF-5384-class detach-on-never-attached (ucom_detach guarded, usb_serial.c:376-377); no param/status chains to stall. fix.diff git-apply --check passes against the host repo tree.",
  "recommended_fix": "Bound the cfg-path control timeout to 250 ms (UVISOR_CFG_TIMEOUT) for the CLOSE_NOTIFICATION request (full diff in fix.diff).",
  "fix_status": "fixed",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 1,
  "fix_verdict": "fix.diff applied to the guests /usr/src copy: the production uvisor.ko compiled -Werror-clean RC=0 (fix_compile.log); harness phase B models the fixed drivers timeout bound: closer ELAPSED drops from ~1.08-1.09 s to ~0.35-0.36 s across two runs. The full-second uninterruptible occupancy is GONE under the fix mechanism.",
  "fix_evidence": "fix.diff (sha256 f73a9c3d... is the harness; fix.diff itself verified by git apply --check on host + guest patch -p5); fix_compile.log (RC=0); run.log/run.2.log phase-B lines; VERDICT.md Fix validation."
}