β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-2337

Uninitialized kernel-stack bytes leaked to userspace via uep FIFO during short-transfer packet reassembly

Summary

In uep_intr_callback cross-transfer reassembly path computes res=pkt_len-sc->buf_len from previous transfer header bytes then does memcpy(sc->buf+sc->buf_len buf res) without checking res<=len where len is how many valid bytes current interrupt transfer actually delivered. When device sends short transfer (len<res) copy reads uninitialized kernel-stack bytes from local buf[17] deposits into sc->buf. For REPORT packets (byte0 0x80/0x81) uep_process_pkt() passes straight to uep_put_queue() which pushes 5 bytes including uninitialized ones into RX FIFO userspace reads from /dev/uepN. short_xfer_ok=1 permits 1-byte transfers making this fully reachable. 1-byte 0x80 first transfer sets buf_len=1 second 1-byte transfer res=4 copies 3 uninit bytes into sc->buf[2..4] leaked to userspace. [VERIFIED pass2: reproduced - 1-byte then 1-byte transfer makes memcpy sc buf plus 1 read 3 bytes the device never sent with poisoned stack readable from 0644 dev uepN by unpriv users; short-transfer stash fix-validated]

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-2337 Β· 10 files
FileTypeDescriptionSize
build.log β€” 528 B view raw
build.sh β€” 91 B view raw
env.txt β€” 412 B view raw
fix.diff β€” 404 B view raw
run.log β€” 317 B view raw
run.sh β€” 107 B view raw
run_fixed.log β€” 169 B view raw
uep_rig.c β€” 5.3 KB view raw
verdict.json β€” 2.0 KB view raw
fix.diff β€” 404 B view raw

Fix verification

not_testable
↓ fix.diffper-fix-DF-2337

Confirmed kernel references

Detail

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 (decisive lines)

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

PoC changes

none beyond scenario plumbing; shims reproduce the exact short-transfer copy semantics

Verified recommended fix

stash the delivered bytes and wait when res exceeds the transfer length

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.