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

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)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-1289 Β· 8 files
FileTypeDescriptionSize
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
README.md readme finding summary + why not reproduced
↓ download 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

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).

VERDICT.md verdict full narrative: mechanism, source citations, fix
↓ download raw

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: the pci/mly driver 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_testable

compile 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.