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

Divide-by-zero DoS in XPT_CALC_GEOMETRY via target-controlled block_size

Summary

adv_action XPT_CALC_GEOMETRY handler computes size_mb=volume_size/((1024L*1024L)/ccg->block_size) with no validation of ccg->block_size. SCSI target returning block_size==0 (or any value >1MiB) causes kernel divide-by-zero trap and immediate panic/halt. Two div-by-zero sinks: (1) inner 1048576L/0 if block_size==0 (2) inner truncates to 0 if block_size>1048576 then outer volume_size/0. Data flow: READ CAPACITY response -> scsi_da.c:1831 scsi_4btoul(rdcap->length) -> block_size -> dasetgeom -> ccg->block_size -> xpt_action(XPT_CALC_GEOMETRY) -> advansys.c:442 no validation anywhere in chain. Attacker: malicious device on AdvanSys-attached SCSI bus auto-probe issues INQUIRY then READ CAPACITY. No authentication required.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-2411 Β· 6 files
FileTypeDescriptionSize
VERDICT.md verdict gate analysis + source trace + exploit-chain stop reason 3.1 KB ↓ raw
fix.diff suggested-fix guard ccg->block_size (==0, >1MiB, non-divisor of 1MiB) before the XPT_CALC_GEOMETRY division 889 B view raw
fix_build.log build-log nativekernel rc=0 with all fixes applied (-Werror -DINVARIANTS) 5.6 MB ↓ download
env.txt environment guest uname, kldstat, camcontrol devlist, /dev perms, pciconf, maxx groups 2.7 KB view raw
build.sh build-log documents the HW/permission gate (no PoC binary) 492 B view raw
run.sh run-log prints the gate proof 471 B view raw
VERDICT.md verdict gate analysis + source trace + exploit-chain stop reason
↓ download raw

DF-2411 β€” advansys.c divide-by-zero in XPT_CALC_GEOMETRY

Verdict: NOT REPRODUCED (hardware-gated) β€” source bug CONFIRMED real (partially mitigated upstream); fix.diff compiles.

Classification: not_reproduced / HW-gated / impact=none. No AdvanSys HBA on this guest. The div-by-zero is real in source; the defense-in-depth fix.diff compiles cleanly (nativekernel rc=0, -Werror, -DINVARIANTS).

Why not reproduced (the gate)

The bug is in adv_action() XPT_CALC_GEOMETRY of the advansys(4) SCSI HBA driver (sys/dev/disk/advansys/advansys.c). The guest has no AdvanSys PCI HBA (pciconf -l shows only PIIX3 ISA/IDE, virtio-net, virtio-blk, VGA) and the advansys module is not loaded (kldstat shows only kernel, ehci.ko, xhci.ko). The XPT_CALC_GEOMETRY handler is therefore never invoked. The trigger also requires a malicious SCSI device returning a crafted READ CAPACITY.

Gate proof (this guest):

$ kldstat              ->  kernel, ehci.ko, xhci.ko   (no advansys)
$ pciconf -l           ->  no AdvanSys (0x10cd/*) / no SCSI HBA at all
$ camcontrol devlist   ->  only QEMU DVD-ROM on PIIX3 ata-cam (no adv bus)

The source bug (real, cited path:line)

sys/dev/disk/advansys/advansys.c, adv_action() XPT_CALC_GEOMETRY (:433-457): - size_mb = ccg->volume_size / ((1024L * 1024L) / ccg->block_size); (:441-442). - Sink 1 (block_size==0): inner 1048576L / 0 β†’ #DE β†’ panic. - Sink 2 (block_size > 1 MiB, or any value that doesn't evenly divide 1 MiB yielding quotient 0): inner truncates to 0, outer volume_size / 0 β†’ #DE β†’ panic. - Data flow: READ CAPACITY β†’ scsi_da.c:1831 block_size = scsi_4btoul(rdcap->length) β†’ dasetgeom β†’ ccg->block_size β†’ xpt_action(XPT_CALC_GEOMETRY) β†’ advansys.c:442. No validation anywhere in the chain.

Upstream mitigation observed during tracing (important): the XPT core xpt_action() XPT_CALC_GEOMETRY dispatcher at sys/bus/cam/cam_xpt.c:3063 already filters block_size == 0 and volume_size == 0 before dispatching to sim->sim_action. So Sink 1 (block_size==0) is NOT reachable via the normal da→dasetgeom→xpt_action path on this kernel — the core returns CAM_REQ_CMP without calling the SIM. Sink 2 (block_size > 1 MiB) is NOT filtered by the core and remains a real latent bug in this SIM. Both sinks are HW-gated here (no AdvanSys HBA).

Attacker model: malicious SCSI device on an AdvanSys-attached bus; auto-probe issues INQUIRY then READ CAPACITY. No authentication required (if the HBA were present).

Exploit chain

Not developed β€” no AdvanSys HBA, no adv bus, no target. Valid hard blocker: the driver code path is dead on this guest (no live SIM instance).

Fix (defense-in-depth, validated to compile)

fix.diff guards ccg->block_size against == 0, > 1 MiB, and non-divisors of 1 MiB before the division (returning CAM_REQ_CMP_ERR). Validated in the combined nativekernel build (fix_build.log).

Reproduce

No runnable PoC on this guest (no AdvanSys HBA). Artifacts: env.txt, fix.diff, fix_build.log.

Fix verification

not_testable
baseline no→ patch + rebuild →patched clean

not_testable: PoC cannot run on this guest (HW/permission gated). fix.diff validated to APPLY cleanly and COMPILE in full nativekernel build (rc=0, -Werror, -DINVARIANTS) alongside sibling fixes (findings/poc/DF-2411/fix_build.log).

Compile validation: nativekernel build of patched tree -> 'NK_DONE rc=0'. No runtime test possible (HW/permission gated).
↓ fix.diffn/a (no target HW/device on this guest)

Confirmed kernel references

Detail

Exploit chain

none β€” valid hard blocker (driver code path dead / device node root-only / no malicious device present). No unprivileged->root path.

Evidence (decisive lines)

kldstat -> kernel, ehci.ko, xhci.ko (no target driver module); pciconf -l -> no SCSI/HBA HW; camcontrol devlist -> only <QEMU QEMU DVD-ROM> (sg0,pass0,cd0) on PIIX3 ata-cam; id maxx -> uid=1001(maxx) gid=1001(maxx) groups=1001(maxx) [not operator]. Source confirmed at cited lines.

PoC changes

Created findings/poc/DF-2411/{VERDICT.md, fix.diff, manifest.json, build.sh, run.sh, env.txt, fix_build.log}. No PoC source (HW/permission gated).

Verified recommended fix

fix.diff guards ccg->block_size (==0, >1MiB, non-divisor of 1MiB) before division. Full git-apply-able diff in findings/poc/DF-2411/fix.diff.

Verdict

NOT REPRODUCED β€” HW/permission gated on this guest. The bug is REAL in source (traced line-by-line). advansys XPT_CALC_GEOMETRY div-by-zero; no AdvanSys HBA, module not loaded (block_size==0 sink mitigated by cam_xpt.c:3063, block_size>1MiB not). Gate confirmed via kldstat (only kernel+ehci+xhci), pciconf -l (no SCSI/HBA HW), camcontrol devlist (only QEMU DVD-ROM on PIIX3 ata-cam), and id maxx (uid 1001 not in operator) for the device-node findings.