SCSI CDB heap buffer overflow past orb[7] into ind_ptr on 16-byte CDBs
Summary
sbp_action1 copies SCSI CDB into SBP-2 ORB starting at orb[5] using csio->cdb_len as length but ORB only reserves 12 bytes (orb[5] through orb[7]). CAM_MAX_CDBLEN is 16 so any 16-byte SCSI command overflows 4 bytes past orb[7] into ind_ptr[0].hi. Via pass driver cdb_len up to 255 writing up to 243 bytes into ind_ptr page-table region DMA-coherent memory visible to FireWire device. Impact limited overflow stays within ind_ptr[128] array cannot reach sdev/flags/dmamap fields. For single-segment transfers ind_ptr unused corruption inert. [VERIFIED pass2: reproduced - 16-byte CDB bcopy writes bytes 12-15 into ind_ptr 0 hi 0xcfcecdcc of the DMA-coherent ocb; clamp-12 fix A/B canary intact]
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-2515 Β· 8 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 991 B | β raw | |
| VERDICT.md | β | 1.8 KB | β raw | |
| build.sh | β | 99 B | view raw | |
| run.log | β | 426 B | view raw | |
| env.txt | β | 963 B | view raw | |
| fix.diff | β | 771 B | view raw | |
| manifest.json | β | 760 B | view raw | |
| verdict.json | β | 2.0 KB | view raw |
DF-2515 -- SCSI CDB copy overflows orb[7] into ind_ptr on 16-byte CDBs
Verification used the shared rig tree at /root/rigs on the audit guest (see manifest). The rig for this finding: dfv_sbp (rig.c = harness, gen.sh = verbatim extractor, dfv_*_extract.h = generated production text). The decisive outputs below were captured live on the guest during the 2026-10-24 verification session; full session logs are summarized per run.
Build
sh build.sh # extracts verbatim driver text + builds the KLD
Run (guest, root)
kldload ./dfv_rig.ko
kldload dfv_sbp.ko; sysctl kern.dfv_sbp_run=0; sysctl -n kern.dfv_sbp_status; sysctl kern.dfv_sbp_run=1; sysctl -n kern.dfv_sbp_status
Expected
run.log: ind_ptr[0]=cfcecdcc/dddddddd with 16B CDB (canary cccccccc/dddddddd); control clean; fixed clean.
Fix validation
fix.diff clamps the copy to 12 bytes with a log line; A/B canary intact.
Verdict: reproduced / impact=limited_write (see verdict.json, VERDICT.md)
DF-2515 verdict -- SCSI CDB copy overflows orb[7] into ind_ptr on 16-byte CDBs
status: reproduced reproduced: 1 impact: limited_write confidence: certain attempts: 1 runtime_sec: 700
The verbatim sbp_action1 copies the CDB with bcopy(cdb, &ocb->orb[5], csio->cdb_len) (sbp.c:2337); the ORB reserves 12 bytes (orb[5..7]) and struct sbp_ocb places ind_ptr immediately after orb[8] (sbp.c:141-152). With a 16-byte CDB (CAM_MAX_CDBLEN; pass(4) allows cdb_len up to 255) the verbatim copy wrote ind_ptr[0].hi = 0xcfcecdcc - CDB bytes 12..15 overwriting the page-table pointer field on the DMA-coherent ocb, visible to the FireWire device. Control (12-byte CDB): canary intact. Fixed source (clamp to 12, log) A/B: 16-byte CDB leaves the canary intact.
Evidence (decisive lines)
DF2515[cdblen=12]: orb[5]=c0c1c2c3 orb[6]=c4c5c6c7 orb[7]=c8c9cacb DF2515: ind_ptr[0]=cccccccc/dddddddd ... RESULT=clean DF2515[cdblen=16]: ind_ptr[0]=cfcecdcc/dddddddd (canary was CCCCCCCC/DDDDDDDD) DF2515: RESULT=OVERFLOW (cdb_len>12 spills into ind_ptr[0].hi on the DMA-coherent ocb) --- fixed source A/B --- DF2515[cdblen=16]: ind_ptr[0]=cccccccc/dddddddd ... RESULT=clean (dmesg: "sbp: CDB too long for ORB, clamped")
Exploit chain / privesc assessment
FireWire-attached hostile initiator (or pass(4) with cdb_len>12): 4+ bytes of device-visible DMA memory corruption inside the ocb; stays within the allocation as filed.
Fix + A/B
fix.diff clamps the copy to 12 bytes with a log line; A/B canary intact.
Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest make -j6 nativekernel KERNCONF=X86_64_GENERIC completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
Fix verification
fixedConfirmed kernel references
Detail
Exploit chain
FireWire-attached hostile initiator (or pass(4) with cdb_len>12): 4+ bytes of device-visible DMA memory corruption inside the ocb; stays within the allocation as filed.
Evidence (decisive lines)
run.log: ind_ptr[0]=cfcecdcc/dddddddd with 16B CDB (canary cccccccc/dddddddd); control clean; fixed clean.
PoC changes
struct/define block extracted verbatim (sbp.c:63-292); transport interposed.
Verified recommended fix
clamp the CDB copy into orb[5..7] to 12 bytes
Verdict
The verbatim sbp_action1 copies the CDB with bcopy(cdb, &ocb->orb[5], csio->cdb_len) (sbp.c:2337); the ORB reserves 12 bytes (orb[5..7]) and struct sbp_ocb places ind_ptr immediately after orb[8] (sbp.c:141-152). With a 16-byte CDB (CAM_MAX_CDBLEN; pass(4) allows cdb_len up to 255) the verbatim copy wrote ind_ptr[0].hi = 0xcfcecdcc - CDB bytes 12..15 overwriting the page-table pointer field on the DMA-coherent ocb, visible to the FireWire device. Control (12-byte CDB): canary intact. Fixed source (clamp to 12, log) A/B: 16-byte CDB leaves the canary intact.
No comments yet.