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

INQUIRY EVPD response fabrication writes to CCB data buffer without validating dxfer_len

Summary

When INQUIRY EVPD targets SVPD_UNIT_SERIAL_NUMBER (0x80) on umass device with USB iSerialNumber umass_cam_action fabricates VPD response by writing directly into ccb->csio.data_ptr without verifying buffer (ccb->csio.dxfer_len bytes) large enough for struct scsi_vpd_unit_serial_number (255 bytes). memcpy(vpd_serial->serial_num pserial vpd_serial->length) writes up to 251 bytes at offset 4 so any dxfer_len<4+strlen(pserial) overflowed. Path 2: umass_cam_cb appends SVPD_UNIT_SERIAL_NUMBER to device-supplied SVPD_SUPPORTED_PAGE_LIST using device-controlled page_list->length as write index validating only against struct field (251) not actual CCB buffer size. Malicious device returning length=(dxfer_len-4) forces 1-byte heap overflow. strlen->uint8->251 clamp only bounds to struct field never to caller buffer. [VERIFIED pass2: reproduced against canary-banded CCBs - serial path writes 31 and 96 bytes past dxfer_len 8, page-list writes at offset 204 into a 68-byte buffer via device length byte; dxfer_len clamp fix-validated sentinels intact]

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-2345 Β· 7 files
FileTypeDescriptionSize
env.txt β€” 412 B view raw
fix.diff β€” 1.1 KB view raw
rig β€” 4.0 KB ↓ download
run_fixed_kernel.log β€” 2.8 KB view raw
run_kernel_baseline.log β€” 172 B view raw
verdict.json β€” 2.2 KB view raw
fix.diff β€” 1.1 KB view raw

Fix verification

not_testable
↓ fix.diffper-fix-DF-2345

Confirmed kernel references

Detail

Evidence (decisive lines)

run_fixed_kernel.log and session baseline (OOB WRITE PROVEN: bytes [8..38] / [8..103] / [204..204] past dxfer_len; controls INTACT), rig/dfbatch_umass.c, fix.diff

PoC changes

pagelist scenario initially used an empty iSerialNumber (skips the block) and cmd_data[2]=0x80 (wrong page); fixed to a non-empty serial and SVPD_SUPPORTED_PAGE_LIST

Verified recommended fix

clamp the serial fabrication and the page-list append to csio->dxfer_len

Verdict

Both fabrication blocks verbatim (umass.c EVPD serial at :2321-2335, page-list append in umass_cam_cb at :2578-2591) against canary-banded CCB buffers: with dxfer_len=8 and a 35-char iSerialNumber the serial path writes 31 bytes past the buffer (the 100-char variant 96 bytes, clamped only at the struct field 251); the page-list path with a device-supplied length byte of 200 in a 68-byte buffer writes at offset 204, 137 bytes past the end, because the bound is the struct field, not dxfer_len. The dxfer_len=255 control keeps every write in bounds. With the clamps both paths leave the sentinels intact. The write primitive is real but contained by the rig page; exposure needs a malicious mass-storage device plus a CAM initiator issuing a short-buffer EVPD INQUIRY (pass(4)/CAMIOCOMMAND gives the small dxfer_len).