# DF-5516 VERDICT — reproduced (mechanism level, verbatim production block)

## Finding

`ubser_attach()` (ubser.c:223-299) issues its FIRST bus transaction
synchronously on the attaching thread — the per-bus USB explore (hub event)
thread: the VENDOR_GET_NUMSER control read at ubser.c:243-251 with
`USB_DEFAULT_TIMEOUT` = **5000 ms** (usbdi.h:87). An evil adapter is one
firmware string away from this path: `ubser_probe` (ubser.c:215-217) matches
manufacturer string "BWCT" + bInterfaceClass 0xff + bInterfaceSubClass 0x00.
A device that NAKs the data stage pins bus-wide device enumeration for the
full 5 s per insertion; a device that answers at just-under-timeout pins
~4.9 s while every request SUCCEEDS (no error visible anywhere).

## Reproduction (verbatim extraction)

build.sh sed-extracts **ubser.c:242-262 unmodified** from the guest's
md5-gated `/usr/src` into `ub5516_block.c` and compiles it inside the
simulated attach; the production driver file is also included whole (for
types/constants; registration neutered). Only the EP0 sink
(`usbd_do_request_flags`, matching usbdi.h:508-510) and `device_printf` are
models; `usbd_errstr` is the real kernel symbol. The fragment's
`goto detach` (ubser.c:257) binds to a local label standing in for the
production label at ubser.c:296-298.

Measured (run.log / run.2.log, hz=100):

| phase | scenario | measured |
|---|---|---|
| A | silent evil device (NAK until timeout) | explore-thread occupancy **4916/4917 ms**; verbatim error path fires ("failed to get number of serial ports: USB_ERR_TIMEOUT" via the real usbd_errstr) and the verbatim `goto detach` aborts attach |
| B | slow-answer device (answers at 4900 ms, claims 4 ports) | occupancy **4812/4807 ms**; request SUCCEEDS, verbatim "found 4 serials", attach CONTINUES — invisible variant |
| C (fixed) | timeout bounded to 1000 ms (fix.diff) | occupancy **1009 ms** fail-fast (891 ms slow-answer) — pin GONE |

During the pin no other device on that bus can finish enumerating (family
mechanism, DF-5359/DF-5407/DF-5488/DF-5505); repeatable at will by
re-insertion.

## Fix validation

fix.diff (ubser.c:251: `USB_DEFAULT_TIMEOUT` -> `1000`) applied to the
guest's /usr/src copy; block re-extracted (now at 244-264 due to the +2-line
comment); harness rebuilt -Werror clean; rerun: **1009 ms** fail-fast vs
4916 ms baseline (run.fixed.log). Guest tree restored and md5-verified
(85afa08fa4f618c9288a6dca75d9e671). `git apply --check` passes against the
audited host repo.

## Impact

Availability only (per-bus enumeration stall, ~5 s per evil-BWCT insertion;
family minimum — exactly one attach request, cf. DF-5505 ucycom Low,
uvisor 2x5 s DF-5488 Low, uipaq 12.8 s DF-5359 Low, uplcom ~70 s DF-5407
Medium). Low per family calibration.

## Honest scope notes

- Mechanism level: no physical BWCT adapter exists for the guest; the EP0
  sink timing is modeled, the attach block, request fields, error path and
  abort path are production code verbatim.
- build.sh's md5 gate correctly refuses to run on a patched tree; the
  fixed-build extraction (+2 line shift) is documented in README.md.

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