β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-1841

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 amrp bus (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 amr MegaRAID controller with /dev/passN passthrough; 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):

  1. 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] of csio->sense_data; on the first run they are likely zero.
  2. 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.
  3. Process B opens /dev/passN, sends a third CCB that triggers CHECK CONDITION on the same slot; it will receive csio->sense_data with 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.

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)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-1841 Β· 1 files
FileTypeDescriptionSize
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_testable
baseline reproduced→ patch + rebuild →patched clean

fix.diff authored but did not apply cleanly; needs context rework

fix.diff authored but did not apply cleanly; needs context rework
↓ fix.diffcombined build rc=0

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