mprsas_send_abort/mprsas_send_reset early -1 returns are ignored by every caller: targ->tm stays set forever, the timed-out CCB is never completed (unkillable I/O hang) and the high-priority TM leaks
Summary
When targ->handle == 0, mprsas_send_abort and mprsas_send_reset return -1 without freeing the TM or clearing targ->tm. All callers ignore the return. Since only TM completion handlers clear targ->tm and the TM was never sent, it never completes: subsequent timeouts pile into timedout_commands forever and the triggering ccb is never returned to CAM. Reachable because mprsas_remove_volume clears targ->handle without draining targ->commands, unlike mprsas_remove_device. Hot removal/volume deletion racing command timeouts (normal storage-box events): the issuing thread blocks forever on I/O that can never complete and each wedge leaks one high-priority command. Hardware-gated; fix.diff unwinds the -1 path + drains.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-3802 Β· 7 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 211 B | β raw | |
| VERDICT.md | β | 3.1 KB | β raw | |
| run.sh | β | 111 B | view raw | |
| env.txt | β | 855 B | view raw | |
| fix.diff | β | 1.9 KB | view raw | |
| verdict.json | β | 2.2 KB | view raw | |
| manifest.json | β | 464 B | view raw |
DF-3802 evidence pack
TM early-return -1 paths wedge the target (targ->tm stuck, timedout ccbs never
completed) and leak the TM. Read VERDICT.md. verdict.json: not_reproduced
(no SAS3 hardware on guest).
DF-3802 β TM error-path early returns wedge the target forever and leak the TM
- File:
sys/dev/raid/mpr/mpr_sas.c - Class: unkillable I/O hang (ccb never completed) + high-priority command leak
- Severity: Medium / Confidence: likely
- Status on guest: not_reproduced β no SAS3 HBA (see
env.txt)
Defect
mprsas_send_abort and mprsas_send_reset have early -1 return paths that
neither free the task-management command nor clear targ->tm:
mpr_sas.c:1609-1615βsend_abort:targ = cm->cm_targ; if (targ->handle == 0) return -1;mpr_sas.c:1456-1461βsend_reset:if (target->handle == 0) ... return -1;mpr_sas.c:1489-1492βsend_reset: unknown type βreturn -1
Every caller ignores the return value:
mpr_sas.c:1731(mprsas_scsiio_timeout:targ->tm = mprsas_alloc_tm(sc); ... mprsas_send_abort(sc, targ->tm, cm);)mpr_sas.c:1351,mpr_sas.c:1584(mprsas_send_abortre-arm fromlogical_unit_reset_complete/abort_complete)mpr_sas.c:1365,mpr_sas.c:1594(mprsas_send_resetescalation)
After the early return:
targ->tmremains set forever (only the TM completion handlers clear it βmpr_sas.c:1307/1353/1403/1431/1553/1578β and the TM was never sent, so it never completes;mprsas_free_tmis never called).- The timed-out command stays on
targ->timedout_commandsin stateMPR_CM_STATE_TIMEDOUTwith its ccb never completed β once a ccb is in the SIM, CAM has no further timeout for it; the issuing thread hangs forever. - Every subsequent timeout on the target takes the
targ->tm != NULLpath (mpr_sas.c:1716-1722) and piles more never-aborted commands. - The allocated high-priority command leaks (pool shrink under repetition).
Reachable trigger (provable sequence)
Outstanding I/O to a RAID volume that is deleted:
mprsas_prepare_volume_removesends the reset TM (mpr_sas.c:439-490), butmprsas_remove_volumeclearstarg->handle = 0on success (mpr_sas.c:411-429) without drainingtarg->commandsβ unlikemprsas_remove_device, which completes them (mpr_sas.c:621-628).- Any command still on
targ->commandsthat times out afterwards runsmprsas_scsiio_timeoutβ allocatestarg->tmβmprsas_send_abortseestarg->handle == 0β returns-1β wedge + leak, per above.
The same wedge occurs mid-error-recovery when the handle is cleared while a
recovery TM exists (abort escalation at mpr_sas.c:1584/1594).
Fix
Handle the -1 returns: free the TM, clear targ->tm, and complete the
timed-out ccbs with CAM_DEV_NOT_THERE; also drain targ->commands in
mprsas_remove_volume like mprsas_remove_device does. See fix.diff.
Guest verification
No SAS3 controller in the guest; no mpr SIM registered β the sequence cannot
run. Static proof stands. See env.txt.
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_testablefix.diff authored from line-accurate analysis; not exercisable on this guest.
findings/poc/DF-3802/fix.diff
Confirmed kernel references
Detail
Evidence (decisive lines)
VERDICT.md (path:line proof incl. remove_volume asymmetry), env.txt, fix.diff
PoC changes
Trigger needs real SAS3 hardware with a failing/removed device racing CAM timeouts.
Verified recommended fix
On the -1 paths, clear targ->tm, free the TM, and complete queued timedout commands with CAM_DEV_NOT_THERE; drain targ->commands in mprsas_remove_volume.
Verdict
mprsas_send_abort (mpr_sas.c:1609-1615) and mprsas_send_reset (mpr_sas.c:1456-1461,1489-1492) return -1 on a zero dev handle without freeing the TM or clearing targ->tm; all callers (mpr_sas.c:1351,1365,1584,1594,1731) ignore the return. The TM never completes, so targ->tm is never cleared (only completion handlers clear it), every later timeout on the target queues into timedout_commands forever (mpr_sas.c:1716-1722), and the triggering ccb is never returned to CAM β an unkillable I/O hang plus a high-priority-command leak. Provable trigger: mprsas_remove_volume clears targ->handle (mpr_sas.c:414) without draining targ->commands (unlike mprsas_remove_device at mpr_sas.c:621-628), so outstanding volume I/O that times out afterwards hits the -1 path. Not reproduced: guest has no SAS3 HBA (env.txt); mpr SIM never attaches.
No comments yet.