ABTS RX_ID bound check uses IOC mpt_max_tgtcmds instead of actual tgt_cmd_ptrs array size (OOB read in FC target mode)
Summary
In mpt_fc_els_reply_handler ABTS path RX_ID (16-bit field from remote FC initiator ABTS frame) validated against mpt->mpt_max_tgtcmds but tgt_cmd_ptrs array is only min(MPT_MAX_REQUESTS/2 mpt_max_tgtcmds)=min(256 mpt_max_tgtcmds) entries wide. When IOC reports MaxPostedCmdBuffers>256 RX_ID values [256 mpt_max_tgtcmds) pass check but index past allocated array OOB read whose result dereferenced as request_t pointer. mpt_max_tgtcmds is port_facts MaxPostedCmdBuffers U16 IOC can report above 256. IOC-input router mpt.c:765 correctly bounds with tgt_cmds_allocated this FC ELS handler does not. Niche target-mode + MaxPostedCmdBuffers>256. [VERIFIED pass2: reproduced - rx_id 300 passes the 512 check against the 256-entry array, OOB-read pointer drives MPT_TGT_STATE control flow proven by mismatch log; guard fix rejects]
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-2537 Β· 6 files| File | Type | Description | Size | |
|---|---|---|---|---|
| rig.c | β | 6.1 KB | view raw | |
| gen.sh | β | 435 B | view raw | |
| Makefile | β | 180 B | β download | |
| build.sh | β | 93 B | view raw | |
| run.sh | β | 90 B | view raw | |
| run.log | β | 933 B | view raw |
Fix verification
not_testableConfirmed kernel references
Detail
Evidence (decisive lines)
mpt2537_run.log mode 0: mismatch log proving the OOB-read pointer was dereferenced; mode 2 fixed guard rejects
PoC changes
verbatim ABTS-branch extract driven with a real mpt_softc + groomed adjacent heap; logging interposed only
Verified recommended fix
use mpt->tgt_cmds_allocated for the rx_id bound at mpt_cam.c:3004
Verdict
mpt_fc_els_reply_handler (mpt_cam.c:3004-3009) bounds the ABTS RX_ID against the IOC-reported mpt->mpt_max_tgtcmds (port_facts[0].MaxPostedCmdBuffers) while tgt_cmd_ptrs is only min(256, max_tgtcmds) entries (mpt_cam.c:4250-4256, MPT_MAX_REQUESTS=512). Verbatim ABTS branch (sha256-attested): with MaxPostedCmdBuffers=512 and a 256-entry array, rx_id=300 passed the check and tgt_cmd_ptrs[300] (352 bytes past the 2048-byte allocation) returned the groomed fake request_t; the verbatim code then dereferenced it via MPT_TGT_STATE and logged ABORT Mismatch: RX_ID received=0x12c; RX_ID in cmd=0x3eef -- the OOB-read pointers contents drove kernel control flow. Control rx_id=100 behaved in-bounds; fixed guard (check tgt_cmds_allocated) rejected. Niche: FC target mode + an IOC (or malicious FC initiator forging ABTS replies is not possible -- this is IOC input) reporting >256; impact is kernel memory corruption potential in a storage driver, gated on hardware we do not have -- hence impact none beyond the demonstrated read+deref.
No comments yet.