mfi_intr bounds reply-queue contexts by mfi_max_fw_cmds but mfi_commands[] is allocated MIN(128, mfi_max_fw_cmds) -> OOB command object under firmware misbehavior
Summary
The validation uses sc->mfi_max_fw_cmds, but sc->mfi_commands is kmalloc'd with ncmds = MIN(128, mfi_max_fw_cmds). On controllers reporting max_fw_cmds>128, a reply context in [mfi_total_cmds, mfi_max_fw_cmds) indexes past the array; mfi_remove_busy performs TAILQ surgery and mfi_complete calls cm->cm_complete through out-of-bounds memory (heap corruption). Only fires if the device posts a context the driver never issued. Correct-bound one-token fix.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-3875 Β· 6 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 1.2 KB | β raw | |
| VERDICT.md | β | 964 B | β raw | |
| fix.diff | β | 349 B | view raw | |
| manifest.json | β | 646 B | view raw | |
| verdict.json | β | 1.1 KB | view raw | |
| env.txt | β | 283 B | view raw |
DF-3875 β mfi_intr bounds reply-queue contexts by mfi_max_fw_cmds, but mfi_commands[] is sized mfi_total_cmds
mfi.c:1227-1234:
while (ci != pi) {
context = sc->mfi_comms->hw_reply_q[ci];
if (context < sc->mfi_max_fw_cmds) { /* WRONG bound */
cm = &sc->mfi_commands[context];
mfi_remove_busy(cm);
cm->cm_error = 0;
mfi_complete(sc, cm);
Allocation (mfi.c:758-786): ncmds = MIN(mfi_max_cmds=128, mfi_max_fw_cmds)
sc->mfi_commands = kmalloc(sizeof(struct mfi_command) * ncmds) and
mfi_total_cmds ends at ncmds, while frames/sense arrays are sized
mfi_max_fw_cmds. On controllers reporting max_fw_cmds > 128 (common), any
reply context in [mfi_total_cmds, mfi_max_fw_cmds) β written by the device
into the DMA reply queue β indexes past mfi_commands[]: mfi_remove_busy then
performs TAILQ list surgery on out-of-bounds memory (heap corruption), and
mfi_complete calls through a garbage cm_complete pointer.
Well-behaved firmware only replies with issued contexts (< mfi_total_cmds),
so this is a robustness hole against a faulty/hostile controller (same trust
boundary as DF-3874). Correct bound: sc->mfi_total_cmds.
DF-3875 VERDICT β inconclusive (hardware-gated), speculative
- Mismatch verified: bound at mfi.c:1229 uses mfi_max_fw_cmds; array allocated with MIN(128, max_fw_cmds) at mfi.c:758/763; mfi_total_cmds is the true issued-context count (mfi.c:785, used correctly in mfi_free at :1081).
- Only manifests if the device (or a DMA-capable attacker) posts a context the driver never issued -> not reachable by unprivileged users on healthy HW.
- Impact if it fires: heap corruption via TAILQ ops + indirect call through OOB cm β hence worth fixing even though speculative.
- fix.diff: one-token bound change.
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
not_testabletrivial bound fix; not validatable without HW
fix.diff
Confirmed kernel references
Detail
Evidence (decisive lines)
VERDICT.md; mfi.c:1229 vs :758-785
PoC changes
no runnable PoC
Verified recommended fix
bound context by sc->mfi_total_cmds
Verdict
Reply-queue contexts are bounds-checked against mfi_max_fw_cmds while mfi_commands[] holds only MIN(128,max_fw_cmds) entries; a firmware-posted context in between indexes OOB (list surgery + indirect call). Requires misbehaving controller; not user-reachable; fix is a one-token bound change.
No comments yet.