DF-2337 / verdict.json
{ "finding_id": "DF-2337", "status": "reproduced", "reproduced": 1, "impact": "leak", "confidence": "certain", "verdict": "uep_intr_callback (uep.c:188-276) verbatim rig with stack poisoning: after a 1-byte 0x80 transfer (REPORT header) a second 1-byte transfer computes res = 5 - 1 = 4 and memcpy(sc->buf+1, buf, 4) reads three bytes the device never delivered; the poisoned stack residue (0xA5) lands verbatim in the FIFO record (80 55 A5 A5 A5) that uep_put_queue pushes to /dev/uepN. Control (full 5-byte transfer) shows all device bytes. With the short-transfer stash the attack queues nothing and waits for the rest of the packet; the control path is byte-identical. Requires a malicious or buggy eGalax touch panel (short_xfer_ok makes 1-byte transfers legal), 0644 device, so an unprivileged local user can read the leaked kernel-stack bytes.", "exploit_chain": "malicious USB pointer device sends 1-byte 0x80 then 1 byte; unprivileged user reads /dev/uepN and receives 3 uninitialized kernel-stack bytes per report pair", "evidence": "run.log (attack FIFO: 80 55 a5 a5 a5, attack_exit=0; control 80 11 22 33 44), run_fixed.log (attack: fifo bytes (0) - stash and wait), fix.diff", "kernel_refs": [ "sys/bus/u4b/input/uep.c:225", "sys/bus/u4b/input/uep.c:226", "sys/bus/u4b/input/uep.c:391" ], "poc_changes": "none beyond scenario plumbing; shims reproduce the exact short-transfer copy semantics", "attempts": 3, "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #5 DFBATCH Wed Oct 21 21:27:34 UTC 2026 root:/usr/obj/usr/src/sys/DFBATCH x86_64 (rig kernel); stock baseline #0 X86_64_GENERIC", "runtime_sec": 120, "guest_dirty": 0, "build_cmd": "sh build.sh (userspace verbatim rig)", "run_cmd": "./run.sh (attack control)", "code_hash": "589f692f609e0a76d9fd16f557931a493e6fa6195ba9986abd2eb9ee75a54840", "notes": "fix validated A/B on the same rig: baseline behavior gone post-patch (see run_fixed* logs); rig kernel = X86_64_GENERIC + device dfbatch, INVARIANTS kept", "recommended_fix": "stash the delivered bytes and wait when res exceeds the transfer length" } |