{
  "finding_id": "DF-5284",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "leak",
  "confidence": "certain",
  "verdict": "Uninitialized kernel heap transmitted to the device in a SCSI MODE SELECT command. sasetparams() allocates ccomp without M_ZERO (scsi_sa.c:2757); when the embedded sagetparams() EINVAL fallback sets SA_QUIRK_NOCOMP it returns without filling *tcs, so 16 bytes of stale kernel heap are bcopyd into the MODE SELECT page (scsi_sa.c:2796), the driver branches on the uninitialized pagecode byte (scsi_sa.c:2863), and - when that stale byte is 0x10/0x0f - transmits the buffer to the device (scsi_sa.c:2954). Reproduced deterministically (first MTCOMP attempt) on a same-source no-INVARIANTS kernel with a heap groom: the captured 28-byte MODE SELECT carries a live slab-freelist pointer (0xfffff8004f0b1e.. range) and the marker kernel pointer &ev_lock (0xffffffff8260d5c0) in its 16 uninitialized bytes, stable across 3 runs. On the stock INVARIANTS audit kernel the transmit is masked (kmalloc poisons bytes[0..7] with -1, forcing the default/ENODEV branch) but the uninitialized-memory use is still visible: the kernel logs device does not seem to support compression, i.e. it branched on the uninitialized byte. With fix.diff (M_ZERO) the payload is zeroed and no 28-byte MODE SELECT occurs.",
  "exploit_chain": "evil tape device: MODE SENSE page 0x0f -> CAM_REQ_INVALID (EINVAL), page 0x10 -> CAM_REQ_INVALID -> sagetparams fallback sets NOCOMP and returns success without touching *tcs -> victim/operator issues MTCOMP (mt comp) -> sasetparams bcopy(ccomp, cpage, 16) with ccomp = kmalloc(16) without M_ZERO -> groomed freelist chunk returns with byte0=0x10 -> dconf branch -> MODE SELECT(6) len 28 carries the 16 uninit bytes to the device (two kernel pointers per call, repeatable per fresh mount)",
  "evidence": "run.log + dmesg lines: [EVILSA] MODE SELECT #1 len 28 payload[12..27]: 10 1e 0b 4f 00 f8 ff ff c0 d5 60 82 ff ff 01 ff - bytes[13..19]=heap freelist pointer, bytes[20..27]=&ev_lock marker (byte 26 overwritten by calg=1); run.inv-kernel.log ((sa0): device does not seem to support compression = branch on uninit byte); probe16 hexdumps showing the marker sitting in the returned chunks; run.patched.log (post-fix: ENODEV, no 28-byte MODE SELECT, no markers)",
  "kernel_refs": [
    "sys/bus/cam/scsi/scsi_sa.c:2757",
    "sys/bus/cam/scsi/scsi_sa.c:2569",
    "sys/bus/cam/scsi/scsi_sa.c:2601",
    "sys/bus/cam/scsi/scsi_sa.c:2796",
    "sys/bus/cam/scsi/scsi_sa.c:2863",
    "sys/bus/cam/scsi/scsi_sa.c:2954",
    "sys/bus/cam/scsi/scsi_sa.c:3009"
  ],
  "poc_changes": "evilsa KLD (adapted from DF-5271 evilcd rig): T_SEQUENTIAL inquiry, mode-sense/mode-select choreography, 16B marker spray with address-selected free order so the chunk returned to ccomp has freelist-linkage byte0=0x10; poc_comp userland trigger flips the device personality after mount. One rig bug fixed mid-run (int aidx[4096] kernel-stack overflow -> .bss).",
  "attempts": 4,
  "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT X86_64_NOINV #0: Fri Oct 2 02:12:33 UTC 2026 (leak reproduced; INVARIANTS stock build masked the transmit leg, see notes)",
  "runtime_sec": 1600,
  "guest_dirty": 1,
  "build_cmd": "cd /root/df5284 && touch opt_cam.h && make && cc -O -o poc_comp poc_comp.c",
  "run_cmd": "sh run.sh (kldload evilsa.ko; usched :1 ./poc_comp /dev/nsa0)",
  "code_hash": "evilsa.c: 968557745b0f060df9477a1280e6b4db9a7dbc0e807c5921babe83937a457d06, poc_comp.c: 9462d288ef3e10bc9aea8f49057d626f70c189569ad5204e60de813ba4d43207",
  "notes": "INVARIANTS kernels poison non-M_ZERO kmalloc bytes[0..7] with (void*)-1 making the uninit pagecode 0x7f -> ENODEV before transmit; production kernels ship without INVARIANTS where the leak is heap-groomable and deterministic (proved: 3/3 first-attempt hits). The MARKER HIT kprintf verdict line in evilsa mis-flags (rig cosmetic bug); the hexdump itself shows the marker bytes - decode documented in VERDICT.md. Trigger (MTCOMP) requires an open sa node (SYSCAP_RESTRICTEDROOT) or the device itself; the data crossing the trust boundary is kernel heap.",
  "recommended_fix": "kmalloc ccomp with M_ZERO in sasetparams() (fix.diff hunk 4; also M_ZERO for rblim and the DF-5285 min_blk guard).",
  "fix_status": "fixed",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "Same-source X86_64_NOINV kernel rebuilt with fix.diff: identical PoC now returns ENODEV from MTCOMP (zeroed pagecode takes the default branch) and no 28-byte MODE SELECT is captured - the uninitialized bytes no longer reach the command buffer.",
  "fix_evidence": "run.patched.log (attempt 0: ENODEV, msel28 stays 0); fix_build.log"
}