mprsas_fw_work IR-event early return leaks fw_event allocation and strands the startup refcount (discovery can never complete)
Summary
On mpr_alloc_command failure the IR_CONFIGURATION_CHANGE_LIST case returns without the startup decrement or the fw_event free: the allocations leak per event and the refcount never drops to 0, freezing discovery completion (simq); the leak amplifies the command-pool exhaustion that triggers it. Decrement+free fix (compile-validated).
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-4252 Β· 10 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 1.7 KB | β raw | |
| VERDICT.md | β | 1.6 KB | β raw | |
| build.log | β | 7.4 KB | view raw | |
| build.sh | β | 65 B | view raw | |
| env.txt | β | 588 B | view raw | |
| fix.diff | β | 806 B | view raw | |
| run.log | β | 425 B | view raw | |
| run.sh | β | 89 B | view raw | |
| trigger.sh | β | 285 B | view raw | |
| verdict.json | β | 1.9 KB | view raw |
DF-4252 β mprsas_fw_work IR-event early return leaks the fw_event and the startup refcount
Where
sys/dev/raid/mpr/mpr_sas_lsi.c:327-331 (MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST
case):
if ((cm = mpr_alloc_command(sc)) == NULL) {
kprintf("%s: command alloc failed\n", __func__);
return; /* <-- leaks */
}
mprsas_fw_work frees the event only at its tail (:780
mprsas_fw_event_free), and the IR case drops the startup refcount only at
:455 (mprsas_startup_decrement). The early return skips both.
What
fw_event+fw_event->event_data(kmalloc'd inmprsas_evt_handler:142-156) leak on every occurrence.- The startup refcount taken in
mprsas_evt_handler(:170-174, wheneverwait_for_port_enableis set β every boot-time discovery) is never dropped:startup_refcountcan never reach 0 β discovery-completion callbacks (simq release, mprsas_startup_decrement side effects at mpr_sas.c:204-226) never fire for this event β CAM queue stays frozen / boot hangs until thempr_detach_sas/reinit forced-drain loops (mpr_sas.c:941-942) run. - Command-pool exhaustion (which triggers this) is most likely precisely during an IR config-change event storm β the leak then amplifies the exhaustion (each leaked fw_event holds pool pressure).
Trigger
mpr(4) HBA in IR mode, IR_CONFIGURATION_CHANGE_LIST event with Hide/PD-Created reason while the command pool is empty (heavy I/O + event storm). Hardware-gated.
Fix
fix.diff β on alloc failure do what the normal path would have done:
decrement the refcount, free the event, then return.
Build/run
build.log β compile-validated on the audit guest.
DF-4252 VERDICT
status: untested (hardware-gated: no mpr HBA on the audit guest) impact class: dos + memory leak confidence: certain (error-path trace)
Trace
- mpr_sas_lsi.c:142-156 β
mprsas_evt_handlerallocates fw_event + event_data. - :170-174 β for IR_CONFIG_CHANGE_LIST with
wait_for_port_enable,mprsas_startup_increment(sassc)(refcount +1). - :274-457 β
mprsas_fw_workIR case: :327-331 earlyreturnwhenmpr_alloc_commandfails, skipping BOTH the :455mprsas_startup_decrement(sassc)and the :780mprsas_fw_event_free(sc, fw_event). - mpr_sas.c:178-226 β refcount 0 is what unfreezes the simq and completes
startup; a stranded +1 keeps
MPRSAS_IN_STARTUPhandling pending until a forced drain (reinit at mpr_sas.c:941-942 or detach).
Consequences: (a) kernel memory leak per failed event, (b) discovery/ startup completion can hang, (c) leak rate correlates with command-pool pressure (the same condition that triggers it), compounding pool exhaustion β mps(4) twin of the DF-4015 family pattern.
Fix (fix.diff): decrement + free before the early return. Compile-validated on the guest (build.log). fix_status: not_testable (runtime needs HBA + pool exhaustion during an IR event).
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_testable at runtime; compile-validated (decrement+free before return).
build.log: patched module builds clean.
Confirmed kernel references
Detail
Evidence (decisive lines)
VERDICT.md refcount trace; build.log compile-validation.
PoC changes
n/a - pass-2 finding; trigger documentation written fresh (hardware-gated, no seed PoC existed)
Verified recommended fix
decrement startup refcount + free fw_event before early return
Verdict
mprsas_fw_work IR_CONFIGURATION_CHANGE_LIST case returns early at :330 when mpr_alloc_command fails, skipping both mprsas_startup_decrement (:455) and mprsas_fw_event_free (:780): the fw_event+event_data allocations leak and the startup refcount taken in mprsas_evt_handler (:170-174) never drops, so discovery completion can hang (simq stays frozen) until a forced drain; leak amplifies the very pool exhaustion that triggers it (DF-4015-family pattern, mpr side).
No comments yet.