DF-2959 / verdict.json
{ "finding_id": "DF-2959", "status": "untested", "reproduced": 0, "impact": "none", "confidence": "likely", "verdict": "Static-analysis-confirmed consumer-side defect found during the pass-2 consumer sweep of sys/kern/tty_subr.c: ucom_get_data (sys/bus/u4b/serial/usb_serial.c:1898-1906) clamps the contiguous DMA segment to res.length but then calls clist_qtob with the unclamped request length len, so the copy can run up to len bytes past a segment as short as one USB page byte when the TX page cache is multi-segment (usbd_get_page, sys/bus/u4b/usb_busdma.c:96-108) โ a latent kernel heap OOB write with attacker-supplied tty data. The sibling RX path (usb_serial.c:2004-2032) uses res.length correctly. Masked in the common single-segment x86 configuration (res.length = -1 -> clamp == len) and hardware-gated (needs a USB serial adapter); not runnable on the audit guest which has no USB devices (/dev/ttyU* absent), so left untested per the conditional Phase-V policy for Low findings.", "exploit_chain": "", "evidence": [ "sys/bus/u4b/serial/usb_serial.c:1898-1906 โ clamp of res.length ignored by clist_qtob(..., len)", "sys/bus/u4b/serial/usb_serial.c:2004-2032 โ RX path uses res.length correctly (asymmetry proof)", "sys/bus/u4b/usb_busdma.c:80-125 โ usbd_get_page segment semantics (multiseg: USB_PAGE_SIZE - offset; Case 1b: per-page buffer)", "sys/bus/u4b/serial/uplcom.c:838 โ caller passes len = UPLCOM_BULK_BUF_SIZE", "sys/kern/tty_subr.c:127-149 โ clist_qtob enforces only min(n, c_cc) as the copy count" ], "kernel_refs": [ "sys/bus/u4b/serial/usb_serial.c:1906", "sys/bus/u4b/serial/usb_serial.c:1901", "sys/bus/u4b/usb_busdma.c:107", "sys/kern/tty_subr.c:127" ], "poc_changes": "No PoC exists to fix: the defect is reachable only with USB serial hardware; the audit guest has none (/dev/ttyU* absent, ucom.ko present but unbound).", "attempts": 0, "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64", "runtime_sec": 0, "guest_dirty": 0, "build_cmd": "", "run_cmd": "", "code_hash": "", "notes": "Reserved-ID pack DF-2959 for the single new pass-2 finding out of sys/kern/tty_subr.c. In-file pass-2 result: no new memory-safety defect inside tty_subr.c itself beyond the six known (DF-0207/0208/0209/0210/0211/2556); ring arithmetic proven invariant-preserving, blocking-kmalloc TOCTOU killed (LWKT token re-acquisition), sio/usb/ng/tty/tty_pty caller locking verified holding tp->t_token, TTY_QUOTE=0x0100 kills sentinel-collision class, ccmax*(short) signed overflow folded into DF-0211's fix. Fix for this finding: use res.length in the qtob call (fix.diff, mirrors RX path). Fix validation not performed: no hardware on guest, guest left clean and up.", "recommended_fix": "usb_serial.c:1906: pass res.length instead of len to clist_qtob (mirrors the RX path at 2004-2032)" } |