DF-5767 / verdict.json
{ "finding_id": "DF-5767", "status": "untested", "verdict": "ohci_controller_init (sys/bus/u4b/controller/ohci.c:282-287) latches the device-reported root-hub port count OHCI_GET_NDP(OREAD4(OHCI_RH_DESCRIPTOR_A)) with an 8-bit mask (ohcireg.h:97) and no upper-bound check \u2014 the retry loop only retries on zero (AMD756 erratum) \u2014 and re-latches it on every resume (ohci.c:462-476). The OHCI 1.0a spec caps NDP at 15 and the operational register file at 0x100 bytes (port regs at 0x50+4n, ohcireg.h:113). With NDP in [16,255]: ohci_root_intr (ohci.c:1610-1616) OREAD4s port status 1..noport (up to 0x474) on every RHSC interrupt; ohci_roothub_exec bounds port indices only by sc_noport (ohci.c:2221/2306/2324) and issues OOB MMIO reads AND writes (fixed UPS_* bit patterns incl. UPS_RESET) up to 0x474; the hub descriptor propagates bNbrPorts=sc_noport (ohci.c:2279) so the kernel uhub thread drives these OOB accesses itself during port exploration. Same register-geometry-trust family as DF-5268/DF-5282/DF-5296. Not live-testable on the audit guest: QEMU hard-caps OHCI num-ports at 15 (hw/usb/hcd-ohci.c:1953-1955) and models HcRhDescriptorA fully read-only (OHCI_RHA_RW_MASK=0, hcd-ohci.c:189/1791-1792), and the default guest QEMU config has no USB controller at all \u2014 identical posture to family sibling DF-5296 (filed untested).", "reproduced": false, "impact": "none", "confidence": "certain", "exploit_chain": "", "evidence": "findings/poc/DF-5767/README.md (full trace), VERDICT.md (narrative incl. killed pass-2 candidates), fix.diff (applies cleanly, NDP clip to 15), qemu-hcd-ohci-reference.c:189/1791/1953 (QEMU caps+RO register proving untestability), env.txt (guest has no USB controller), itd_offset_sim.py (negative-result proof for the isoc ITD page-math class)", "kernel_refs": [ "sys/bus/u4b/controller/ohci.c:286", "sys/bus/u4b/controller/ohci.c:283", "sys/bus/u4b/controller/ohci.c:462", "sys/bus/u4b/controller/ohci.c:1606", "sys/bus/u4b/controller/ohci.c:1612", "sys/bus/u4b/controller/ohci.c:2221", "sys/bus/u4b/controller/ohci.c:2306", "sys/bus/u4b/controller/ohci.c:2324", "sys/bus/u4b/controller/ohci.c:2279", "sys/bus/u4b/controller/ohcireg.h:97", "sys/bus/u4b/controller/ohcireg.h:113", "sys/bus/u4b/controller/ohci.h:251" ], "poc_changes": "no PoC seed existed; no trigger written because the precondition (controller NDP>15) cannot be instantiated on the audit guests QEMU (num-ports capped at 15, HcRhDescriptorA read-only, no USB controller on default cmdline)", "attempts": 0, "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:02 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": "Low severity / kernleak (hardware-trust) class, consistent with DF-5296 (uhci BAR trust, Low). Pass-2 depth documented in VERDICT.md: isoc ITD 3-page mis-mapping proven real (sim) but confined to the transfers own DMA allocation (QEMU page(bp0)/page(be) clamping; sumlen validated at usb_generic.c:1166-1170) => integrity bug only, not filed; isoc nframes==0 NULL-deref unreachable (usb_transfer.c:1748/2779); TD/ED sizing, cbp/be guards, isoc_done clamps, double-done serialization, done-list-free reaping design all verified sound.", "recommended_fix": "Clip latched NDP to the OHCI 1.0a maximum of 15 at the latch site (ohci.c:286, both boot and resume paths) with a device_printf warning; defense-in-depth: clamp port indices to 15 in ohci_root_intr/ohci_roothub_exec checks.", "fix_status": "not_testable", "fix_baseline_reproduced": 0, "fix_patched_reproduced": 0, "fix_verdict": "fix.diff (git-apply clean) clips sc_noport to 15 inside the re-read loop, covering boot and resume latch paths; validation kernel build/boot not performed because the bug cannot be manifested on this guest (QEMU NDP hard cap 15 + read-only HcRhDescriptorA), so baseline==patched==no-observable-change by construction.", "fix_evidence": "findings/poc/DF-5767/fix.diff" } |