{
  "finding_id": "DF-5426",
  "status": "reproduced",
  "reproduced": true,
  "impact": "leak",
  "confidence": "certain",
  "verdict": "The gadget EP0 engine usb_handle_request() is CONTAINED for every in-tree provider and driver: 41/41 live containment expectations met against the production code (twice, no panic, no guard-zone hits), and the ustorage pass-2 question about max_len -= off (:746) is answered with three independent proofs (exact mod-2^16 cancellation with *plen += off at :285 for the driver path; off<=len induction for internal/template paths; the force_short->control_rem=0 feeder always lands rem==0 where :753 clamps). The filed finding is the missing explicit underflow guard at :746: the rig demonstrates on the production code that a provider length that shrinks below the already-transferred offset wraps max_len and yields an out-of-object DMA window of up to ~4 KiB per fragment (P1a: escapes 1948/2972/3996 bytes; P1b: 2044/3068/4092) - a latent OOB DMA read (IN) / write (OUT, P2 via real kobj devmethod dispatch) primitive gated on a contract-violating out-of-tree usb_temp_get_desc_p provider or gadget driver, since all in-tree providers are pure functions of the immutable setup bytes. Info severity / hardening; fix.diff adds the two-line guard and the fix-validated rig shows the primitive gone (contained=43, escaped=0) with all 41 conformant behaviors unchanged.",
  "exploit_chain": "Not reachable in-tree. Demonstrated latent chain (rig only): hostile USB host issues GET_DESCRIPTOR with wLength == descriptor length (multi-fragment data stage) -> fragment 1 delivers 1024 bytes -> provider that returns a smaller length for later fragments makes max_len = len - off wrap (uint16) -> :750/:753 clamps to 1024/rem but not to the object -> usbd_xfer_set_frame_data(:785) aims the controller DMA at src_zcopy+off for 1024 bytes -> OOB read of adjacent kernel memory streamed to the host (leak); the mirror-image ctrl-WRITE path through a lying sub-driver aims host-controlled DMA writes past the driver buffer (heap overflow). Requires a length-shrinking provider, i.e. out-of-tree kernel code - no in-tree trigger exists.",
  "evidence": "run.log: P1a ... ESCAPE 1948/2972/3996 bytes, P1b ... ESCAPE 2044/3068/4092 bytes, SUMMARY: contained=41 failed=0 latent-primitives=4, RUN_RC=0 (twice); fix_run.log: P1a/P1b ... escaped=0, SUMMARY: contained=43 failed=0 latent-primitives=2; build.log/fix_build.log (production md5 a972d0a7efbc45870ba3741ffb92c8a4, patched 7d86c18229c4456b33c8cdec43eae971); VERDICT.md for the full candidate kill list",
  "kernel_refs": [
    "sys/bus/u4b/usb_handle_request.c:746",
    "sys/bus/u4b/usb_handle_request.c:285",
    "sys/bus/u4b/usb_handle_request.c:750",
    "sys/bus/u4b/usb_handle_request.c:753",
    "sys/bus/u4b/usb_handle_request.c:785",
    "sys/bus/u4b/usb_handle_request.c:644",
    "sys/bus/u4b/usb_transfer.c:1548",
    "sys/bus/u4b/usb_transfer.c:1608",
    "sys/bus/u4b/usb_transfer.c:1616",
    "sys/bus/u4b/usb_dynamic.h:48",
    "sys/bus/u4b/gadget/g_audio.c:544"
  ],
  "poc_changes": "Seed was a concept only; the rig (neg_usbhr.c) was written from scratch: #includes the production usb_handle_request.c, synthesizes xfer/root/udev/bus with guard-patterned buffers, replicates the usbd_setup_ctrl_transfer control_rem lifecycle, overrides usb_temp_get_desc_p with scripted hostile providers, and drives the real USB_HANDLE_REQUEST kobj dispatch through a bare kobj device. Two harness iterations were needed (lock-discipline for the callback context; completion-fragment and zero-copy classification in expectations).",
  "attempts": 4,
  "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": 2100,
  "guest_dirty": 0,
  "build_cmd": "ssh guest cd /root/negusbhr && sh build.sh  (KLD: #include production usb_handle_request.c; make against /usr/src)",
  "run_cmd": "ssh guest cd /root/negusbhr && sh run.sh  (kldload negusbhr.ko x2; NEG: battery on console/dmesg)",
  "code_hash": "05b92889b37b4f8555e76a36aa8efba2e61c26e64ecad2b0c554ba1a989cdcd2",
  "notes": "File-level pass-2 verdict: CLEAN apart from this Info hardening finding - every other candidate class (OOB copy/DMA, uninit reads, subdev TOCTOU, broadcast iteration bounds, alt/endpoint/address validation, scratch lifetime, stale frame pointers, FreeBSD-main delta) was killed by trace + live rig. SET_CONFIG and remote-wakeup paths traced statically only (need configured device graph / bus explore). Guest reset to clean-source snapshot after bring-up panic (rig bug); final runs are from the clean snapshot and the guest is healthy (guest_dirty=0).",
  "recommended_fix": "Guard the offset subtraction in usb_handle_request() tr_valid: if (max_len < off) max_len = 0; else max_len -= off; - behavior-preserving for all conformant providers, turns any provider-length wrap into a clean status-stage termination (see fix.diff).",
  "fix_status": "fixed",
  "fix_baseline_reproduced": true,
  "fix_patched_reproduced": false,
  "fix_verdict": "Rig-level fix validation (the patched unit is exactly the function the rig executes): baseline shows the P1a/P1b wrap escapes (esc_bytes 8916/9204); the identical rig built against the patched production file shows escaped=0 for both, clean status-stage termination after the honest prefix, contained=43/43, all 41 conformant cases byte-identical. P2/P3 (third-party driver-contract violations) intentionally remain - not addressable in this file.",
  "fix_evidence": "fix.diff; fix_build.log (patched md5 7d86c18229c4456b33c8cdec43eae971); fix_run.log lines P1a SHRINK 4096->100 ... contained, P1b ... contained, P1a frags=3 sent=1024 escaped=0, SUMMARY: contained=43 failed=0 latent-primitives=2, RUN_RC=0"
}