MFI_DCMD_LD_DELETE post-check assumes the volume still exists: AEN-driven deletion during the DCMD round-trip hits KASSERT('volume dissappeared')/NULL->ld_dev deref
Summary
mfi_check_command_post re-walks mfi_ld_tqh after the LD_DELETE DCMD completes and KASSERTs ld!=NULL then dereferences ld->ld_dev; the pre-check's existence guarantee is voided if the AEN task deletes the volume mid-roundtrip (decode_evt performs device_delete_child without mfi_config_lock). Release builds NULL-deref -> panic. The developer's own commented-out twin fix ('Fix: for kernel panics when SSCD is removed') proves this race class has panicked in the field. Replace-KASSERT-with-break fix.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-3877 Β· 6 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 1.4 KB | β raw | |
| VERDICT.md | β | 1.0 KB | β raw | |
| fix.diff | β | 520 B | view raw | |
| manifest.json | β | 651 B | view raw | |
| verdict.json | β | 1.2 KB | view raw | |
| env.txt | β | 283 B | view raw |
DF-3877 β MFI_DCMD_LD_DELETE pre/post-check race with AEN-driven volume deletion (KASSERT/NULL deref)
mfi_check_command_post (mfi.c:2624-2637) re-walks mfi_ld_tqh after the DCMD completes:
TAILQ_FOREACH(ld, &sc->mfi_ld_tqh, ld_link) {
if (ld->ld_id == cm->cm_frame->dcmd.mbox[0])
break;
}
KASSERT(ld != NULL, ("volume dissappeared"));
if (cmd_status == MFI_STAT_OK) {
... device_delete_child(sc->mfi_dev, ld->ld_dev); /* ld NULL deref */
The pre-check (mfi.c:2570-2579) verified the volume exists and disabled the
disk, but between pre and post the AEN task can remove it:
mfi_handle_evt -> mfi_decode_evt MR_EVT_ARGS_LD_STATE OFFLINE
(mfi.c:1494-1511) performs device_delete_child WITHOUT holding mfi_config_lock
(the io-protected detach at mfi_disk.c:189-191 blocks on io_lock, which the
post-check holds β the deletion lands between the DCMD round-trip windows).
When the volume is gone, ld == NULL:
- INVARIANTS kernels: KASSERT panic ("volume dissappeared" β the developer's
own comment at mfi.c:1503-1505 shows this exact class already panicked once
and was papered over in mfi_decode_evt);
- release kernels: ld->ld_dev / mfi_disk_enable(ld) NULL deref -> panic.
Operator-group trigger: race an LD_DELETE management ioctl against a volume going offline (or two paths that delete concurrently). Low: needs device access + event timing.
DF-3877 VERDICT β inconclusive (hardware-gated), speculative race
- Pre/post asymmetry verified (mfi.c:2570-2579 vs 2624-2637); the KASSERT text and the commented-out twin in mfi_decode_evt (mfi.c:1502-1505, "Fix: for kernel panics when SSCD is removed") evidence the race family is real.
- AEN deletion path takes no config lock (mfi.c:1494-1511) while the ioctl path serializes LD_DELETEs through mfi_config_lock (mfi.c:2530-2543) β cross-path serialization is missing.
- Requires an mfi adapter, operator access, and a volume-state transition racing the ioctl: cannot be exercised on the guest; speculative timing.
- fix.diff NULL-guards the post-walk result like the decode_evt twin.
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_testableguard fix; not validatable without HW
fix.diff
Confirmed kernel references
Detail
Evidence (decisive lines)
VERDICT.md
PoC changes
no runnable PoC (race + HW)
Verified recommended fix
NULL-guard ld in mfi_check_command_post like the decode_evt twin
Verdict
LD_DELETE pre-check validates the volume, post-check assumes it still exists and KASSERTs/derefs NULL when an AEN offline event removes it mid-DCMD; the driver's own commented-out twin fix (mfi.c:1502-1505) proves the pattern has panicked before. Race + operator access needed; guarded fix attached.
No comments yet.