# DF-5456 VERDICT — reproduced (impact: dos)

## Finding

Every umoscom cfg-callback step is a synchronous EP0 vendor control
request via `ucom_cfg_do_request()` (usb_serial.h:220-221 →
`usbd_do_request_proc`, 1000 ms timeout) whose `usb_error_t` result is
discarded at every call site — `umoscom_cfg_write()` returns void and
`umoscom_cfg_read()` returns only the (possibly uninitialized, DF-5455)
byte (umoscom.c:524-557). No chain step ever aborts on device failure.

Chain accounting for ONE first open of the tty (all tasks queued on the
per-adapter `sc_super_ucom.sc_tq` by `ucom_open()`, usb_serial.c:801-903):

1. `ucom_param()` at :842 → `umoscom_cfg_param()` — **4 writes**
   (umoscom.c:454 LCR divlatch-enable, :457 BAUDLO, :460 BAUDHI, :492
   LCR format) + hz/10 pause (usb_serial.c:1636);
2. `ucom_cfg_open` at :865 → `umoscom_cfg_open()` — **5 writes**
   (:368 FIFO purge, :371 FIFO enable, :377 INT enable, :380 magic 0x01,
   :383 magic 0x00) + hz/10 pause (usb_serial.c:777);
3. line-state task at :874-878 (DTR|RTS + ring-off + break-off coalesced
   by usb_serial.c:1384-1420) — **3 writes** (umoscom.c:415 set_dtr,
   :428 set_rts, :402 set_break);
4. `ucom_status_change()` at :880 → `umoscom_cfg_get_status()` —
   **2 reads** (umoscom.c:506 LSR, :507 MSR).

= **14 sequential 1000 ms-timeout requests + 2 × hz/10 pauses ≈ 14.2 s**
of uninterruptible taskqueue occupancy for one open(2) of an evil/silent
MCS7703 — the largest 1000 ms-family chain measured this pass (uslcom
5, uftdi 5, uvscom 5 requests).

Amplifiers:

- every later `tcsetattr` of the open tty re-queues cfg_param
  (double-buffered, usb_serial.c:1691-1693): **+4.1 s each**,
  unprivileged local user;
- `close(2)` is synchronous against the queue (usb_serial.c:671-672 +
  955-957, uninterruptible usb_process.c:385-393) while
  `umoscom_cfg_close()` itself is a no-op (umoscom.c:386-390) — the
  closer purely waits out whatever is in front of it;
- unplug mid-cycle pins the USB hub event thread via `ucom_detach()` →
  `usb_proc_drain()` (usb_serial.c:394) — the DF-5367 mechanism;
- a device that answers each request at just under 1000 ms makes every
  request *succeed* — same occupancy, nothing to propagate even if
  errors were checked (only the bounded timeout helps there).

## Reproduction (KLD harness, guest 6.5-DEVELOPMENT, hz=100)

Real `usb_process` taskqueue, production request counts, production
1000 ms timeout, per-request cost = one `lksleep("WXFER", 1000 ms)`
(the exact traced cost of a data stage the device never answers):

| phase | meaning | measured |
|---|---|---|
| A | first-open chain + synchronous close | **13922 ms** |
| 2 | + 1 extra user tcsetattr behind it | **17923 ms** |
| B | fix mechanism #1 (abort chain on first error) | **4109 ms** |
| C | fix #1+#2 (abort + 250 ms bound) | **1229 ms** |

(`run.log`; full per-task traces with request accounting in the same
log.) Matches the predicted 14.2/18.3/4.4/1.2 s minus the closer's
100 ms head start. Phase C is also the fix-mechanism validation: the
family fix cuts the worst case from 14.2 s to ~1.2 s.

## Impact ceiling

Evil-USB (or wedged-device) precondition: insertion of a crafted
MOSCHIP 0x9710:0x7703 adapter, or any real MCS7703 that stops answering
EP0. Then: per-open ~14 s uninterruptible occupancy of the adapter's ucom
taskqueue, SIGKILL-immune blocked closers, hub event thread stalls on
unplug, unprivileged-user-tcsetattr amplification. Severity: **Low**
(family precedent DF-5421/5424/5425/5449; below uplcom's 70 s Medium
DF-5407), base:hw bucket.

## Fix validation

- `fix.diff` (UMOSCOM_CFG_TIMEOUT=250, error-propagating
  `umoscom_cfg_write()`, chain aborts on first failure in
  cfg_open/cfg_param with divisor-latch safety preserved): patched
  production `umoscom.ko` builds -Werror-clean on the guest
  (`fix_compile.log`, RC=0, 11 hunks applied).
- Runtime mechanism: harness phases B (4109 ms) and C (1229 ms) vs
  baseline A (13922 ms) — `fix_baseline_reproduced=1`,
  `fix_patched_reproduced=1` (mechanism-level, the family-standard
  validation for this class: the request-level behavior change is
  exercised directly; no full patched-kernel boot is required to observe
  a per-request timeout bound).

Not applied to `sys/` (read-only audit target).

## 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.
