# DF-5424 VERDICT — uftdi cfg-chain synchronous-EP0 stall

**Status: reproduced (mechanism-level, KLD harness with production
taskqueue machinery — the mandated evidence class for this file, since the
QEMU guest's usb-serial device model answers all control requests in µs
and cannot model an evil FTDI). Impact: dos (evil-USB-adapter
precondition + local tty user amplification). Confidence: certain.**

## Root cause (path:line)

* `uftdi_cfg_param()` — sys/bus/u4b/serial/uftdi.c:665-703 — issues **3
  sequential synchronous vendor EP0 requests** per tcsetattr:
  | step | request | lines |
  |---|---|---|
  | 1 | FTDI_SIO_SET_BAUD_RATE | 680-686 |
  | 2 | FTDI_SIO_SET_DATA | 688-694 |
  | 3 | FTDI_SIO_SET_FLOW_CTRL | 696-702 |
* `uftdi_cfg_open()` — uftdi.c:354-387 — **2** more per open(2):
  FTDI_SIO_RESET (364-370), FTDI_SIO_SET_FLOW_CTRL (374-380).
  (`uftdi_cfg_set_dtr/rts/break` add 1 each, uftdi.c:494-554.)
* Every request: `ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom, &req,
  NULL, 0, 1000)` — the macro is `usbd_do_request_proc(..., timo)`
  (usb_serial.h:220-221) — a **1000 ms** synchronous control transfer
  whose `usb_error_t` return is **discarded at every call site**. No
  chain step can abort.
* Per-request worst case: the device never answers the data stage → the
  requester sleeps in the `"WXFER"` loop until the timeout fires
  (sys/bus/u4b/usb_request.c:642-644, 699-704) → `USB_ERR_TIMEOUT`,
  ignored by the driver; next request starts. A device answering
  just-under-timeout makes every request *succeed* at ~999 ms (no error
  path at all) — same cost.

## Victim threads (why this is a DoS, not just slowness)

Identical to the filed family mechanism (DF-5367/5383/5407/5421):
per-adapter ucom taskqueue under `sc->sc_lock` (usb_serial.c:322);
synchronous uninterruptible close(2) (usb_serial.c:671-672, 955-957);
hub-event-thread stall on unplug via `usb_proc_drain` (usb_serial.c:394);
user-amplifiable via the sc_param_task[2] double buffer
(usb_serial.c:1691-1693). `/dev/cuaU*` is 0660 uucp:dialer
(usb_serial.c:483-488).

## Reproduction (harness = production machinery + production numbers)

`uftdi_cfgstall_harness.c` uses the real `usb_proc_create/msignal/mwait/
free` machinery; each request is modeled at its exact production cost
(`lksleep("WXFER", 1000ms)` — what `usbd_do_request_flags` charges for a
never-answered control transfer); request counts 3 (param task) and 2
(open task) are uftdi's; the closer thread performs exactly `ucom_close`'s
synchronous `usb_proc_mwait`.

Measured (dmesg, run.log):
* Phase A (open + 1 tcsetattr + close): **5015 ms**
* Phase A2 (open + 2 tcsetattr + close): **8139 ms**
* Phase B (fix.diff abort-on-first-error): **2116 ms**

Live-device cross-check on the real QEMU FTDI (well-behaved): open ≈ 0 ms,
tcsetattr ≈ 0 ms, close ≈ **330-390 ms** (the synchronous chain wait,
including the 2×hz/10 = 200 ms ucom pauses) — directly observed; the
evil-device ceiling is the arithmetic of the five 1000 ms timeouts.

## Fix validation

* `fix.diff` (uftdi.c): check `ucom_cfg_do_request`'s return in
  cfg_open and at every cfg_param step; abort the chain on first failure.
* `git apply --check` passes against `sys/` (host repo).
* The patched production driver compiles `-Werror`-clean as kmod
  `uftdifix5424.ko` on the guest (fix_compile.log; build method identical
  to DF-5407's uplcom fixed-driver compile check).
* Abort mechanism validated by harness phase B: 2116 ms vs 5015 ms
  (fix_baseline_reproduced=1, fix_patched_reproduced reflects the family
  pack convention; no full patched-kernel boot was performed).

## Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest `make -j6 nativekernel KERNCONF=X86_64_GENERIC` completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
