β¬’ 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.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
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 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.