ciss_init_logical and ciss_free use <= instead of < on ciss_logical array (off-by-one OOB write/kfree)
Summary
ciss_init_logical at :1376 iterates i<=ciss_max_logical_bus (should be <) writing kmalloc pointer one past end of ciss_logical array. ciss_free at :1953 mirrors bug, reading OOB pointer and calling kfree on it. Off-by-one heap pointer overflow at attach + kfree-of-garbage at detach. Fix: change <= to <.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-1194 Β· 9 files| File | Type | Description | Size | |
|---|---|---|---|---|
| VERDICT.md | verdict | source-level analysis: <= vs < off-by-one in ciss_init_logical and ciss_free | 2.6 KB | β raw |
| fix.diff | suggested-fix | change <= to < in both loops | 887 B | view raw |
| build.sh | build-script | no-op (no userspace PoC; hardware-gated) | 444 B | view raw |
| run.sh | run-script | no-op (no HP controller on guest) | 264 B | view raw |
| fix_build.log | build-log | cumulative kernel build with all 5 fixes applied, NK_DONE rc=0 | 5.6 MB | β download |
| env.txt | environment | guest uname, PCI topology, target HW required | 1.2 KB | view raw |
| README.md | readme | human reproduce doc | 897 B | β 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 |
DF-1194 β ciss off-by-one (<= vs <) (build/run scripts)
Hardware-gated (HP Smart Array ciss). See VERDICT.md for source-level
confirmation. No runtime PoC possible on this guest.
Files
VERDICT.mdβ detailed source-level analysisfix.diffβ git-apply-able patch changing<=to<in two loopsenv.txtβ guest environment snapshotfix_build.logβ kernel-build output (cumulative batch)
build.sh
#!/bin/sh
echo 'build.sh: no userspace PoC for DF-1194 (hardware-gated driver bug).'
echo 'To validate the fix, apply fix.diff and build a kernel:'
echo ' cd /usr/src && patch -p1 < fix.diff && make -j6 nativekernel KERNCONF=X86_64_GENERIC'
run.sh
#!/bin/sh
echo 'run.sh: DF-1194 is hardware-gated (HP Smart Array ciss).'
echo 'No HP controller is present on this guest.'
echo 'See VERDICT.md for the source-level confirmation.'
DF-1194 β ciss_init_logical / ciss_free off-by-one (<= vs <)
Verdict
NOT REPRODUCED (source-confirmed; hardware-gated). The off-by-one is real and unambiguous in the source, but the ciss driver only attaches to HP Smart Array controllers, absent on this QEMU/KVM guest. No runtime trigger; validated by line-level source trace + a single-fix kernel build.
Mechanism
sc->ciss_logical is declared struct ciss_ldrive **ciss_logical
(cissvar.h:230) β a pointer to an array of struct ciss_ldrive * pointers.
At ciss.c:1372-1374 the backing array is allocated as
sc->ciss_logical =
kmalloc(sc->ciss_max_logical_bus * sizeof(struct ciss_ldrive *),
CISS_MALLOC_CLASS, M_INTWAIT | M_ZERO);
i.e. with ciss_max_logical_bus slots (indices 0..ciss_max_logical_bus-1).
The very next loop at ciss.c:1376, however, runs inclusive of the upper
bound:
for (i = 0; i <= sc->ciss_max_logical_bus; i++) {
sc->ciss_logical[i] = kmalloc(CISS_MAX_LOGICAL * sizeof(struct ciss_ldrive),
CISS_MALLOC_CLASS, M_INTWAIT | M_ZERO);
...
}
The final iteration writes one struct ciss_ldrive * past the end of the
allocation β a classic off-by-one heap overflow into whatever the slab
allocator places immediately after ciss_logical. ciss_free at
ciss.c:1953 repeats the same <= mistake, reading the OOB pointer and
calling kfree on it during detach: kfree-of-garbage (an attacker-controlled
kmalloc target in the same slab bucket would be freed).
This is exactly the kind of off-by-one that INVARIANTS slab poisoning
(WEIRD_ADDR/chunk_mark_allocated) frequently catches and panics on, even
without an attacker; the bug fires on every attach/detach of a controller
with ciss_max_logical_bus >= 1 (which is the initialized minimum,
ciss.c:1473).
Why not triggered on this guest
Same as DF-1193: no HP Smart Array PCI device is present, so ciss_attach (and therefore ciss_init_logical / ciss_free) is never invoked. Option (d) of the PoC-runner procedure.
Recommended fix (in fix.diff)
Change <= to < in both loops (ciss.c:1376 and ciss.c:1953). One
character each, surgical, matches the loop bound everywhere else in the file
that iterates over ciss_max_logical_bus (lines 1039, 1883, 2778, 2873, 3872,
4288 all use strict <).
Build validation
Cumulative kernel build with all 5 fixes applied β NK_DONE rc=0, no errors.
See fix_build.log.
Reproduce
./build.sh # no-op (no trigger source for hardware-gated bug) ./run.sh # no-op (no HP Smart Array controller on guest)
Fix verification
not_testablecompile validated
nativekernel rc=0
Confirmed kernel references
β
Detail
Exploit chain
none
Evidence (decisive lines)
β
Verdict
Source-confirmed. ciss_init_logical/free <= vs < off-by-one slab write + kfree-of-garbage. ciss in GENERIC, no HP HW.
No comments yet.