# DF-5455 — umoscom(4): uninitialized kernel stack returned by umoscom_cfg_read() on failed/short vendor control-IN, disclosed to userspace through TIOCMGET modem-status bits

Production file: `sys/bus/u4b/serial/umoscom.c` (MosChip MCS7703 USB serial,
ucom core). Evidence class: **KLD-harness-with-production-code** (no MCS7703
device model exists on the QEMU guest).

## What the harness is

`mo5455_harness.c` #includes `umoscom_prod_guarded.c` — a byte-identical
copy of `/usr/src/sys/bus/u4b/serial/umoscom.c` except ONE guard hunk
(`prod_guard.diff`): the `ucom_cfg_do_request` macro is rerouted after its
`usb_serial.h` definition to `mo_shim_request()` (defined in the separate
TU `mo5455_shim.c`, mirroring production's opaque cross-module
`usbd_do_request_proc` call). The shim reproduces the traced
`usbd_do_request_flags()` failure semantics of an evil/silent MCS7703 —
timeout, and "successful" zero-length data stage — both of which leave the
caller's 1-byte buffer untouched. The DRIVER_MODULE registration is kept
(inert: no MCS7703 exists on the guest); the production cfg helpers are
called directly.

## Build

```
sh build.sh     # in-tree kmod build on the guest:
                # /usr/src/sys/bus/u4b/serial/mo5455 + make
```

## Run

```
sh run.sh       # kldload umoscomunleak.ko x3, kldunload, dmesg | grep MO5455
```

## Expected (decisive) output

```
MO5455: pat=0xff mode=timeout  : PROD msr=0xf0 (predict 0xf0) TIOCM after ucom_totio=0741 MATCH
MO5455: pat=0xa5 mode=0-len    : PROD msr=0xa0 (predict 0xa0) TIOCM after ucom_totio=0501 MATCH
MO5455: pat=0xXX FIXED (val=0) : msr=0x00 (clean)
MO5455: RESULT: ... 12/12 pattern-match across failure modes -- UNINITIALIZED STACK DISCLOSED THROUGH MODEM-STATUS BITS
```

Bits 4..7 of the stale stack byte surface as TIOCM_CTS/TIOCM_DSR/
TIOCM_RI/TIOCM_CD exactly per the production mapping chain
(umoscom.c:511-521 → usb_serial.c:1527 → 1321-1332 → 1259-1270 →
TIOCMGET copyout at 1209-1211). Deterministic across 3 loads (36/36
matches, 0 mismatches). `run.1.fold.log` documents the optimizer-fold
artifact seen when the shim was same-TU inlinable (GCC folded the
provably-uninitialized load to constant 0 — why the shim now lives in its
own TU). `build.werror_evidence.log` shows the production-shaped
cross-TU build compiles with no diagnostic at all — the bug ships
silently; the disassembly (`movzbl -0x9(%rbp),%eax` after the opaque
call, feeding the four `orb` SER-bit translations) is in VERDICT.md.

## Fix

`fix.diff` — initialize `val` in `umoscom_cfg_read()` (one line).
Runtime counterfactual in the harness (fixed twin under identical
poisoning: msr=0x00) plus patched `umoscom.ko` building -Werror-clean
(`fix_compile.log`, RC=0 — and the patched build passes WITH
-Wuninitialized armed).
