# DF-5488 VERDICT — REPRODUCED (verbatim production code)

**Finding:** `uvisor_attach()` → `uvisor_init()` (uvisor.c:326, 370-517)
issues up to two synchronous EP0 control requests at the 5000 ms
`USB_DEFAULT_TIMEOUT` (usbdi.h:87) on the per-bus USB explore thread,
before the ucom port exists: 1× vendor IN for VISOR devices
(uvisor.c:382-389), 1× vendor IN for PALM4 devices (uvisor.c:434-442),
2× standard requests for PALM35 devices (uvisor.c:476-496). An evil
adapter with one of the 28 VID:PIDs in uvisor_devs[] (uvisor.c:248-278)
that NAKs the data stages pins bus-wide enumeration for the full chain
(~5 s typical, ~10 s for CLIE_35), holding the per-device enum lock
(usb_request.c:467) per request. Same class as DF-5407 (uplcom ~70 s,
Medium) / DF-5359 (uipaq ~12.8 s, Low).

## Reproduction (verbatim-production-extraction harness, DF-5407 class)

The production `uvisor_init()` is extracted VERBATIM from the guest's
clean tree and compiled into the harness KLD; only the EP0 entry point
it calls is re-targeted to an evil-device model (NAK ~4.9 s → answer,
USB-legal; this is the worst case because the chain then continues to
the next request). Guest and audited host tree are identical
(uvisor.c sha256 b742032f0dab0dc9c5cbfd63432834c00828390ddfe97f3410298f
d703844438). Extraction itself is reproducible (sha256s re-recorded
post-run and matching build.log: uv_defs.h 7911b455…, uv_init.h
63a03e13…).

Measured (hz=100 guest, two runs each):

| variant | phase A (evil) | phase B (250 ms bound) |
|---|---|---|
| VISOR (sc_flag=0x0002) | **4796 / 4802 ms** | 250 / 265 ms |
| PALM4 (sc_flag=0x0001) | **4794 / 4803 ms** | 259 / 261 ms |
| PALM35 (sc_flag=0x0004) | **9591 / 9609 ms** | 249 / 272 ms |

Decisive lines (run.log / run.2.log):
`HX5488: PALM35 (Sony Clie 3.5): uvisor_init() DONE err=USB_ERR_NORMAL_COMPLETION ELAPSED=9591 ms`
`HX5488: VISOR … ELAPSED=4796 ms`, `HX5488: PALM4 … ELAPSED=4794 ms`
Full EP0 trace confirms the exact production requests:
`bmRequestType=0xc2 bRequest=0x03 wLength=18` (GET_CONNECTION_INFORMATION),
`bmRequestType=0xc2 bRequest=0x04 wLength=68` (GET_PALM_INFORMATION),
`bmRequestType=0x80 bRequest=0x08 wLength=1` (UR_GET_CONFIG) +
`bRequest=0x0a` (UR_GET_INTERFACE). The PALM4 run additionally shows the
device-supplied endpoint bytes flowing through the verbatim code into
`config[].endpoint` (`cfg endpoints 10/5` from the 0x5A-filled response).

## Why this is the production behavior

- `uvisor_attach()` calls `uvisor_init(sc, uaa->device,
  uvisor_config_copy)` at uvisor.c:326 before ucom_attach; attach runs on
  the per-bus explore thread (established family-proven in DF-5407/DF-5359:
  usb_needs_explore → usb_bus_explore → device attach serializes the bus).
- Each request is `usbd_do_request_flags(..., USB_DEFAULT_TIMEOUT)` /
  `usbd_do_request(...)` (macro → same, usbdi.h:511-512), whose "WXFER"
  wait loop sleeps until completion or timeout (usb_request.c:642-644,
  699-704). A NAK-ing device burns the full 5000 ms per request.
- On timeout, `err` aborts the chain (uvisor.c:391-393, 444-446, 483-485,
  494-496) and attach fails — but the multi-second explore-thread stall
  has already happened; a gadget device can also answer at 4.9 s to keep
  the chain going (modeled in phase A).

## Severity

Low — bounded (~5-10 s per insertion), requires an evil/malfunctioning
Visor-family adapter; family precedent (DF-5359 at ~12.8 s = Low,
DF-5407 at ~70 s = Medium). Impact: bus enumeration latency / hub event
thread stall, no corruption, no leak.

## Fix validation

`fix.diff` adds `UVISOR_INIT_TIMEOUT` (250 ms) and uses it at all four
call sites (vendor coninfo, palm info, GET_CONFIG, GET_INTERFACE).
Validated two ways:
1. Harness phase B re-extracts the patched function verbatim (renamed):
   all three variants collapse to ~250 ms with `USB_ERR_TIMEOUT` and a
   clean chain abort.
2. The fully patched production uvisor.c compiled -Werror clean as a kmod
   on the guest (fix_compile.log, RC=0).

## Negative results / what was checked and killed

- PALM4 short-transfer uninit: the `actlen < 12` check (uvisor.c:447-451)
  covers exactly the bytes later consumed (offsets 1, 8, 9 of
  `uvisor_palm_connection_info`), so no uninitialized read on that path
  (the unguarded sibling is the VISOR path → DF-5489).
- Device-supplied endpoint nibbles (uvisor.c:452-460) only feed
  `usbd_transfer_setup` endpoint matching (uvisor.c:333-335), which
  validates type/direction against the real interface descriptors.
- Guest left clean: harness dirs removed, production uvisor.c untouched.

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