⬢ DragonFlyBSD Kernel Audit
DF-5517 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-5517",
  "status": "reproduced",
  "reproduced": true,
  "impact": "dos",
  "confidence": "certain",
  "verdict": "Production-code request-sequence proof: the unmodified ubser.c (md5-gated) is compiled into a KLD harness and the real static ubser_cfg_set_break() runs on a real usb_process taskqueue with the exact ucom_cfg_line_state arithmetic (usb_serial.c:1384-1420). The full open -> TIOCSBRK -> TIOCCBRK -> close lifecycle sends exactly ONE device command, VENDOR_SET_BREAK (0x02); the clear command is NEVER sent on any path -- PHASE L sequence = { 0x02 }, PHASE D (direct set_break(1); set_break(0) on a live port) = { 0x02 }, VENDOR_CLEAR_BREAK (0x03) NEVER OBSERVED, because the request lives inside `if (onoff) (ubser.c:470) with no else-leg and the constant at ubser.c:102 has exactly one occurrence in the file (its #define, grep proof in build.log). Consequence: once a break is set on a BWCT port, the devices line stays broken until the adapter is power-cycled; TIOCCBRK and close are silent kernel-side no-ops and all subsequent TX on the port is garbled (functional kill of the port, fails open). Upstream-inherited (FreeBSD ubser has the identical shape). fix.diff (else-leg sending VENDOR_CLEAR_BREAK, wValue=portno, bounded 250 ms) rebuilt and rerun on the guest: both phases observe { 0x02, 0x03 }; tree restored md5-verified.",
  "exploit_chain": "any tty opener (root via ttyU* 0600, group dialer via cuaU* 0660, usb_serial.c:477-488) issues TIOCSBRK once -> VENDOR_SET_BREAK (0x02) reaches the device -> TIOCCBRK/close send nothing (ubser.c:470 gate, ubser.c:102 dead constant) -> the BWCT ports TX line remains in break indefinitely -> every later write(2) on the port transmits garbage until the adapter is physically replugged",
  "evidence": "run.log/run.2.log: PHASE L lifecycle request sequence = { 0x02 } (1 request(s); VENDOR_CLEAR_BREAK=0x03 NEVER OBSERVED) and PHASE D direct set+clear request sequence = { 0x02 } (...); build.log grep proof VENDOR_CLEAR_BREAK occurrences in ubser.c: 1 (definition only: YES); run.fixed.log: both sequences = { 0x02, 0x03 } (0x03 OBSERVED)",
  "kernel_refs": [
    "sys/bus/u4b/serial/ubser.c:99-102",
    "sys/bus/u4b/serial/ubser.c:462-487",
    "sys/bus/u4b/serial/ubser.c:470-486",
    "sys/bus/u4b/serial/usb_serial.c:1190-1197",
    "sys/bus/u4b/serial/usb_serial.c:1401-1420"
  ],
  "poc_changes": "No seed PoC existed; authored from scratch (DF-5447 production-include + DF-5515 rig). Bring-up fixes: (1) kernel TU has no memchr -- replaced with a scan loop; (2) neutered ubser_driver/ubser_devclass statics must be referenced (touch function) or -Wunused kills the build; (3) the direct-clear phase must run on a LIVE taskqueue so the sinks usb_proc_is_gone gate (usb_request.c:771) passes as in production.",
  "attempts": 4,
  "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": 700,
  "guest_dirty": 0,
  "build_cmd": "sh /root/df5517/src/build.sh (in-tree kmod at /usr/src/sys/bus/u4b/serial/ub5517, -Werror clean; prints the reference-count grep proof)",
  "run_cmd": "sh /root/df5517/src/run.sh (kldload /root/df5517/ub5517clrbrk.ko; kldunload; dmesg | grep UB5517)",
  "code_hash": "32433755711ede5e46ee39717be4483f577a9a69892749fe9ad7a8da36690b04",
  "notes": "Guest left pristine (ubser.c md5 restored, harness dirs removed, modules unloaded). Severity Low: functional/port-availability defect for tty openers, no kernel memory-safety impact, fails open. Upstream-inherited from FreeBSD -- candidate for an upstream joint fix.",
  "recommended_fix": "Add the missing else-leg to ubser_cfg_set_break() sending VENDOR_CLEAR_BREAK (wValue=portno) with a bounded 250 ms timeout (full diff in fix.diff; validated: clear now OBSERVED).",
  "fix_status": "fixed",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 1,
  "fix_verdict": "fix.diff applied to the guests /usr/src ubser.c (guest patch(1), hunk #1 @482); same production-code harness rebuilt -Werror-clean and re-run: PHASE L = { 0x02, 0x03 } and PHASE D = { 0x02, 0x03 } -- VENDOR_CLEAR_BREAK OBSERVED, the clear path exists. git apply --check passes on the audited repo; guest tree restored and md5-verified.",
  "fix_evidence": "fix.diff; fix_build.log (RC=0); run.fixed.log (VENDOR_CLEAR_BREAK=0x03 OBSERVED in both phases); VERDICT.md Fix validation section"
}