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

Unclamped cdb_len over-reads 16-byte inline cdb_bytes and leaks kernel memory out parallel port

Summary

vpo_intr passes csio->cdb_len (u_int8_t 0..255) directly as command length to imm_do_scsi/vpoio_do_scsi while handing &csio->cdb_io.cdb_bytes as command buffer but cdb_bytes is fixed 16-byte IOCDBLEN inline array. cdb_len>16 makes send loop read past cdb_bytes into rest of csio/ccb (cdb_ptr/msg_ptr kernel pointer aliases) and transmit bytes out parallel-port SCSI bus. Leaked bytes include kernel pointer material from csio struct KASLR disclosure to physical/hardware channel. csio->cdb_len caller-controlled unvalidated via xpt_merge_ccb. Local privileged attacker root/operator. [PASS-2 NOTE: DF-2530/DF-2531 are the sense/cdb halves of DF-1958 - one unclamped-length root; fold on triage] [VERIFIED pass2: reproduced - cdb_len 255 clocks 240 bytes past the 16-byte cdb out the parallel port with first 8 the csio msg_ptr kernel pointer; malicious-peripheral reach; clamp fix inline-A/B]

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-2531 Β· 6 files
FileTypeDescriptionSize
rig.c β€” 9.0 KB view raw
gen.sh β€” 785 B view raw
Makefile β€” 171 B ↓ download
build.sh β€” 93 B view raw
run.sh β€” 90 B view raw
run.log β€” 1.1 KB view raw

Fix verification

not_testable
↓ fix.diffper-fix-DF-2531

Confirmed kernel references

Detail

Evidence (decisive lines)

vpo2531_run.log: OUT bytes clocked=256 (in-bounds=16 OOB=240) and first OOB bytes: 34 12 fe ca ef be ad de (msg_ptr=0xdeadbeefcafe1234); control run clean

PoC changes

verbatim-extract rig (vpo_intr + imm_do_scsi + interposed imm_* transport), sysctl-driven

Verified recommended fix

clamp csio->cdb_len to IOCDBLEN before the transfer call in vpo_intr

Verdict

vpo_intr (vpo.c:220-226) hands (char*)&csio->cdb_io.cdb_bytes and the unvalidated user CCB byte csio->cdb_len (0..255 via pass(4) xpt_merge_ccb) to imm_do_scsi; cdb_bytes is the 16-byte IOCDBLEN inline array, and the command loop clocks out 2 bytes per iteration past it. Verbatim vpo_intr + imm_do_scsi (sha256-attested extract, scripted malicious peripheral at the ppbus boundary): cdb_len=255 clocked 256 bytes, of which 240 were past cdb_bytes[15] -- the first 8 leaked bytes were csio->msg_ptr (a real kernel pointer field immediately after cdb_io in struct ccb_scsiio), followed by msg_len/tag_action and adjacent heap. Control cdb_len=16: 0 OOB. Fixed model (clamp to IOCDBLEN): 0 OOB. Reachability: root/operator with a pass(4) device on vpo(4) plus a malicious parallel-port peripheral (physical channel), as filed.