Heap overflow of CAM CCB sense buffer from untrusted controller sense_length
Summary
mly_cam_complete at mly.c:2356-2358: bcopy(mc->mc_packet,&csio->sense_data,mc->mc_sense). mc->mc_sense from controller status mailbox (u8 0-255, :1567). sense_data is SSD_FULL_SIZE=32 bytes. No min(mc_sense,SSD_FULL_SIZE). Malicious/buggy HBA returns sense_length>32 -> up to 223B heap overflow of CAM CCB. Sibling of DF-1281. Fix: bcopy(...,min(mc_sense,SSD_FULL_SIZE)).
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-1289 Β· 8 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | readme | finding summary + why not reproduced | 2.9 KB | β raw |
| VERDICT.md | verdict | full narrative: mechanism, source citations, fix | 2.6 KB | β raw |
| fix.diff | suggested-fix | clamp bcopy length to min(mc->mc_sense, SSD_FULL_SIZE) | 601 B | view raw |
| build.sh | build-script | no PoC binary; points at kernel build | 357 B | view raw |
| run.sh | run-script | no runtime PoC (HBA absent) | 326 B | view raw |
| env.txt | environment | pciconf -l + kldstat -v + uname + cc version | 862 B | view 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-1289 β mly CAM CCB sense buffer heap overflow
Finding
mly_cam_complete at sys/dev/raid/mly/mly.c:2357 copies controller-supplied
sense data into a CAM CCB's sense_data field with no length clamp:
bcopy(mc->mc_packet, &csio->sense_data, mc->mc_sense);
mc->mc_sense is a u_int8_t (sys/dev/raid/mly/mlyvar.h:132) loaded directly
from the controller status mailbox at mly.c:1567:
mc->mc_sense = sp->status.sense_length;. The destination sense_data is
sizeof(struct scsi_sense_data) = SSD_FULL_SIZE = 32 bytes
(sys/bus/cam/scsi/scsi_all.h:953). A buggy or malicious Mylex AcceleRAID/
eXtremeRAID controller that returns sense_length up to 255 therefore drives a
heap overflow of up to 223 bytes past csio->sense_data.
Why we did not reproduce at runtime
The mly driver attaches only to Mylex PCI RAID HBAs (vendor 1069). The
audit guest is a QEMU/KVM VM with no Mylex hardware β the only PCI devices
present are Intel PIIX3/PIIX4 + virtio-net + virtio-blk + QEMU std VGA
(pciconf -l in env.txt). The driver is compiled into the GENERIC kernel
(sys/config/X86_64_GENERIC:122 device mly) but devclass_get_softc returns
NULL for every unit, so the buggy path is unreachable on this guest. There is
no userspace syscall path to the affected function β it is only invoked from
the controller's command-completion interrupt handler.
Source-level confirmation
sys/dev/raid/mly/mly.c:2357βbcopy(mc->mc_packet, &csio->sense_data, mc->mc_sense);(no clamp)sys/dev/raid/mly/mlyvar.h:132βu_int8_t mc_sense;(range 0..255)sys/dev/raid/mly/mly.c:1567βmc->mc_sense = sp->status.sense_length;(controller-DMA-derived)sys/bus/cam/scsi/scsi_all.h:953β#define SSD_FULL_SIZE sizeof(struct scsi_sense_data)= 32
The bug is real. The sibling finding DF-1281 reports the same defect on the
mly_user_command path (mly.c:1129-1131).
How to reproduce the source defect
This is a hardware-driver finding that cannot be exercised on a guest lacking
the device. To validate the fix, build the patched kernel (see fix.diff) β
the length is now clamped: bcopy(..., min(mc->mc_sense, SSD_FULL_SIZE));.
Realistic impact ceiling
A malicious or faulty Mylex HBA (or a PCI-attached FPGA the attacker controls)
can overflow a CAM ccb_hdr_path/csio allocation by up to 223 bytes. Because
the CCB is allocated from a generic CAM bucket, this is a kernel heap overflow
of attacker-shaped bytes. On the default GENERIC kernel (INVARIANTS ON) the
slab poisoning checks would likely catch the corruption; on a non-debug kernel
the primitive could in principle be groomed for privilege escalation. The
realistic threat model is "hostile PCI device" or "faulty HBA firmware",
which is narrower than an unprivileged-local attack.
Build
No PoC binary β this finding is not exercisable without the HBA. The fix
compiles cleanly (see fix_build.log).
DF-1289 β mly CAM CCB sense buffer heap overflow
Verdict
NOT REPRODUCED β real source-level bug confirmed by line-by-line trace;
unreachable at runtime on this guest because the mly driver attaches
only to Mylex PCI RAID HBAs (PCI vendor 1069) and the audit QEMU/KVM guest has
none.
Mechanism (verified)
mly.c:1567:mc->mc_sense = sp->status.sense_length;β controller-DMA-derived u8.mly.c:2354: SCSI_STATUS_CHECK_COND handler.mly.c:2356:bzero(&csio->sense_data, SSD_FULL_SIZE);β destination is SSD_FULL_SIZE=32 bytes.mly.c:2357:bcopy(mc->mc_packet, &csio->sense_data, mc->mc_sense);β no clamp. mc_sense β [0,255] β up to 223-byte overflow.
Sink confirmed; no bounds check anywhere upstream. The sibling finding
DF-1281 (mly.c:1129-1131) is the same defect on a different code path and
was independently fixed via the same min(.., SSD_FULL_SIZE) clamp on the
user-command path. DF-1289 is the CAM-completion path that the sibling fix did
not cover.
Why not triggered on this guest
pciconf -l: only Intel PIIX3/PIIX4 + virtio-net + virtio-blk + std-VGA. No vendor-1069 device.kldstat -v | grep mly: thepci/mlydriver is compiled in but never attaches (devclass_get_softcβ NULL).- No syscall path leads to
mly_cam_completeβ it fires only from the HBA's command-completion interrupt.
Per Phase 4(d) of the procedure (genuinely not reachable on this kernel β the
sink is behind an absent device), this is recorded as not_reproduced. The
bug itself is real and the fix is necessary.
Fix
fix.diff clamps the bcopy length:
bcopy(mc->mc_packet, &csio->sense_data,
min(mc->mc_sense, SSD_FULL_SIZE));
Matches the approach taken for DF-1281. min() and SSD_FULL_SIZE are
already in scope (<sys/systm.h> is included at line 31; scsi_all.h is
pulled in via the CAM headers).
Fix validation
The fix compiles cleanly as part of make -j6 nativekernel KERNCONF=X86_64_GENERIC (see fix_build.log). A runtime before/after test is not
testable on this guest: there is no Mylex HBA, so neither the unpatched nor
the patched kernel can reach the affected code path. fix_status: not_testable
reflects this honestly.
Realistic impact ceiling
Heap overflow of up to 223 attacker-influenced bytes into a CAM CCB, but only reachable from a malicious/faulty Mylex HBA (hostile-PCI-device threat model). On default GENERIC (INVARIANTS ON) the slab checks would likely catch the overflow; on a non-debug kernel the primitive is in principle groomable. The fix is correct and minimal regardless of exploitability.
Fix verification
not_testablecompile validated
nativekernel rc=0
Confirmed kernel references
β
Detail
Exploit chain
none
Evidence (decisive lines)
β
Verdict
Source-confirmed. mly_cam_complete sense bcopy no clamp vs SSD_FULL_SIZE=32 -> up to 223B heap OOB write. mly in GENERIC, no Mylex HW.
No comments yet.