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)
PoC verification
Evidence pack
findings/poc/DF-2345 Β· 7 files| File | Type | Description | Size | |
|---|---|---|---|---|
| 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_testableConfirmed 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).
No comments yet.