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

ciss_init_logical: unbounded CISS_LUN_TO_BUS/TARGET at attach yields kernel OOB write of pointers and objects

Summary

ciss_init_logical at ciss.c:1386-1406: CISS_LUN_TO_BUS (8-bit 0-255) and CISS_LUN_TO_TARGET (8-bit 0-255) from controller REPORT_LOGICAL_LUNS used to index ciss_logical[bus][target] with NO bounds check. ld->cl_controller=&sc->ciss_controllers[bus] writes OOB pointer. ciss_identify_logical kmallocs into OOB ld->cl_ldrive/cl_lstatus. Malicious/emulated CISS PCI device at attach. Fix: validate bus<max_logical_bus and target<CISS_MAX_LOGICAL.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-1190 Β· 11 files
FileTypeDescriptionSize
harness.c trigger-source userspace replica of ciss_init_logical OOB-index loop with real CISS_LUN_TO_BUS/TARGET macros 4.0 KB view raw
VERDICT.md verdict full narrative: mechanism, path:line, harness proof, fix 4.0 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 decisive run: 2 OOB index accesses 635 B view raw
env.txt environment uname, cc version, module/threat-model notes 418 B view raw
fix.diff suggested-fix validate bus<max_logical_bus && target<CISS_MAX_LOGICAL before indexing 556 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-1190 β€” ciss_init_logical out-of-range bus/target index -> OOB write

File: sys/dev/raid/ciss/ciss.c:1391-1396 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: mechanism, path:line, harness proof, fix
↓ download raw

DF-1190 β€” ciss_init_logical out-of-range bus/target index (OOB write)

Verdict

REPRODUCED (harness) β€” real bug confirmed by source trace + userspace replica. Impact class: kernel heap OOB write / OOB pointer store. No local-unprivileged trigger on the audit guest (no HP Smart Array controller); trigger requires a malicious/emulated CISS PCI device at driver attach. uid=0 escalation chain is N/A β€” this is a hardware/firmware-attacker primitive (driver-probe time), not a syscall-driven local-privesc path.

Mechanism (confirmed path:line)

ciss_init_logical() (sys/dev/raid/ciss/ciss.c) walks the controller's REPORT_LOGICAL_LUNS reply and decodes each LUN's 8-bit bus and target from controller-supplied data:

The index macros (sys/dev/raid/ciss/cissreg.h:509-510) yield 0..255 for each of bus and target, but the arrays are far smaller: - ciss_logical is ciss_max_logical_bus rows Γ— CISS_MAX_LOGICAL(15) cols (cissvar.h:49, allocated at ciss.c:1372-1383), - ciss_controllers is ciss_max_logical_bus entries (ciss.c:1484-1486).

There is no bounds check between decoding bus/target and indexing. With bus >= ciss_max_logical_bus or target >= 15: 1. sc->ciss_logical[bus] reads an out-of-bounds pointer (row pointer past the array), 2. ld->cl_controller = &sc->ciss_controllers[bus] writes an OOB kernel pointer into the corrupted ld (ciss.c:1396), 3. ciss_identify_logical(sc, ld) then kmallocs into ld->cl_ldrive / ld->cl_lstatus (ciss.c:1397) β€” controlled heap writes through the OOB-corrupted ld.

The earlier sanity check at ciss.c:1357 only bounds ndrives (the count) to CISS_MAX_LOGICAL; it does not validate the per-LUN bus/target encodings.

Harness proof (run.log)

harness.c replicates the exact loop with the real CISS_LUN_TO_BUS / CISS_LUN_TO_TARGET macros and a ciss_max_logical_bus=1 layout, feeding a forged LUN with bus=200/target=250 and another with bus=0/target=40:

[!] OOB index drive=0 bus=200 (max 1) target=250 (max 15) -> writes ciss_logical[200][250] + ciss_controllers+200
[!] OOB index drive=1 bus=0 (max 1) target=40 (max 15) -> writes ciss_logical[0][40] + ciss_controllers+0
[BUG REPRODUCED] 2 out-of-range index accesses observed

Why not a live-kernel trigger / no uid0 chain

ciss is a module (/boot/kernel/ciss.ko, device ciss in X86_64_GENERIC:115) that attaches only to HP Smart Array PCI devices (ciss_pci_attach). The audit QEMU guest has no CISS controller, so the module is never loaded/attached (kldstat shows neither). The malicious data comes from the PCI device's REPORT_LOGICAL_LUNS DMA response at probe time β€” it is not reachable from any unprivileged userspace syscall. Driving it live would require either (a) a malicious physical/emulated CISS PCI device (a hardware-attacker / VFIO-passthrough threat) or (b) kldload+crafted device (root-only). Per the audit's realism bar this is a hardware/firmware-attacker class finding: valid primitive (confirmed here at the harness level), but no unprivileged local escalation path exists on a default guest.

Fix (fix.diff)

Validate bus < ciss_max_logical_bus and target < CISS_MAX_LOGICAL before indexing, at ciss.c:1393. One logical change; compiles cleanly (-Werror) in the rebuilt ciss.ko.

Fix validation

Built ciss.ko from patched source (with DF-1190/1191/1192 applied) β€” compiled with -Werror and linked (/usr/obj/usr/src/sys/dev/raid/ciss/ciss.ko, 61664 B), new "logical drive %d has out-of-range address" string present. No live kernel trigger available on the guest (no CISS HW), so the fix is validated at the applies + compiles + closes-the-code-path level (the honest bar for a hardware-only driver bug), fix_status: not_testable.

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_init_logical CISS_LUN_TO_BUS/TARGET no bounds -> OOB index. No HP controller.