sc->map_update_cmd is never cleared: shutdown aborts a recycled pooled mfi command (stale handle β wrong-command abort)
Summary
sc->map_update_cmd is assigned exactly once and cleared nowhere in the driver. All three release paths for the map-sync mfi command return it to the shared 32-entry pool without nulling the pointer. mrsas_shutdown_ctlr then issues the abort on the recycled slot, and the abort frame is built from the command's current index/frame_phys_addr, so the firmware aborts whatever unrelated in-flight ioctl passthrough or internal DCMD now occupies it - its waiter receives a spurious abort completion. Shutdown-time cross-command abort of an unrelated management/ioctl command (wrong status delivered to a bystander). Indices stay in-bounds and pooled objects are permanent allocations, so impact is logic confusion, not wild memory access. Clear-handle-at-every-release fix.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-3846 Β· 7 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 1.2 KB | β raw | |
| VERDICT.md | β | 3.2 KB | β raw | |
| run.log | β | 90 B | view raw | |
| env.txt | β | 260 B | view raw | |
| fix.diff | β | 1.8 KB | view raw | |
| manifest.json | β | 777 B | view raw | |
| verdict.json | β | 2.8 KB | view raw |
DF-3846 β sc->map_update_cmd never cleared: dangling pooled command aborted at shutdown
sc->map_update_cmd is set only in mrsas_sync_map_info() (mrsas.c:3239) and cleared nowhere.
The map-sync mfi command is released to the shared pool at mrsas.c:2953 (NOT_FOUND failure β
no follow-up sync), mrsas.c:2960 (normal completion), and mrsas.c:2454 (OCR re-fire loop),
always leaving the pointer dangling. mrsas_shutdown_ctlr() (mrsas.c:3041-3042) then issues
mrsas_issue_blocked_abort_cmd() on the recycled slot β the firmware aborts whatever command
now occupies that index/frame (an unrelated in-flight ioctl or internal DCMD) β spurious abort
completion for a bystander command at shutdown.
Impact: wrong-command abort / status confusion; indices in-bounds; no wild write. Low severity, hardware-gated.
Reproduce
Needs an attached MegaRAID HBA that completes (or NOT_FOUND-fails) a map sync plus a later
shutdown after the 32-entry mfi pool recycled the slot. Guest has mrsas compiled in but no
LSI device / /dev/mrsas* (run.log) β path unreachable in the VM.
Files
VERDICT.md,run.log,env.txt,fix.diff,manifest.json,verdict.json
VERDICT β DF-3846 (sc->map_update_cmd never cleared: dangling pooled command aborted at shutdown)
status: inconclusive (hardware-gated; dangling-pointer structure source-certain) confidence: certain (lifetime defect at source level) Β· class: stale-handle / cross-command abort (logic confusion; in-bounds indices)
The defect (source)
sc->map_update_cmd is assigned once β mrsas_sync_map_info(), mrsas.c:3239 β and cleared
nowhere (grep across mrsas*.c: only writers are 3239; only reader is mrsas_shutdown_ctlr,
mrsas.c:3041-3042).
Every completion path for a RAID-map sync command returns the mfi command to the free pool
without touching sc->map_update_cmd:
mrsas_complete_mptmfi_passthru()map branch, success/normal:mrsas_release_mfi_cmd(cmd)at mrsas.c:2960 (and the map_id++ path re-issues a new sync which re-points it at 3239 β but only when a new sync actually fires);- map-sync failed
MFI_STAT_NOT_FOUND:mrsas_release_mfi_cmd(cmd)at mrsas.c:2953 thenbreakβ no new sync is issued, sosc->map_update_cmdis left dangling to a command that is now on the free list; mrsas_reset_ctrl()re-fire loop: forMR_DCMD_LD_MAP_GET_INFOopcodes it doesmrsas_release_mfi_cmd(mfi_cmd); mrsas_release_mpt_cmd(mpt_cmd);at mrsas.c:2454-2455 β again leavingsc->map_update_cmdpointing at the released command.
Consequence
At detach/shutdown, mrsas_shutdown_ctlr() (mrsas.c:3038-3042) does:
if (sc->map_update_cmd)
mrsas_issue_blocked_abort_cmd(sc, sc->map_update_cmd);
mrsas_issue_blocked_abort_cmd (mrsas.c:3465-3517) builds the abort frame from
cmd_to_abort->index and cmd_to_abort->frame_phys_addr (mrsas.c:3486-3488). If the pooled
command has been recycled in the meantime (its 32-entry pool is shared by all internal and
ioctl passthrough traffic), the firmware is asked to abort whatever command now occupies
that index/frame β an in-flight ioctl passthrough of another thread or an internal DCMD.
That command's waiter receives a spurious abort completion (mrsas_complete_abort /
mrsas_wakeup), i.e. an unrelated management command fails at shutdown time. All indices
remain in-bounds; the pooled objects are permanent allocations, so this is a stale-handle
logic defect (wrong-command abort / status confusion), not a wild memory access β hence
Low severity.
Why not reproduced on the guest
Requires an attached MegaRAID controller that completes (or fails with NOT_FOUND) a map sync
and then a shutdown during which the command slot was recycled. The guest has mrsas compiled
in but no LSI device (run.log). Source structure is certain: there is no clearing store to
sc->map_update_cmd anywhere in the driver.
Fix
fix.diff: null the pointer at all three release sites and re-check the command is still the
registered map-sync command before aborting at shutdown.
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 nulls the pointer at all three release sites; obviously removes the dangling consumer at mrsas.c:3041. Not boot-testable without the HBA -> not_testable.
fix.diff four hunks at the exact release/consumer lines.
Confirmed kernel references
Detail
Evidence (decisive lines)
VERDICT.md with the three uncleared release sites and the shutdown consumer; grep over mrsas*.c shows sc->map_update_cmd written only at mrsas.c:3239 and read only at mrsas.c:3041-3042.
PoC changes
No seed PoC; trigger requires an attached HBA completing a map sync and a later shutdown after pool recycling. Guest cannot reach the path.
Verified recommended fix
Clear sc->map_update_cmd whenever the map-sync mfi command is released (mrsas.c:2953, 2960, 2454) so shutdown can never abort a recycled command.
Verdict
Stale-handle lifetime defect: sc->map_update_cmd is assigned once in mrsas_sync_map_info (mrsas.c:3239) and never cleared anywhere in the driver. All three release paths for the map-sync mfi command return it to the shared 32-entry pool without nulling the pointer: the NOT_FOUND failure path (mrsas.c:2953, which issues no follow-up sync), the normal completion path (mrsas.c:2960), and the OCR re-fire loop (mrsas.c:2454-2455). mrsas_shutdown_ctlr (mrsas.c:3041-3042) later aborts whatever command now occupies that index/frame β after recycling this is an unrelated in-flight ioctl passthrough or internal DCMD of another thread, which receives a spurious abort completion. All indices stay in-bounds and pooled objects are permanent, so impact is wrong-command abort / status confusion at shutdown, not wild memory access (Low). Not executable on the audit guest: driver compiled in but no LSI HBA, no /dev/mrsas* (run.log); the structure of the defect (no clearing store exists) is source-certain.
No comments yet.