XPT_RESET_DEV on the RAID physical-disk bus resets the WRONG device: phydisk id passed unmapped as a bus-0 TMF TargetID (hits the RAID volume sharing the number)
Summary
The raid_passthru mapping gate excludes XPT_RESET_DEV from mpt_map_physdisk(), so the raw phydisk-bus id (bus 1) reaches mpt_bus_reset, which sends the TMF on channel 0 where the same number denotes a RAID volume - 'reset this hidden disk' becomes 'TARGET_RESET of an unrelated volume', disrupting all its in-flight I/O. mpt_start() maps correctly for I/O, proving the omission. MPT RAID host: camcontrol reset of a physdisk pass node resets a whole volume - availability/data-integrity impact for that volume's in-flight commands.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-3677 Β· 6 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 648 B | β raw | |
| VERDICT.md | β | 3.1 KB | β raw | |
| fix.diff | β | 685 B | view raw | |
| env.txt | β | 281 B | view raw | |
| verdict.json | β | 1.8 KB | view raw | |
| manifest.json | β | 619 B | view raw |
DF-3677 β XPT_RESET_DEV on the RAID physical-disk bus resets the WRONG device (unmapped phydisk id sent as bus-0 TargetID)
Severity: Low (wrong-device TMF reset: in-flight volume I/O disrupted).
The raid_passthru mapping gate at mpt_cam.c:3292-3302 excludes XPT_RESET_DEV,
so tgt stays the raw phydisk-bus id when mpt_bus_reset() sends the TMF on
channel 0 (mpt_cam.c:3350 -> 2279-2287) β hitting the RAID volume with the
same numeric id. mpt_start() maps for I/O (2104-2112); the reset path
forgot. Trigger: camcontrol reset on the phydisk pass node. Requires MPT
RAID hardware (absent on guest β env.txt). See VERDICT.md + fix.diff.
DF-3677 β VERDICT
status: inconclusive (logic bug, source-certain; no MPT RAID hardware on guest)
Root cause
mpt_action() maps the RAID-physical-disk target id to a real bus-0
TargetID for every function except three:
/* sys/dev/disk/mpt/mpt_cam.c:3292-3302 */
if (raid_passthru &&
ccb->ccb_h.func_code != XPT_PATH_INQ &&
ccb->ccb_h.func_code != XPT_RESET_BUS &&
ccb->ccb_h.func_code != XPT_RESET_DEV) { /* <-- RESET_DEV excluded */
if (mpt_map_physdisk(mpt, ccb, &tgt) != 0) { ... CAM_DEV_NOT_THERE ... }
}
and mpt_start() performs the mapping itself for I/O
(mpt_cam.c:2104-2112), but the XPT_RESET_DEV case does not:
/* sys/dev/disk/mpt/mpt_cam.c:3342-3359 */
case XPT_RESET_DEV:
...
(void) mpt_bus_reset(mpt, tgt, lun, FALSE); /* tgt = raw path id */
tgt is the phydisk-bus id (0..MaxPhysDisks-1, exported on bus 1,
mpt_cam.c:3634-3638), but mpt_bus_reset() issues the TMF on channel
0 (mpt_scsi_send_tmf(..., 0 /* channel */, tgt, ...) via
mpt_cam.c:2279-2287), where the same numeric id denotes a RAID
volume. The result of XPT_RESET_DEV on a physical disk is a
TARGET_RESET of the unrelated volume that happens to share the number β
resetting every I/O in flight to that volume β or a reset sent to a
nonexistent target. mpt_map_physdisk() exists precisely to translate
(mpt_raid.c:806-819: *tgt = mpt_disk->config_page.PhysDiskID).
Impact: wrong-device reset (availability/data-integrity for the volume's in-flight I/O: unit attentions, failed writes reported to fs layers). Severity Low: requires a RAID-capable MPT controller, a userland reset of a hidden physdisk (camcontrol reset on the phydisk pass node), and the volume id space to overlap.
Fix
--- a/sys/dev/disk/mpt/mpt_cam.c
+++ b/sys/dev/disk/mpt/mpt_cam.c
@@ -3291,7 +3291,7 @@
if (raid_passthru &&
ccb->ccb_h.func_code != XPT_PATH_INQ &&
ccb->ccb_h.func_code != XPT_RESET_BUS &&
- ccb->ccb_h.func_code != XPT_RESET_DEV) {
+ ccb->ccb_h.func_code != XPT_RESET_DEV) { /* keep: mapped below */
if (mpt_map_physdisk(mpt, ccb, &tgt) != 0) {
ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
mpt_set_ccb_status(ccb, CAM_DEV_NOT_THERE);
@@ -3342,6 +3342,14 @@ mpt_action(struct cam_sim *sim, union ccb *ccb)
} else {
xpt_print(ccb->ccb_h.path, "reset device\n");
}
+ if (raid_passthru && mpt_map_physdisk(mpt, ccb, &tgt) != 0) {
+ ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
+ mpt_set_ccb_status(ccb, CAM_DEV_NOT_THERE);
+ xpt_done(ccb);
+ return;
+ }
(void) mpt_bus_reset(mpt, tgt, lun, FALSE);
Guest verdict
inconclusive β no MPT RAID controller on the QEMU guest; the mapping mismatch is proven by reading the three code sites against each other.
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_testableMapping fix authored (fix.diff); not exercisable without MPT RAID hardware.
fix.diff; env.txt
Confirmed kernel references
Detail
Evidence (decisive lines)
VERDICT.md (three-site comparison with path:line); fix.diff (map in the RESET_DEV case); env.txt
PoC changes
n/a
Verified recommended fix
Call mpt_map_physdisk() for XPT_RESET_DEV on the phydisk sim before issuing the TMF
Verdict
Source-certain logic bug: the raid_passthru gate in mpt_action (mpt_cam.c:3292-3302) excludes XPT_RESET_DEV from mpt_map_physdisk(), so the raw phydisk-bus target id is passed to mpt_bus_reset (3350) which issues the TMF on channel 0 (2279-2287) β resetting the RAID volume that shares the numeric id instead of the intended physical disk. I/O commands map correctly (mpt_start 2104-2112), proving the omission. Impact on hardware: wrong-device TARGET_RESET, disrupting in-flight volume I/O (availability/data-integrity); requires an MPT RAID controller, absent on this guest.
No comments yet.