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

adwprocesserror() panics on firmware-defined host_status codes the switch does not enumerate (0x35/0x36/0x46/0x47) β€” target/device-triggerable kernel panic

Summary

The switch over the device-written host_status omits four codes the driver's own firmware ABI defines; any completion carrying one hits default: panic - kernel DoS from ordinary I/O completion. DIRECTION_ERR is the RISC verdict for data-phase mismatch, which a misbehaving SCSI target can deliberately produce. Handle-the-four-codes fix.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-4308 Β· 5 files
FileTypeDescriptionSize
VERDICT.md β€” 2.2 KB ↓ raw
README.md β€” 347 B ↓ raw
fix.diff β€” 2.3 KB view raw
manifest.json β€” 195 B view raw
verdict.json β€” 2.7 KB view raw

DF-4308 evidence pack

Source-level finding against sys/dev/disk/advansys/adwcam.c β€” hardware-gated (guest/QEMU has no Advansys HBA; pciconf shows no vendor 10cd). No runnable PoC exists without the device. See VERDICT.md for the full path:line proof and fix.diff for the validated-shape fix (patch -p1 apply-verified, never applied to sys/).

VERDICT.md
↓ download raw

DF-4308 β€” adwprocesserror() panics on firmware-defined host_status codes the switch does not enumerate

File: sys/dev/disk/advansys/adwcam.c β€” severity Low (panic/DoS), bucket base:dev, confidence certain (source).

Root cause

adwprocesserror() (adwcam.c:1341-1429) maps firmware host-status codes to CAM statuses and ends in:

    default:
        panic("%s: Unhandled Host status error %x",
              adw_name(adw), acb->queue.host_status);   /* adwcam.c:1412-1414 */

acb->queue.host_status is a device-written byte (the RISC's completion verdict, DMA'd into the acb). The switch handles every code up to 0x45 except the four codes the driver's own firmware ABI defines (sys/dev/disk/advansys/adwlib.h:346-354):

  • QHSTA_M_DIRECTION_ERR 0x35 β€” data phase mismatch (a SCSI target can deliberately violate the data-in/data-out phase agreed in the identify; classic malicious/misbehaving-peripheral behavior, also produced by marginal cabling)
  • QHSTA_M_DIRECTION_ERR_HUNG 0x36 β€” same, bus hung
  • QHSTA_M_FROZEN_TIDQ 0x46 β€” TID queue frozen (U160 microcode)
  • QHSTA_M_SGBACKUP_ERROR 0x47 β€” S/G backup error (U160 microcode)

Any of these completing a command β†’ panic() β†’ kernel DoS from device/target-controlled input, exactly the class DF-1548/DF-2411/DF-2415 (CALC_GEOMETRY div0) already established for this driver family, but reachable from ordinary I/O completion rather than geometry setup.

Reproduction

Hardware-gated: needs an Advansys HBA + a target that produces a data-phase mismatch (or firmware emitting 0x46/0x47). Guest has no Advansys hardware (pciconf -l | grep 10cd β†’ empty). Source-level certainty β€” status untested.

Fix

fix.diff — handle the four codes (DIRECTION_ERR*→CAM_DATA_RUN_ERR, FROZEN_TIDQ→CAM_REQUEUE_REQ, SGBACKUP_ERROR→CAM_DATA_RUN_ERR) instead of panicking. patch -p1 apply-verified.

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 authored against the read-only sys/ tree (patch -p1 apply-verified); cannot be runtime-tested without Advansys hardware.

findings/poc/DF-4308/fix.diff
↓ fix.diffper-fix-DF-4308

Confirmed kernel references

Detail

Exploit chain

Attacker with an Advansys-equipped host plus a malicious/misbehaving SCSI target (or compromised HBA firmware): target violates the data phase for a command -> RISC completes it with host_status=0x35 -> adwprocesserror default branch -> panic('Unhandled Host status error 35') -> kernel DoS. Availability only.

Evidence (decisive lines)

findings/poc/DF-4308/VERDICT.md; switch adwcam.c:1350-1416; default panic adwcam.c:1412-1414; missing codes enumerated adwlib.h:346-354

PoC changes

No seed PoC (finding new in pass 2). Hardware-gated; no executable PoC without an Advansys HBA and a phase-violating target.

Verified recommended fix

Handle 0x35/0x36/0x46/0x47 with CAM_DATA_RUN_ERR / CAM_REQUEUE_REQ mappings instead of panic() β€” see fix.diff.

Verdict

Source-certain, hardware-gated. adwprocesserror() (adwcam.c:1341-1429) translates the device-written acb->queue.host_status byte but its switch omits four codes the driver's own firmware ABI defines (adwlib.h:346-354): QHSTA_M_DIRECTION_ERR 0x35, QHSTA_M_DIRECTION_ERR_HUNG 0x36, QHSTA_M_FROZEN_TIDQ 0x46, QHSTA_M_SGBACKUP_ERROR 0x47. Any completion carrying one of them falls into default: panic() at adwcam.c:1412-1414 -> kernel panic/DoS. 0x35/0x36 are data-phase-mismatch verdicts a misbehaving SCSI target can deliberately produce (phase violation), i.e. target-device-triggerable; 0x46/0x47 are U160-microcode statuses. Same device-fed-panic class as DF-1548/DF-2411/DF-2415 but reachable from ordinary I/O completion. No runtime reproduction: guest has no Advansys HBA (no vendor 10cd on pciconf).