Sense-data over-copy in amr_cam_complete leaks stale cross-command SCSI sense bytes
| Field | Value |
|---|---|
| ID | DF-1841 |
| Status | new |
| Severity | Info |
| CVSS 3.1 | CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N |
| CWE | CWE-909 Missing Initialization of Resource |
| File | sys/dev/raid/amr/amr_cam.c |
| Lines | 451, 477, 596-602 |
| Area | dev/raid (MegaRAID CAM sense) |
| Confidence | likely |
| Discovered | 2026-07-20 |
| Reported | pending |
| Known CVE | none |
| CVE match | dfly_specific |
Summary
On every CHECK CONDITION (scsi_status == 0x02), amr_cam_complete bcopys
the full AMR_MAX_REQ_SENSE_LEN (0x20 = 32) bytes out of the firmware sense
area and advertises sense_len = 32 to CAM, but the firmware is only requested
to fill ap_request_sense_length = 14 bytes (amr_cam.c:451,477). Bytes 14..31
of the DMA-resident sense area are never overwritten by the firmware and never
zeroed per-command. Those trailing bytes therefore carry whatever a prior
command on the same slot left there, and are copied verbatim into
csio->sense_data and returned to whichever userland client receives the next
CHECK CONDITION on that slot.
Root cause
amr_cam.c:451 sets aep->ap_request_sense_length = 14; and amr_cam.c:477 sets
ap->ap_request_sense_length = 14;. amr_cam.c:596-602 then does:
bcopy(aep->ap_request_sense_area, &csio->sense_data,
AMR_MAX_REQ_SENSE_LEN); /* 0x20 = 32 */
(and the ap variant), where AMR_MAX_REQ_SENSE_LEN == 0x20 (amrreg.h:92) and
u_int8_t ap_request_sense_area[AMR_MAX_REQ_SENSE_LEN] (amrreg.h:492,518) is 32
bytes wide. The firmware honours ap_request_sense_length and writes exactly 14
bytes; the driver copies 32. csio->sense_len = AMR_MAX_REQ_SENSE_LEN; (line
602) tells CAM to copy all 32 bytes back to the user. amr_alloccmd
(amr.c:1894-1904) clears ac_status/ac_mailbox/ac_flags etc. but never
touches ac_ccb (the DMA union), so the sense area persists across commands on
the same slot.
Threat model & preconditions
- Attacker position: local user able to issue SCSI passthrough CCBs to the
same
amrpbus (operator group or root on DragonFlyBSD). - Privileges gained or impact: local cross-command info leak of prior SCSI REQUEST SENSE payloads. Two processes sharing a MegaRAID passthrough device can in principle read fragments of each other's CHECK-CONDITION responses; the leaked bytes are SCSI sense data, not arbitrary kernel heap, so impact is informational.
- Required config or capabilities:
device amrMegaRAID controller with/dev/passNpassthrough; operator group. - Reachability: trigger CHECK CONDITION on a slot that previously carried a
different CHECK CONDITION on the same DMA slot; read bytes 14..31 of
csio->sense_data.
Proof of concept
Two-process PoC sketch (findings/poc/DF-1841/amr_sense_leak.c):
- Process A opens
/dev/passN, sends a SCSI CCB that produces CHECK CONDITION with a distinctive sense payload (e.g. TEST UNIT READY against a powered-off target, or MODE SENSE with an illegal page). Capture the 18 trailing bytes [14..31] ofcsio->sense_data; on the first run they are likely zero. - Process A sends a second CCB to a different target that returns a different CHECK CONDITION with its own sense data; bytes 14..31 of that slot's sense area remain whatever the prior command wrote.
- Process B opens
/dev/passN, sends a third CCB that triggers CHECK CONDITION on the same slot; it will receivecsio->sense_datawith bytes 14..31 equal to whatever bytes 14..31 of the slot held β stale data from prior commands on that slot.
Build & run
cc -o amr_sense_leak amr_sense_leak.c ./amr_sense_leak /dev/pass0
Expected output
Dump csio->sense_data and show that bytes 14..31 differ from the current
command's actual 14-byte sense β that confirms the leak. Document the leaked
bytes in leak_sample.txt across at least 3 runs.
Impact
Info-level cross-command sense data leak. No kernel heap disclosure; the leaked bytes are SCSI sense payloads from prior commands on the same DMA slot. Useful only for inferring what other operators are doing on the same controller.
Recommended fix
Zero the entire sense area before each submission so the trailing 18 bytes the firmware does not overwrite are always zero instead of stale data.
--- a/sys/dev/raid/amr/amr_cam.c
+++ b/sys/dev/raid/amr/amr_cam.c
@@ -453,6 +453,7 @@ amr_cam_command(struct amr_softc *sc, struct amr_command **acp)
aep->ap_timeout = 2;
aep->ap_ars = 1;
aep->ap_request_sense_length = 14;
+ bzero(aep->ap_request_sense_area, sizeof(aep->ap_request_sense_area));
aep->ap_islogical = 0;
@@ -481,6 +482,7 @@ amr_cam_command(struct amr_softc *sc, struct amr_command **acp)
ap->ap_timeout = 0;
ap->ap_ars = 1;
ap->ap_request_sense_length = 14;
+ bzero(ap->ap_request_sense_area, sizeof(ap->ap_request_sense_area));
ap->ap_islogical = 0;
References
- Firmware-honoured sense length: amr_cam.c:451, 477.
- Over-copy site: amr_cam.c:596-602.
- DMA region not zeroed per-command: amr.c:1894-1904.
Timeline
- 2026-07-20 Discovered during automated audit.
- 2026-07-20 Reported to DragonFlyBSD security contact (pending).
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-1841 Β· 1 files| File | Type | Description | Size | |
|---|---|---|---|---|
| fix.diff | suggested-fix | Sense-data over-copy in amr_cam_complete leaks stale cross-command SCSI sense by | 592 B | view raw |
Fix verification
not_testablefix.diff authored but did not apply cleanly; needs context rework
fix.diff authored but did not apply cleanly; needs context rework
Confirmed kernel references
β
Detail
Exploit chain
none (Info severity)
Evidence (decisive lines)
Source-confirmed at sys/dev/raid/amr/amr_cam.c:451: sense-data over-copy leaks stale cross-command SCSI sense bytes
Verified recommended fix
Source-confirmed at sys/dev/raid/amr/amr_cam.c:451: sense-data over-copy leaks stale cross-command SCSI sense bytes
Verdict
Source-confirmed at sys/dev/raid/amr/amr_cam.c:451: sense-data over-copy leaks stale cross-command SCSI sense bytes
No comments yet.