DF-3823 / verdict.json
{ "finding_id": "DF-3823", "status": "inconclusive", "reproduced": 0, "impact": "none", "confidence": "certain", "verdict": "asr_intr() converts the adapter-posted FromFIFO value into a kernel pointer (ReplyOffset - ha_Msgs_Phys + ha_Msgs, asr.c:2890-2891) with no check that it lies inside the ha_Msgs reply pool. An out-of-window offset (faulty or malicious IOP) yields a forged PI2O_SCSI_ERROR_REPLY_MESSAGE_FRAME whose InitiatorContext64 (raw u64 load, asr.c:2896-2898) becomes a union asr_ccb * that ASR_ccbRemove (asr.c:2971, 785-792) writes through: callout_stop on a forged callout pointer plus LIST_REMOVE unlink writes, then status/resid/sense writes and xpt_done dispatch - a device-driven arbitrary kernel write engine. The FAIL branch additionally uses the device-supplied PreservedMFA as unbounded bus-space offsets for MMIO read/write (asr.c:2917-2921, 2948-2949). Guest has no I2O HBA (/dev/asr0 ENOENT, zero vendor-0x1044 PCI devices) so asr_intr never runs; source analysis certain. Note the same function clamps its sense lengths four ways (asr.c:3033-3042) - the offset mapping was simply never validated.", "exploit_chain": "device: post out-of-window ReplyOffset -> forged Reply over DMA-controlled memory -> chosen InitiatorContext64 -> forged ccb -> callout_stop + LIST_REMOVE unlink writes + sense bcopy -> kernel code execution. Precondition: compromised/faulty IOP firmware.", "evidence": "VERDICT.md step-by-step trace with line refs; fix.diff (pool-window validation); ../DF-3825/run.log + ../DF-3819/env.txt (no asr hardware on guest)", "kernel_refs": ["sys/dev/raid/asr/asr.c:2890", "sys/dev/raid/asr/asr.c:2896", "sys/dev/raid/asr/asr.c:2917", "sys/dev/raid/asr/asr.c:2948", "sys/dev/raid/asr/asr.c:1910", "sys/dev/raid/asr/asr.c:785"], "poc_changes": "No seed; analysis pack (interrupt-time device data cannot be synthesized without the HBA).", "attempts": 1, "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026 X86_64_GENERIC x86_64", "runtime_sec": 0, "guest_dirty": 0, "build_cmd": null, "run_cmd": null, "code_hash": null, "notes": "Reply-frame-walk hunt item (b). FreeBSD ancestor shares the defect. Severity Low: hardware precondition, but primitive is arbitrary kernel write once held.", "recommended_fix": "Validate ReplyOffset against [ha_Msgs_Phys, ha_Msgs_Phys + ha_Msgs_Count*sizeof(frame)) before forming Reply (asr.c:2890).", "fix_status": "not_testable", "fix_baseline_reproduced": 0, "fix_patched_reproduced": 0, "fix_verdict": "Baseline and fix runs both require an asr IOP posting frames; absent on the guest. fix.diff adds the pool-window check.", "fix_evidence": "fix.diff" } |