mpssas_add_device/mpssas_volume_add re-initialize a target slot without checking the asynchronous removal is still in flight (INREMOVAL flag cleared under an outstanding TM; TAILQ_INIT over possibly-linked command lists)
Summary
prepare_remove only starts an async removal; add_device unconditionally clears flags and re-inits the command lists on the same slot - a re-add event inside the removal window clears INREMOVAL under an outstanding TM and orphans linked commands; the completion's TAILQ_REMOVE then writes through stale tqe_prev pointers. Not covered by DF-3895/3898; filed speculative per pass-2 lifetime discipline (needs real HBA event timing). Bail-EBUSY guard sketch.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-4562 Β· 4 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 2.6 KB | β raw | |
| fix.diff | β | 1.3 KB | view raw | |
| VERDICT.md | β | 1.8 KB | β raw | |
| verdict.json | β | 2.5 KB | view raw |
DF-4562 β mpssas_add_device re-initializes a target that may still be in
removal / have in-flight commands (speculative list-corruption race)
File: `sys/dev/raid/mps/mps_sas_lsi.c:580-682 (sink :653-670), interaction with :212-219/:328-346/:394-395 Severity: Low (speculative), Status:** untested β needs an mps HBA to create the event interleaving; filed as a labeled speculation per pass-2 discipline (lifetimes/error-path interactions), adjacent to the already-filed DF-3895/DF-3898 removal-path defects.
The hypothesis
All fw events are processed serialized on ev_tq under mps_lock
(mps_sas_lsi.c:564-577), but mpssas_prepare_remove() only starts an
asynchronous removal: it sets MPSSAS_TARGET_INREMOVAL, sends a TM
TARGET_RESET, and the removal finishes later in completion callbacks
(mps_sas.c:407-466). If a TARG_ADDED / PD_DELETED event for the same (or a
colliding-ID) device is processed before that removal completes,
mpssas_add_device() unconditionally overwrites the target slot
(mps_sas_lsi.c:653-670):
targ->flags = 0clearsMPSSAS_TARGET_INREMOVALwhile the TM is still outstanding (targ->tmstill points at it);TAILQ_INIT(&targ->commands)/TAILQ_INIT(&targ->timedout_commands)orphan any still-linked commands β theirtqe_prevstill point into the (now reset) head or into each other, so the completion path'sTAILQ_REMOVEwrites through stale pointers into the new list head (list corruption; lost/leaked commands);- the failure branch at :212-219 itself calls
mpssas_prepare_remove()on a just-failed add of the same handle, interleaving two removals on one slot.
mpssas_volume_add() (:847-853) has the same shape (no INREMOVAL /
non-empty-list check before TAILQ_INIT).
Why speculative
Triggering requires a specific firmware-event interleaving (removal not yet completed when the re-add for the same target ID is processed) that cannot be produced on the QEMU guest (no mps controller). The list mechanics above are how TAILQ behaves, but the existence of the interleaving window in the field is unproven; pass-1 findings DF-3895 / DF-3898 cover neighboring removal-lifetime defects, so this is recorded as the remaining uncovered edge rather than a demonstrated primitive.
Suggested hardening (defensive; also collapses this window)
In mpssas_add_device / mpssas_volume_add, before overwriting the slot:
bail out (EBUSY) if targ->handle != 0 && (targ->flags &
MPSSAS_TARGET_INREMOVAL || !TAILQ_EMPTY(&targ->commands) ||
!TAILQ_EMPTY(&targ->timedout_commands) || targ->tm != NULL) β see
fix.diff sketch.
DF-4562 VERDICT β untested (speculative), Low, target-slot re-init race
Bottom line
Speculative, labeled as such. mpssas_add_device()
(sys/dev/raid/mps/mps_sas_lsi.c:653-670) and mpssas_volume_add()
(:847-853) overwrite/TAILQ_INIT a target slot without checking
MPSSAS_TARGET_INREMOVAL / outstanding commands / targ->tm. Removal is
asynchronous (TM TARGET_RESET started in mpssas_prepare_remove,
mps_sas.c:449-466); a re-add event processed before the removal completes
would clear the flag under an outstanding TM and re-init lists that may
still be linked, corrupting the new list through stale tqe_prev
pointers on the completion path.
Why not verified
The interleaving requires a real mps HBA delivering a re-add event inside the removal window; the QEMU guest has no such hardware, and unlike DF-4559/DF-4560 there is no deterministic arithmetic to replicate β the claim is about event timing, not address math. Honest status: untested. Filed (speculative) because pass-2 exists exactly for lifetime/error-path interactions, and the neighboring removal defects DF-3895/DF-3898 do not cover this sink.
Impact if real
List corruption / lost commands on the storage path of one adapter β availability-grade (DoS), possibly worse if the orphaned command blocks are later double-completed. Not demonstrated.
Recommended fix
Guard in add paths (see README): refuse to re-init a slot that is
INREMOVAL, has non-empty command lists, or an outstanding tm.
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_testablenot_applicable (speculative finding, no reproducer)
README.md hardening sketch.
Confirmed kernel references
Detail
Evidence (decisive lines)
VERDICT.md and README.md contain the full path:line trace of the interleaving hypothesis; no runtime artifacts (no hardware).
PoC changes
No PoC possible on the available guest; filed as a labeled speculative pass-2 lifetime finding.
Verified recommended fix
Guard target-slot re-initialization in mpssas_add_device/mpssas_volume_add against in-flight removal (INREMOVAL flag, non-empty command lists, outstanding tm).
Verdict
SPECULATIVE, untested (needs a real mps HBA to produce the event interleaving; the QEMU guest has none, and unlike DF-4559/DF-4560 there is no deterministic arithmetic to replicate β the claim is about event TIMING). mpssas_add_device (mps_sas_lsi.c:653-670) and mpssas_volume_add (:847-853) overwrite/TAILQ_INIT a target slot without checking MPSSAS_TARGET_INREMOVAL, outstanding commands, or targ->tm, while mpssas_prepare_remove's removal is asynchronous (TM TARGET_RESET completes later, mps_sas.c:449-466). A re-add event processed inside the removal window would clear INREMOVAL under an outstanding TM and re-init possibly-still-linked lists; completion-path TAILQ_REMOVE would then write through stale tqe_prev pointers into the re-initialized head. Adjacent to (not covered by) DF-3895/DF-3898. If real: list corruption / lost commands β availability-grade.
No comments yet.