ciss_init_pci: unvalidated firmware transport_offset maps ciss_perf outside the BAR window; ciss_init_perf writes through it
Summary
sc->ciss_perf = (cbase + cofs + sc->ciss_cfg->transport_offset) uses a firmware-controlled u32 with no window check (the existing check covers only the config table itself); ciss_init_perf then writes the fetch table, rq_size/rq_count and reply-queue addresses through that pointer - arbitrary-offset write relative to the BAR mapping on malicious/corrupted controller memory or a spoofed Smart Array on external PCIe. Upstream-inherited. Malicious/buggy-hardware threat model only. Fix compile-validated.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-3732 Β· 8 files| File | Type | Description | Size | |
|---|---|---|---|---|
| VERDICT.md | verdict | full narrative: mechanism, path:line, harness proof, fix | 2.8 KB | β raw |
| fix.diff | suggested-fix | validate cfg->transport_offset against the BAR window before mapping ciss_perf; else fall back to simple transport | 651 B | view raw |
| fix_apply.log | apply-log | patch --dry-run on guest /usr/src (clean) | 2.8 KB | view raw |
| fix_build.log | build-log | ciss.ko rebuilt with all 7 pass-2 fixes at -Werror, link rc=0 | 1.0 KB | view raw |
| env.txt | environment | guest uname, no-HW proof, module presence | 538 B | view raw |
| README.md | readme | human reproduce doc | 1.5 KB | β raw |
| manifest.json | manifest | this file | 1.9 KB | view raw |
| verdict.json | verdict | machine verdict (persist_poc.py schema) | 2.2 KB | view raw |
DF-3732 β ciss_init_pci: firmware-controlled transport_offset maps the Performant table outside the BAR window; ciss_init_perf writes through it
File: sys/dev/raid/ciss/ciss.c:692-695 β
sc->ciss_perf = (struct ciss_perf_config *)(cbase + cofs +
sc->ciss_cfg->transport_offset); with no bound on
transport_offset (the config-table check at ciss.c:646 validates only
cofs + sizeof(struct ciss_config_table) <= csize).
ciss_init_perf then writes the fetch table, queue sizes and reply-queue
address through that pointer (ciss.c:926-946).
Class: OOB write relative to the mapped BAR (CWE-787), fully firmware/PCIe-device controlled (malicious or corrupted controller memory / spoofed Smart Array on external PCIe). Upstream-inherited (FreeBSD has the identical code). Severity Low (malicious-hardware threat model; no unprivileged-local or remote trigger).
Verification status
Source-level certainty; inconclusive at runtime β the audit guest has no
HP Smart Array PCI device (env.txt), so neither the vulnerable mapping nor
the fix can be exercised live. The one-line bounds check in fix.diff
mirrors the existing ciss.c:646 pattern.
Fix
fix.diff (validate cofs + transport_offset + sizeof(struct ciss_perf_config)
<= csize, else fall back to the simple transport). Compile-validated:
applied together with the 6 other ciss pass-2 fixes, ciss.ko rebuilt at
-Werror, link rc=0 (fix_build.log, fix_apply.log).
Artifacts
VERDICT.md, fix.diff, fix_apply.log, fix_build.log, env.txt,
manifest.json, verdict.json.
DF-3732 VERDICT
Finding
During attach, ciss_init_pci() bounds-checks the CISS config table location
(cofs + sizeof(struct ciss_config_table) > csize β ENXIO, ciss.c:646-649),
then selects the Performant transport by pointer arithmetic on a second,
unvalidated firmware field:
/* sys/dev/raid/ciss/ciss.c:692-695 */
setup:
if ((supported_methods & CISS_TRANSPORT_METHOD_PERF) != 0) {
method = CISS_TRANSPORT_METHOD_PERF;
sc->ciss_perf = (struct ciss_perf_config *)(cbase + cofs +
sc->ciss_cfg->transport_offset); /* 32-bit FW value, unchecked */
transport_offset is a u_int32_t read out of adapter-mapped memory
(cissreg.h:414). Nothing constrains it to the BAR window (csize). With a
malicious/corrupted controller (or a spoofed Smart Array function on
externally-attacker-reachable PCIe, e.g. Thunderbolt-era chassis),
sc->ciss_perf can point anywhere within ~4 GB of the mapping base β and
ciss_init_perf() immediately writes through it:
/* sys/dev/raid/ciss/ciss.c:926-946 */
pc->fetch_count[...] = ...; /* 8 x u32 writes */
pc->rq_size = sc->ciss_max_requests;
pc->rq_count = 1;
pc->rq_bank_hi/lo = 0;
pc->rq[0].rq_addr_hi/lo = ...; /* host phys addresses written OOB */
Impact: arbitrary-offset kernel memory corruption relative to the BAR mapping (write of semi-controlled content: small integers + host physical addresses). Threat model is malicious/buggy hardware β the same trust boundary the rest of this driver's firmware-parsing findings use, but here there is no unprivileged-local or remote software trigger at all, hence Low.
Status
- Source-certain (the missing check is unambiguous; FreeBSD upstream has the same gap).
- Runtime: inconclusive β the audit guest has no HP Smart Array PCI
device (env.txt:
pciconf -l | grep -i 0e11|103cβ NONE), so neither the vulnerable path nor the fix is live-testable.
Fix validation
fix.diffadds the window check (mirroring the ciss.c:646 pattern) and falls back to the SIMPLE transport when it fails.fix_apply.log:patch --dry-runclean on the guest's/usr/src;fix_build.log:ciss.korebuilt with all 7 ciss pass-2 fixes at-Werror, link rc=0. No behavioral run possible (no hardware).
Bottom line: inconclusive at runtime (hardware absent), source-certain missing bounds check on a firmware-controlled pointer used for writes; fix compile-validated.
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
inconclusiveBounds check added (cofs+transport_offset+sizeof(perf config) <= csize, else fall back to SIMPLE). Compile-validated only: -Werror module build with all 7 fixes, link rc=0. No behavioral run possible (hardware absent).
fix.diff; fix_apply.log; fix_build.log
Confirmed kernel references
Detail
Exploit chain
malicious/corrupted controller config table -> transport_offset out of window -> ciss_init_perf writes OOB of mapping
Evidence (decisive lines)
VERDICT.md path analysis; env.txt (no HP PCI devices); fix_apply.log + fix_build.log
PoC changes
no runnable PoC possible without the device; source-level pack
Verified recommended fix
validate cfg->transport_offset against the BAR window before mapping ciss_perf; else fall back to simple transport
Verdict
INCONCLUSIVE at runtime (no HP Smart Array PCI device on the guest - env.txt), source-certain: sc->ciss_perf is computed as cbase+cofs+cfg->transport_offset (ciss.c:694-695) from an unvalidated firmware u32 (only the config table itself is checked at ciss.c:646) and ciss_init_perf writes the fetch table/queue config through it (ciss.c:926-946) -> arbitrary-offset write relative to the BAR on malicious/buggy hardware. Low severity (malicious-hardware threat model). Upstream-inherited.
No comments yet.