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

CDB heap overflow via unchecked cdb_len into 12-byte CmdBlock

Summary

XPT_SCSI_IO driver copies pcsio->cdb_len bytes out of CDB into pSRB->CmdBlock with no check cdb_len fits. CmdBlock only 12 bytes (amd.h:159) immediately followed by union ccb *pccb (amd.h:160) but cdb_len attacker-controlled u_int8_t forwarded verbatim by passsendccb. 16-byte CDB (READ_16/WRITE_16 for >2TB disks) already overruns buffer. cdb_len>=17 corrupts pccb pointer. bcopy also reads cdb_len bytes from cdb_bytes[16] so cdb_len>16 is OOB read of adjacent ccb_scsiio fields. pccb dereferenced unconditionally (amd.c:287 amd.c:240 amd.c:919). amdsetupcommand feeds corrupted ScsiCmdLen to SCSI FIFO leaking overflowed bytes to target. Local /dev/passN CAMIOCOMMAND cdb_len>12.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-2425 Β· 22 files
FileTypeDescriptionSize
README.md β€” 4.7 KB ↓ raw
VERDICT.md β€” 11.6 KB ↓ raw
amdrig.c β€” 10.5 KB view raw
Makefile β€” 641 B ↓ download
build.sh β€” 138 B view raw
run.sh β€” 152 B view raw
fix-apply-build.sh β€” 1.2 KB view raw
build.log β€” 6.8 KB view raw
run.log β€” 94 B view raw
panic.txt β€” 1.6 KB view raw
attach-am53c974-boot.log β€” 10.3 KB view raw
fix.diff β€” 755 B view raw
fix-apply.log β€” 692 B view raw
fix-module-build.log β€” 853 B view raw
fix-kernel-build.log β€” 486 B view raw
fix-run.log β€” 157 B view raw
fix-run-serial.log β€” 1.4 KB view raw
fix-run2-serial-full.log β€” 13.8 KB view raw
env.txt β€” 370 B view raw
kernel-patched.sha256 β€” 65 B ↓ download
manifest.json β€” 1.5 KB view raw
verdict.json β€” 7.8 KB view raw

DF-2425 β€” PoC evidence pack

Finding: CDB heap overflow via unchecked cdb_len into 12-byte CmdBlock File: sys/dev/disk/amd/amd.c:399-400 (sink), sys/dev/disk/amd/amd.h:159 (CmdBlock[12]) Verdict: reproduced (kernel memory corruption, production-code rig) Β· fix validated

What was verified

  1. Static chain (host tree) β€” no validation of cdb_len anywhere between the CAMIOCOMMAND ioctl and the driver sink: - sys/bus/cam/scsi/scsi_pass.c:462 CAMIOCOMMAND β†’ passsendccb - sys/bus/cam/cam_xpt.c:3888 xpt_merge_ccb() β€” bcopys the user's entire CCB payload (incl. cdb_len, msg_ptr) into the kernel ccb, verbatim - sys/dev/disk/amd/amd.c:399-400 β€” bcopy(cdb_bytes, CmdBlock[12], cdb_len) - overflow bytes CmdBlock[16..24) land exactly on struct amd_srb.pccb; those source bytes are ccb_scsiio.msg_ptr (fully user-controlled) - amd.c:287-288 dereferences the forged pointer immediately
  2. Hardware reality β€” QEMU 7.2's -device am53c974 (PCI 0x1022:0x2020) is matched by amd_probe (amd.c:2455): amd0 attaches to real emulated silicon (attach-am53c974-boot.log:103). The XPT bus scan then wedges forever in the emulation (the driver has no timeout handler, amd.c:356-360 #if 0), so the end-to-end userland path could not complete on emulated hardware; the production-code KLD rig below was used instead (as sanctioned for hardware-absent drivers).
  3. Trust boundary (live on guest) β€” /dev/pass0 is crw------- root:operator; non-root open fails with EACCES. device amd is compiled into GENERIC (sys/config/X86_64_GENERIC:88) but dormant without the PCI card.
  4. Baseline reproduction (rig driving the real amd_action, unmodified /usr/src source) β€” panic.txt + panic.txt: - controlled WRITE through the forged pccb (amd.c:355 ccb->ccb_h.status |= CAM_SIM_QUEUED observed at the victim address), full deterministic SRB smash (dmamap=0x00c0ffee005a1337, pSGlist=0x1234abcd), guest survives; - panic proof: forged pccb=0x414141414141 β†’ Fatal trap 12, faulting address 0x4141414141c9 (attacker bytes + 0x88 = offsetof(ccb_hdr, ccb_amd_ptr)), stopped at amdexecutesrb+0x12: movq 0x88(%r13),%r12 β€” exactly amd.c:288.
  5. Fix validation β€” fix.diff (reject cdb_len > sizeof(CmdBlock) with CAM_REQ_INVALID) applied to guest /usr/src; rig module rebuilt against the patched source AND full nativekernel rebuild + install + reboot (kernel #1 Mon Oct 12 08:57:10 UTC 2026, sha256 1aecdc66d61423b7fd570f698e4df6a4d6d335c7779b95b30c609248910ee63b): identical inputs β†’ RIGDONE: shim saw func=2305 status=0x6 (XPT_SCSI_IO / CAM_REQ_INVALID), SRB untouched, no panic, and a valid 6-byte CDB still queues normally (no functional regression).

Layout

file what
amdrig.c the rig: verbatim #include of production amd.c, driven like amd_attach does
Makefile in-guest module Makefile (make -C /usr/src/sys/modules/amdrig)
build.sh / run.sh exact host-side build/run commands
build.log final successful baseline module build (full compiler output)
run.log host-side run transcripts
panic.txt baseline run, verbatim (write-demo + sanity + panic; the full baseline serial was lost when QEMU truncated boot.log on the subsequent reset β€” every RIG* line and the complete trap dump are preserved here)
attach-am53c974-boot.log proof the real driver attaches to QEMU's emulated AMD 53C974
fix.diff git-apply-able clamp fix
fix-apply.log / fix-module-build.log / fix-kernel-build.log patch + module + kernel rebuild logs
fix-run-serial.log / fix-run2-serial-full.log patched-kernel runs (reject, no panic)
fix-run.log host-side fixed-run transcript
env.txt / kernel-patched.sha256 guest environment, patched kernel hash
VERDICT.md full narrative
manifest.json / verdict.json machine-readable results

Reproduce

# guest is up (vm.sh up), /usr/src present:
./build.sh                      # module build (baseline: unpatched /usr/src)
kldload /usr/src/sys/modules/amdrig/amdrig.ko     # write-demo (survives)
sysctl dev.amdrig_fire=1                          # panic proof (panics)
# after vm.sh reset with-src:
./fix-apply-build.sh            # patch + module + nativekernel rebuild
# reboot, then: kldload ...; sysctl dev.amdrig_fire=1  -> clean reject, no panic

Expected on the unpatched kernel: RIGW1 ... WRITE-THROUGH-FORGED-PTR-CONFIRMED and (mode 1) Fatal trap 12 ... Stopped at amdexecutesrb+0x12. Expected on the patched kernel: RIGDONE: shim saw func=2305 status=0x6, no write, no panic, mode 2 still queues normally.

VERDICT.md
↓ download raw

DF-2425 VERDICT β€” full narrative

Bottom line

REPRODUCED. The unchecked cdb_len β†’ bcopy into CmdBlock[12] at sys/dev/disk/amd/amd.c:400 is a real, deterministic kernel heap overflow inside the SRB, and it yields a fully attacker-chosen 64-bit pointer (struct amd_srb.pccb) that the driver dereferences immediately (amd.c:287-288) and writes through (amd.c:355). Demonstrated on the production driver source compiled into a KLD rig (no modification of the audited code path), including a kernel panic whose faulting address contains the attacker's bytes verbatim. The clamp fix (fix.diff) eliminates both the overflow and the forged-pointer deref and was validated on a rebuilt GENERIC kernel. However, the trigger is reachable in practice only from a context that can already issue arbitrary SCSI commands (/dev/passN is root:operator 0600) and only on systems whose PCI bus carries an AMD 53C974 / Tekram DC-390(T) HBA. Severity is therefore materially lower than filed (High β†’ realistic Low/Medium); see "Honest reachability".

The bug, precisely

struct amd_srb (sys/dev/disk/amd/amd.h:157-160):

offset  0: TAILQ_ENTRY(amd_srb) links;   /* 16 bytes */
offset 16: u_int8_t CmdBlock[12];        /* sink                       */
offset 24: (4 bytes padding)
offset 32: union ccb *pccb;              /* CmdBlock[16..24) lands HERE */
offset 40: bus_dmamap_t dmamap;          /* CmdBlock[24..32) */
offset 48: struct amd_sg *pSGlist;       /* CmdBlock[32..40) */

amd_action(XPT_SCSI_IO) (amd.c:399-400):

pSRB->ScsiCmdLen = pcsio->cdb_len;                                       /* :399 */
bcopy(pcsio->cdb_io.cdb_bytes, pSRB->CmdBlock, pcsio->cdb_len);          /* :400 */

cdb_len is u_int8_t (sys/bus/cam/cam_ccb.h:603) β€” 0..255, and cdb_io.cdb_bytes is 16 bytes (IOCDBLEN = CAM_MAX_CDBLEN = 16, cam_ccb.h:44,587). Nothing between the CAMIOCOMMAND ioctl and this bcopy validates it:

  • scsi_pass.c:462 CAMIOCOMMAND hands the user's ccb to passsendccb;
  • xpt_merge_ccb (cam_xpt.c:3888-3897) copies the user's entire CCB payload after ccb_hdr into the kernel ccb β€” cdb_len, msg_ptr, tag_action, … all verbatim;
  • cam_periph_runccb β†’ xpt_action dispatches to the SIM with no further checks (grep cdb_len over cam_xpt.c/cam_periph.c: no hits).

The over-read source bytes cdb_bytes[16..24) are ccb_scsiio.msg_ptr (next field after cdb_io, cam_ccb.h:625-633) β€” an 8-byte, fully-user-controlled value copied verbatim by xpt_merge_ccb. They land exactly on pccb (verified at runtime: offsetof(CmdBlock)=16, offsetof(pccb)=32, sizeof(amd_srb)=384).

Then, with CAM_DIR_NONE (no DMA mapping), amdexecutesrb runs on the same call:

ccb = srb->pccb;                        /* amd.c:287 β€” forged            */
amd = ccb->ccb_h.ccb_amd_ptr;           /* amd.c:288 β€” DEREF of it       */
...
if (ccb->ccb_h.status != CAM_REQ_INPROG) /* amd.c:347 β€” read through it  */
...
ccb->ccb_h.status |= CAM_SIM_QUEUED;    /* amd.c:355 β€” WRITE through it  */

Deeper overflow (cdb_len up to 255) also overwrites dmamap, pSGlist, TotalXferredLen, SGPhysAddr, SGToBeXferLen, Segment0/1 and walks 141 bytes into SGsegment[] β€” all within the softc's SRB_array, so the bcopy itself stays inside the softc allocation; the dangerous primitives are the three smashed pointer fields (pccb used at :240/:244/:287/:919; dmamap later bus_dmamap_unloaded at :349 on error paths; pSGlist consumed by the S/G engine). Additionally amdsetupcommand (amd.c:252-255) later writes ScsiCmdLen (=255) bytes from CmdBlock to the SCSI FIFO β€” an info leak of the overflowed SRB bytes to a (hostile) SCSI target.

Why a rig (and what the rig is)

The amd(4) driver attaches only to PCI 0x1022:0x2020 (amd.c:82,2455). It IS compiled into GENERIC (sys/config/X86_64_GENERIC:88; /usr/obj/.../amd.o present in the guest) but no physical card exists in the QEMU guest.

QEMU 7.2 does emulate this chip (-device am53c974, and dc390), with the same PCI ID. Attaching it proved the driver binds for real:

attach-am53c974-boot.log:103:
amd0: <Tekram DC390(T)/AMD53c974 SCSI Host Adapter> port 0xc000-0xc07f irq 11 at device 3.0 on pci0
attach-am53c974-boot.log:133: CAM: Configuring 3 busses

but boot then wedges forever at Waiting 5 seconds for SCSI devices to settle β€” the XPT scan of the emulated bus never completes (the driver has no timeout handler at all, amd.c:356-360 is #if 0), so multiuser is never reached and the userland pass(4) path cannot be driven end-to-end on this emulation. That is an availability bug of its own (any command that does not complete hangs the queue forever), not a bypass of the finding.

The rig (amdrig.c) therefore compiles the production /usr/src/sys/dev/disk/amd/amd.c verbatim into a KLD (#include), sets up exactly what amd_init/amd_attach set up (softc, dma tag, amd_linkSRB, cam_sim_alloc(amd_action, amd_poll, ...)), and calls the real amd_action with a crafted XPT_SCSI_IO ccb. Documented deviations, none in the audited path:

  • #define xpt_done rig_xpt_done shim β€” forwards to the real xpt_done unless ccb_h.path == NULL (rig-fabricated ccbs cannot travel the real CAM completion machinery without a registered device; the shim records the completion instead). The baseline panic/writes never reach xpt_done; only the fixed build's reject path does.
  • DRIVER_MODULE stubbed (newbus registration boilerplate) β€” the GENERIC kernel already owns module pci/amd; without the stub kldload refuses.
  • #define amd amdrig_chip β€” renames module-scope identifiers only; every driver function/struct token is untouched.

Baseline results (unmodified /usr/src, kernel #0 Jul 2 2026)

Run 1 β€” controlled write, guest survives (panic.txt, panic.txt header):

RIGW0: victim=0xfffff8008db3b800 (pre status=0x0), forging pccb=0xfffff8008db3b800 via csio.msg_ptr, cdb_len=255
RIGW1: post victim status=0x200 (CAM_SIM_QUEUED=0x200) -> WRITE-THROUGH-FORGED-PTR-CONFIRMED
RIGW2: srb=... CmdBlock[0..11]=4c4c4c4c4c4c4c4c4c4c4c4c pccb=0xfffff8008db3b800
       dmamap=0xc0ffee005a1337 pSGlist=0x1234abcd ScsiCmdLen=255

The write status |= CAM_SIM_QUEUED (amd.c:355) landed at the forged address β€” a write-what-where-class primitive (OR of a known constant at a chosen kernel address). dmamap/pSGlist values match the predicted packing of msg_len/tag_action/tag_id/init_id β€” the smash is byte-exact and deterministic.

Run 2 β€” sanity: cdb_len=6 queues normally (RIGS1), i.e. the rig drives the driver's legitimate path.

Run 3 β€” panic proof:

RIGP0: forging pccb=0x414141414141 (canonical, unmapped) via csio.msg_ptr, cdb_len=255
Fatal trap 12: page fault while in kernel mode
fault virtual address = 0x4141414141c9
fault code = supervisor read data, page not present
Stopped at amdexecutesrb+0x12: movq 0x88(%r13),%r12

0x4141414141c9 = 0x414141414141 + 0x88 (0x88 = offsetof(struct ccb_hdr, ccb_amd_ptr)) and the faulting instruction is exactly amd.c:288 β€” the deref uses the attacker's six bytes verbatim. That is byte-for-byte pointer control at the sink, proven.

Honest reachability / severity

  • Non-root users cannot trigger it. /dev/pass0 and /dev/xpt0 are crw------- root:operator on this guest; opening as an unprivileged user returns EACCES (tested). cdb_len > 16 exists nowhere in kernel-issued CCBs: periph drivers build ≀16-byte CDBs, and the only >12 case reachable from ordinary disk I/O is da(4) READ_16/WRITE_16 (cdb_len=16) on

    2TB devices β€” which writes 4 bytes into the padding between CmdBlock[12] and pccb (offsets 28..31): technically UB, no live field corrupted.

  • The driver must be attached, i.e. the machine must carry an AMD 53C974/Tekram DC-390 PCI HBA (1990s hardware; QEMU -device am53c974 re-creates it, and the driver attaches β€” proven above).
  • Therefore the practical attacker is root (or an operator with a permissive pass node / a jail with pass exposed) on a machine with this HBA, turning "send raw SCSI CDB" into a kernel write primitive. On the audit rubric ("Low: … requires specific hardware or already-privileged user") the realistic severity is Low–Medium, not the filed High (whose PR:L assumption does not hold). The code defect itself is certain and the primitive is strong; the fix is still warranted as hardening and correctness.

  • uid0 escalation was not pursued because the trigger is already root-gated on the only reachable configuration; "root β†’ uid0" adds no privilege.

Fix validation

fix.diff inserts, before the bcopy:

if (pcsio->cdb_len > sizeof(pSRB->CmdBlock)) {
        TAILQ_INSERT_HEAD(&amd->free_srbs, pSRB, links);
        pccb->ccb_h.status = CAM_REQ_INVALID;
        xpt_done(pccb);
        return;
}

Applied to guest /usr/src (fix-apply.log: Hunk #1 succeeded at 393), then:

  1. Module-level A/B β€” rig rebuilt against the patched source, same inputs (fix-run-serial.log, fix-run2-serial-full.log):

RIGW0: ... forging pccb=0xfffff8008db3b800 ... cdb_len=255 RIGDONE: shim saw func=2305 status=0x6 <- XPT_SCSI_IO / CAM_REQ_INVALID RIGW1: post victim status=0x0 -> no-write <- forged ptr never used RIGW2: ... CmdBlock[0..11]=000000000000000000000000 pccb=0 dmamap=<valid map> ScsiCmdLen=0

pccb=0, CmdBlock zeroed, dmamap = the legitimate map from amd_linkSRB β€” the bcopy never executed.

  1. Full kernel A/B β€” make -j6 nativekernel KERNCONF=X86_64_GENERIC + install + reboot into kernel #1 Mon Oct 12 08:57:10 UTC 2026 (sha256 1aecdc66…ee63b), the config that includes device amd:
  • the exact input that panicked the baseline (dev.amdrig_fire=1, forged 0x414141414141) now completes with RIGDONE: shim saw func=2305 status=0x6 and no panic β€” guest stayed up (RIGP1: UNEXPECTED survival, uptime verified);
  • dev.amdrig_fire=2 (cdb_len=6) still queues the srb normally β€” no functional regression for legitimate commands.

Known rig wart, documented for honesty: dev.amdrig_fire=3 (rig_reject_case) memsets an SRB that is still linked on free_srbs, corrupting the TAILQ; on the fixed kernel its reject path then touches the corrupted queue and panics at amd_action+0x335 (fix-run-serial.log). This is a bug in my test harness, not in the production fix β€” the load-time write-demo (same cdb_len=255 input, no memset) rejects cleanly. Mode 3 is not needed for the verdict; modes 0/1/2 carry the full A/B.

Conclusion

baseline patched
write through forged pccb (amd.c:355) YES (status 0x200 at victim) no (status stays 0)
SRB smash (CmdBlock/pccb/dmamap/ScsiCmdLen) YES, byte-exact none
forged deref amd.c:288 β†’ Fatal trap 12 YES @ 0x4141414141c9 no β€” CAM_REQ_INVALID
valid cdb_len=6 path works works

The finding is certain at the code level, reproduced with both a controlled kernel-address write and a kernel panic in the production routine, the fix is validated at module and full-kernel level, and the practical severity is gated by hardware presence + root-level CAM access (non-root is locked out by /dev/passN permissions β€” tested).

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

fixed
baseline reproduced→ patch + rebuild →patched clean

fix.diff (clamp cdb_len to sizeof(CmdBlock), reject with CAM_REQ_INVALID) applied to guest /usr/src (Hunk #1 succeeded at 393). Module A/B: identical cdb_len=255 input went from 'WRITE-THROUGH-FORGED-PTR-CONFIRMED' + full SRB smash to 'RIGDONE shim saw func=2305 status=0x6', CmdBlock zeroed, pccb=0, dmamap=legitimate, no write. Full kernel A/B: make -j6 nativekernel + installkernel + reboot into #1 Mon Oct 12 08:57:10 (sha256 1aecdc66d61423b7fd570f698e4df6a4d6d335c7779b95b30c609248910ee63b) β€” the exact input that panicked the baseline (Fatal trap 12 @ amdexecutesrb+0x12, fault 0x4141414141c9) now rejects cleanly and the guest stays up; cdb_len=6 sanity still queues normally (no regression).

fix-run2-serial-full.log: 'RIGP0: forging pccb=0x414141414141 ...' followed by 'RIGDONE: shim saw func=2305 status=0x6' and 'RIGP1: UNEXPECTED survival' (no Fatal trap, guest up; RIGP1 text is the rig's vulnerable-build wording), plus 'RIGS1: cdb_len=6 returned; waiting_srbs non-empty'; contrast panic.txt baseline 'Fatal trap 12 ... 0x4141414141c9 ... amdexecutesrb+0x12'; fix-kernel-build.log: '>>> Kernel build for X86_64_GENERIC completed'; kernel-patched.sha256
↓ fix.diffper-fix-DF-2425

Confirmed kernel references

Detail

Exploit chain

root with /dev/passN open on a machine with an attached AMD 53C974 HBA -> CAMIOCOMMAND with XPT_SCSI_IO, CAM_DIR_NONE, cdb_len=255, cdb_bytes pattern, csio.msg_ptr= -> xpt_merge_ccb copies payload verbatim -> amd_action:400 bcopy overflows CmdBlock[12]; msg_ptr lands on amd_srb.pccb -> amdexecutesrb:287 loads it, :288 dereferences (read at +0x88), :347 reads, :355 OR-writes CAM_SIM_QUEUED at the chosen address -> controlled kernel-address write primitive (plus panic on unmapped target; deeper cdb_len also smashes dmamap/pSGlist consumed on later paths). Not reachable from non-root (pass node 0600) nor without the HBA; uid0 chain N/A (trigger already root).

Evidence (decisive lines)

panic.txt (verbatim baseline transcript): 'Fatal trap 12 ... fault virtual address = 0x4141414141c9 ... Stopped at amdexecutesrb+0x12: movq 0x88(%r13),%r12' preceded by RIGW1 'post victim status=0x200 -> WRITE-THROUGH-FORGED-PTR-CONFIRMED' and RIGW2 'CmdBlock=4c4c.. pccb=victim dmamap=0xc0ffee005a1337 pSGlist=0x1234abcd ScsiCmdLen=255' and RIGS1 sanity; attach-am53c974-boot.log:103 'amd0: <Tekram DC390(T)/AMD53c974 SCSI Host Adapter> ... pci0'; fix-run2-serial-full.log: 'RIGDONE: shim saw func=2305 status=0x6' + 'RIGW2 CmdBlock=0000... pccb=0 dmamap=<valid>' + mode-1 no panic on patched kernel #1; env.txt: /dev/pass0 crw------- root:operator

PoC changes

Pass-1 pack did not exist; built from scratch. Rig includes production /usr/src amd.c verbatim with three documented, non-audited-path adaptations: (1) xpt_done shim (records completions of path-less fabricated ccbs, forwards real ones) β€” baseline crash/write never reach xpt_done, only the fixed build's reject path does; (2) DRIVER_MODULE stubbed (kernel already owns module pci/amd, kldload would refuse); (3) #define amd amdrig_chip identifier rename for module-scope symbols. Rig bug found during validation: fire mode 3 (rig_reject_case) memsets an SRB still on free_srbs, corrupting the TAILQ β€” its panic on the fixed kernel (amd_action+0x335) is a harness artifact, documented; modes 0/1/2 carry the verdict. The userland trigger would be a plain CAMIOCOMMAND ioctl; end-to-end pass(4) drive was impossible on the guest because QEMU's am53c974 emulation wedges the driver's no-timeout XPT scan at boot.

Verified recommended fix

Reject XPT_SCSI_IO with cdb_len > sizeof(pSRB->CmdBlock) before the bcopy (CAM_REQ_INVALID + xpt_done), see fix.diff

Verdict

The unchecked pcsio->cdb_len bcopy into CmdBlock[12] (amd.c:400) is a real, deterministic SRB heap overflow: cdb_len (u_int8_t, copied verbatim from the CAMIOCOMMAND payload by xpt_merge_ccb, cam_xpt.c:3888 β€” no validation anywhere in the chain) writes up to 255 bytes, and bytes CmdBlock[16..24) land exactly on amd_srb.pccb with the fully user-controlled csio.msg_ptr as their source. Verified on the production amd.c source (KLD rig, driver code verbatim): amdexecutesrb dereferences the forged pointer immediately (amd.c:287-288) β€” forged 0x414141414141 gave Fatal trap 12, fault 0x4141414141c9 (attacker bytes + 0x88), stopped at amdexecutesrb+0x12 β€” and amd.c:355 writes status |= CAM_SIM_QUEUED through the forged pointer (write-what-where-class OR primitive, byte-exact SRB smash: dmamap=0x00c0ffee005a1337, pSGlist=0x1234abcd). The real driver attaches to QEMU 7.2's emulated am53c974 (amd0 at pci0:3.0, same PCI ID 0x1022:0x2020), but the XPT scan wedges forever in the emulation (no driver timeout handler, amd.c:356), so the end-to-end pass(4) path could not be driven on this guest; the rig (sanctioned for hardware-absent drivers) drove the real amd_action instead. Honest reachability: non-root users cannot trigger (tested: /dev/pass0 is root:operator 0600, EACCES as user); kernel-issued CDBs never exceed 16 bytes (da(4) READ_16's cdb_len=16 writes only 4 bytes of inter-field padding); and the driver must be attached (AMD 53C974/Tekram DC-390 PCI HBA, compiled into GENERIC but dormant without the card). So the practical attacker is root on HBA-equipped hardware β€” realistic severity Low-Medium vs the filed High (PR:L does not hold); uid0 escalation was not pursued because the trigger is already root-gated. Fix (reject cdb_len > sizeof(CmdBlock) with CAM_REQ_INVALID) validated at module level AND on a full nativekernel rebuild+reboot: identical inputs now reject cleanly (func=2305 status=0x6), no write, no panic, valid cdb_len=6 commands unaffected.