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.9 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 | 65 B | view raw |
| run.sh | run-script | no runtime PoC (HBA absent) | 89 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 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
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.