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

fOsBuildSgl executes panic("physical address unsupported") on CAM_DATA_PHYS passthrough CCBs (reachable debug panic)

Summary

The build-sgl callback of every hptmv READ/WRITE panics when a CCB carries CAM_DATA_PHYS (or CAM_SG_LIST_PHYS without scatter); pass(4) forwards such CCBs to the SIM unfiltered because it only memory-maps when the flag is clear. Root/operator: single ioctl = kernel panic. Same left-in-debug-panic family as DF-3921. Return-FALSE fix (existing PIO/error handling then deals with it).

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-3924 Β· 7 files
FileTypeDescriptionSize
README.md β€” 2.1 KB ↓ raw
VERDICT.md β€” 1.3 KB ↓ raw
df3924.c β€” 1.3 KB view raw
fix.diff β€” 492 B view raw
env.txt β€” 1.2 KB view raw
manifest.json β€” 749 B view raw
verdict.json β€” 1.8 KB view raw

DF-3924 β€” fOsBuildSgl panics on CAM_DATA_PHYS passthrough CCBs (reachable kernel panic)

What

sys/dev/raid/hptmv/entry.c:2510-2541 (fOsBuildSgl, the pfnBuildSgl of every hptmv command, set at entry.c:2799):

if(logical) {
    if (ccb->ccb_h.flags & CAM_DATA_PHYS)
        panic("physical address unsupported");        /* :2517-2518 */
    if (ccb->ccb_h.flags & CAM_SCATTER_VALID) {
        if (ccb->ccb_h.flags & CAM_SG_LIST_PHYS)
            panic("physical address unsupported");    /* :2521-2522 */

A CAMIOCOMMAND CCB on /dev/passN with CAM_DIR_* + CAM_DATA_PHYS set (and data present) skips cam_periph_mapmem entirely β€” passsendccb only maps when (ccb->ccb_h.flags & CAM_DATA_PHYS) == 0 (sys/bus/cam/scsi/scsi_pass.c:565) β€” so the flag reaches the SIM unfiltered and the first READ/WRITE with a non-scatter data buffer executes panic().

CAM_SG_LIST_PHYS without CAM_SCATTER_VALID is likewise a panic, though the scatter+phys variant is handled earlier in OsSendCommand (entry.c:2852-2857).

Impact

Root/operator-triggerable kernel panic on any hptmv box (DoS); also the "correct" hardware-event-adjacent path: any kernel consumer that legitimately issues physical-address CCBs to this SIM would panic. Left-in debug panic, same family as DF-3921 (hpt_async "Here"). Severity Low (privileged trigger + hardware-gated), certainty certain.

Reproduce (needs RR1820 + root)

cc -o df3924 df3924.c && sudo ./df3924 <hptmv-pass-unit>
# vulnerable driver: immediate panic "physical address unsupported"

Fix

--- a/sys/dev/raid/hptmv/entry.c
+++ b/sys/dev/raid/hptmv/entry.c
@@ -2514,11 +2514,13 @@ fOsBuildSgl(_VBUS_ARG PCommand pCmd, FPSCAT_GATH pSg, int logical)
    if(logical) {
-       if (ccb->ccb_h.flags & CAM_DATA_PHYS)
-           panic("physical address unsupported");
+       if (ccb->ccb_h.flags & CAM_DATA_PHYS)
+           return FALSE;
        if (ccb->ccb_h.flags & CAM_SCATTER_VALID) {
-           if (ccb->ccb_h.flags & CAM_SG_LIST_PHYS)
-               panic("physical address unsupported");
+           if (ccb->ccb_h.flags & CAM_SG_LIST_PHYS)
+               return FALSE;

(returning FALSE funnels the command into the existing PIO/RETURN_NEED_LOGICAL_SG error handling instead of panicking; see fix.diff)

VERDICT.md
↓ download raw

DF-3924 VERDICT

status: not_reproduced (hardware-gated) | impact observed: none (potential: privileged DoS panic) | source certainty: certain

Trace

  • scsi_pass.c:565-568: passsendccb calls cam_periph_mapmem ONLY when CAM_DATA_PHYS is clear; a CAM_DATA_PHYS CCB is forwarded to the SIM as-is.
  • entry.c:2799: every hptmv READ/WRITE gets pfnBuildSgl = fOsBuildSgl.
  • entry.c:2517-2518 / 2521-2522: unconditional panic() when the flag is seen with a logical (mapped) buffer request.
  • Trigger actor: root / SYSCAP_RESTRICTEDROOT through /dev/passN (see DF-3920 privilege analysis) on an hptmv target.

Not reproduced: audit guest has no RR1820 (env.txt); panic is unconditional at source, so the only uncertainty is reachability of the hardware, not the crash.

Fix validation

Hardware-gated; fix.diff replaces the panics with FALSE returns, which route the command to the existing PIO path / RETURN_NEED_LOGICAL_SG error handling (fDeviceSendCommand entry.c:1792-1805).

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_testable
baseline no→ patch + rebuild →patched clean

fix.diff swaps panics for FALSE returns routing into existing PIO/error handling; cannot validate without hardware

fix.diff in this pack; never applied to sys/
↓ fix.diffper-fix-DF-3924

Confirmed kernel references

Detail

Exploit chain

root -> /dev/passN CAMIOCOMMAND with CAM_DATA_PHYS + READ_10 -> hpt_action -> OsSendCommand -> fOsBuildSgl -> panic (DoS)

Evidence (decisive lines)

VERDICT.md trace; df3924.c exact CCB construction

PoC changes

n/a (fresh pack)

Verified recommended fix

Return FALSE instead of panic() in fOsBuildSgl for CAM_DATA_PHYS/CAM_SG_LIST_PHYS

Verdict

Unconditional panic("physical address unsupported") at entry.c:2518/2522 in fOsBuildSgl, the build-sgl callback of every hptmv READ/WRITE (registered at entry.c:2799). passsendccb forwards CAM_DATA_PHYS CCBs to the SIM unfiltered (scsi_pass.c:565 skips mapping only when the flag is clear), so a root/operator pass CCB with CAM_DATA_PHYS + READ_10 reaches the panic immediately. Not reproduced: no RR1820 hardware on the audit guest.