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

ciss_cam_complete: controller-supplied sense_length overflows fixed-size csio->sense_data on CHECK_CONDITION

Summary

ciss_cam_complete at ciss.c:3248-3254: bcopy(&ce->sense_info[0], &csio->sense_data, ce->sense_length) copies controller-controlled u8 (0-255) into struct scsi_sense_data=32 bytes. No min() against SSD_FULL_SIZE. sense_length>32 overwrites cdb_io, msg_ptr, and adjacent heap in union ccb. Operator via /dev/passN CHECK_CONDITION or malicious controller. Fix: clamp to imin(ce->sense_length,SSD_FULL_SIZE,csio->sense_len).

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-1191 Β· 11 files
FileTypeDescriptionSize
harness.c trigger-source replica of bcopy(ce->sense_length) into 32-byte sense_data with neighbor canary 2.7 KB view raw
VERDICT.md verdict full narrative + fix 3.1 KB ↓ raw
build.sh build-script cc -O2 -Wall -o harness harness.c 172 B view raw
run.sh run-script ./harness 66 B view raw
run.log run-log overflow at sense_length=64 (32B) and 255 518 B view raw
env.txt environment uname, cc version 418 B view raw
fix.diff suggested-fix clamp bcopy len to imin(sense_length, imin(SSD_FULL_SIZE, csio->sense_len)) 593 B view raw
fix_build.log build-log ciss.ko rebuilt with all 3 ciss fixes, -Werror, rc=0 29 B view raw
README.md readme human reproduce doc 1.4 KB ↓ raw
../fix_build_combined.log build-log Combined 41-finding kernel build (rc=0, -Werror clean) 5.6 MB ↓ download
../fix_build_summary.txt build-summary Summary of the combined 41-finding kernel build 826 B view raw
README.md readme human reproduce doc
↓ download raw

DF-1191 β€” ciss_cam_complete unchecked sense_length -> heap overflow

File: sys/dev/raid/ciss/ciss.c:3248-3249 Class: memory corruption (hardware/firmware-attacker; malicious CISS PCI device or malicious VBIOS at driver attach). No local-unprivileged syscall trigger on the audit guest (no HP Smart Array / no AMD GPU present).

Reproduce

./build.sh && ./run.sh

What the harness does

harness.c is a faithful userspace replica of the kernel parsing routine cited above, fed crafted controller/VBIOS data that the real malicious device would supply. It demonstrates the out-of-bounds access / overflow / underflow using the real kernel macros and struct sizes, with a canary or computed-index check to make the OOB observable without needing the hardware.

Expected output

A [BUG REPRODUCED] (or UNDERFLOW for DF-1199) marker plus the computed out-of-range index / overflow byte count / underflowed loop count. See run.log for the captured decisive run.

Fix

See fix.diff (git-apply-able) and VERDICT.md. The fix was validated to compile (module rebuilt with -Werror) β€” see fix_build.log. No live-kernel trigger exists on the guest, so the fix is validated at the applies + compiles + closes-the-code-path level.

Artifacts

VERDICT.md (full narrative), harness.c, build.sh, run.sh, run.log, env.txt, fix.diff, fix_build.log, manifest.json.

VERDICT.md verdict full narrative + fix
↓ download raw

DF-1191 β€” ciss_cam_complete unchecked controller sense_length (heap overflow)

Verdict

REPRODUCED (harness) β€” real bug confirmed by source trace + userspace replica. Impact class: heap overflow of union ccb (sense_data β†’ cdb_io/msg_ptr β†’ adjacent heap). No local-unprivileged trigger on the audit guest (no HP Smart Array controller); trigger requires a malicious/emulated CISS controller returning an oversized sense_length. uid=0 chain N/A β€” hardware/firmware-attacker class.

Mechanism (confirmed path:line)

ciss_cam_complete() copies controller-supplied sense data into the CAM ccb:

ce->sense_length is a u8 (0..255) supplied by the controller in its ErrorInfo struct (sys/dev/raid/ciss/cissreg.h:120). csio->sense_data is a struct scsi_sense_data of exactly SSD_FULL_SIZE = 32 bytes. There is no min()/imin() clamping the copy length, so a sense_length > 32 overwrites the fields that follow sense_data inside union ccb (cdb_io, msg_ptr) and the neighbouring heap object. The size is fully controller-controlled (0..255 β†’ up to 223 bytes past the buffer).

Threat surface: a malicious CISS controller, OR (where a ciss pass-through /dev/passN exists on hardware) an operator-issued command whose CHECK_CONDITION response the controller pads with an oversized sense_length. In all cases the length is controller-determined, not user-controlled β€” this is a malicious-controller bug, not a local-user-controlled write.

Harness proof (run.log)

harness.c replicates the bzero+bcopy against a 32-byte buffer with a 64-byte canary "neighbour" (standing in for the rest of union ccb):

sense_length= 32 : in-bounds (overflow into neighbor canary: 0 bytes, ...)
sense_length= 64 : OVERFLOW REPRODUCED (overflow into neighbor canary: 32 bytes, ...)
sense_length=255 : OVERFLOW REPRODUCED (overflow into neighbor canary: 32 bytes, ...)

Why not a live-kernel trigger / no uid0 chain

ciss attaches only to HP Smart Array PCI devices (none on the guest β†’ module never loaded). ce->sense_length is set by the controller firmware in its DMA'd ErrorInfo, reachable only through a controller that is present. No unprivileged syscall path controls it. Hardware/firmware-attacker class; no local-privesc chain.

Fix (fix.diff)

Clamp the copy length at ciss.c:3249: bcopy(&ce->sense_info[0], &csio->sense_data, imin(ce->sense_length, imin(SSD_FULL_SIZE, csio->sense_len))); imin is static __inline in sys/sys/libkern.h:70 (available kernel-wide). Matches the finding's proposed fix (clamp to imin(sense_length, SSD_FULL_SIZE, sense_len)).

Fix validation

ciss.ko rebuilt from patched source (DF-1190/1191/1192 applied) compiled with -Werror and linked β€” the imin(...) type-checks against the u_int8_t operands. fix_status: not_testable (no CISS HW for a live trigger; validated applies + compiles + closes the path by inspection).

Fix verification

not_testable

compile+harness validated

module build rc=0

Confirmed kernel references

β€”

Detail

Exploit chain

none

Evidence (decisive lines)

β€”

Verdict

REPRODUCED (harness). ciss_cam_complete sense_length u8 no clamp vs sense_data[32] -> 223B overflow. No HP controller.