# DF-5447 VERDICT — uvscom_pre_param() inverted switch

**Status: REPRODUCED (production code) — impact: functional DoS of the serial
port (fails closed); fix validated behaviorally on the guest.**

## What was run

KLD-harness-with-production-code (no SUNTAC VID:PID device model exists for
QEMU): `uvscom_preparam_harness.c` `#include`s the **unmodified** production
`sys/bus/u4b/serial/uvscom.c` (newbus `DRIVER_MODULE`/`MODULE_DEPEND`/
`MODULE_VERSION` registration macros expanded to nothing so no second "uvscom"
driver registers on uhub) and calls the real, file-static
`uvscom_pre_param()` (uvscom.c:514-533) for every baud rate the driver itself
lists as supported.

## Baseline (run.log)

```
UVS5447[A]: calling production uvscom_pre_param() (uvscom.c:514-533) for all 11 supported speeds
UVS5447[A]: pre_param(B150)     = 22 (EINVAL -- REJECTED)
   ... (B300 B600 B1200 B2400 B4800 B9600 B19200 B38400 B57600 B115200) ...
UVS5447[A]: pre_param(B230400)  = 22 (ok, expected EINVAL)
UVS5447[A]: SUPPORTED speeds accepted: 0/11 (BUG: every tcsetattr fails EINVAL,
              uvscom_cfg_param() is unreachable, uvscom.c:532 return(0) dead)
```

All eleven supported speeds return EINVAL(22). The `return (0)` at
uvscom.c:532 is unreachable dead code — every path through the switch,
**including the eleven listed cases**, falls into `return (EINVAL)` at line
530. This is a transcription inversion of the NetBSD original (supported
speeds → `return (0)`, only `default:` → `return (EINVAL)`).

## Why it matters (production call path, cited)

- `ucom_param()` uses this callback to validate every termios change:
  usb_serial.c:1678-1684 — non-zero return ⇒ `goto done` with the error ⇒
  **every `tcsetattr(2)`/TIOCSETA on the tty fails with EINVAL** and
  `ucom_cfg_param` is never queued (usb_serial.c:1691-1693).
- `ucom_open()`'s initial programming call also fails (error discarded,
  usb_serial.c:842) ⇒ `uvscom_cfg_param()` (uvscom.c:535-615) **never
  executes on any open** — the device never receives UVSCOM_SET_SPEED /
  UVSCOM_SET_PARAM (uvscom.c:581,614).
- Net effect: the port is permanently locked to default termios; the driver
  is functionally dead for its whole user base. Fails closed (EINVAL), no
  memory-safety impact.

## Fix validation (run.fixed.log / fix_run.log)

`fix.diff` applied to the guest's /usr/src copy of uvscom.c, same harness
rebuilt (build log in fix_build.log, -Werror clean), re-run:

```
UVS5447[A]: SUPPORTED speeds accepted: 0/11 (BUG: ...)     <- baseline dmesg leftover
UVS5447[A]: SUPPORTED speeds accepted: 11/11 (fixed)
```

With the fix, all eleven supported speeds are accepted and unsupported
speeds (B230400) still return EINVAL. Baseline bad behavior GONE.

## PoC bring-up notes (what had to be fixed vs. a naive include)

1. `#include <sys/termios.h>` does not exist for -nostdinc kernel builds →
   `<sys/tty.h>` (which pulls `<sys/_termios.h>`).
2. The harness prelude must NOT include any `bus/u4b/*` headers before
   including uvscom.c: usb_debug.h's include guard would suppress uvscom.c's
   own `#define USB_DEBUG_VAR uvscom_debug`-first include, leaving
   DPRINTF/DPRINTFN undefined (implicit/nested-extern errors under -Werror).
3. `uvscom_devclass` / `uvscom_driver` become unused when DRIVER_MODULE is
   neutered → referenced from a harness function to stay -Werror clean.

## Environment

See env.txt: DragonFly 6.5-DEVELOPMENT #0 Thu Jul 2 06:02:54 UTC 2026,
X86_64_GENERIC, cc 8.3, guest left pristine (uvscom.c md5
a58a99ef02d63a2d2e7f7b661f5224b3 restored, harness dirs removed, no leftover
KLDs).

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