⬢ DragonFlyBSD Kernel Audit
DF-3583 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-3583",
  "status": "inconclusive",
  "reproduced": 0,
  "impact": "none",
  "confidence": "certain",
  "verdict": "Kernel stack OOB read confirmed at source level and proven arithmetically on the guest with the real kernel headers: isp_intr()s RQSTYPE_RIO1 handler (sys/dev/disk/isp/isp.c:5093) loops `i < rio->req_header.rqs_seqno` over isp_rio1_t.req_handles[15] (ispmbox.h:866-871) where rqs_seqno is a full card-written 8-bit byte; seqno > 15 reads up to 960 bytes past the 64-byte stack buffer qe[]. The extracted-logic PoC faults at the first i == 16 iteration (run.log). Values are only used as completion-handle lookup keys (isp_fastpost_complete validates via ISP_VALID_INI_HANDLE), so impact is chance spurious command completion/stack-value disclosure into lookup keys \u2014 not a direct user-visible leak. Reachable only on Ultra3 SCSI cards (RIO 32-bit enabled by default, isp.c:1360-1361) with faulty/malicious firmware; guest has no QLogic HBA so the in-kernel path was not exercised. Modern FreeBSD removed RIO1 handling entirely.",
  "exploit_chain": "",
  "evidence": "run.log \u2014 sizeof(isp_rio1_t) = 64 (header 4 + req_handles[15]) and FAULT (SIGSEGV/SEGV) ... (loop reached i == 16, array holds 15); trigger_df3583.c; VERDICT.md; fix.diff (clamp to NELEM(req_handles))",
  "kernel_refs": [
    "sys/dev/disk/isp/isp.c:5087-5098",
    "sys/dev/disk/isp/isp.c:1360-1361",
    "sys/dev/disk/isp/ispmbox.h:316-321",
    "sys/dev/disk/isp/ispmbox.h:866-871"
  ],
  "poc_changes": "No seed (pass-2 new finding). Trigger written from scratch against the verbatim kernel headers; qe[64] placed flush against a PROT_NONE page so the first out-of-array read (i == 16) faults deterministically.",
  "attempts": 2,
  "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Thu Jul  2 06:02:54 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64",
  "runtime_sec": 90,
  "guest_dirty": 0,
  "build_cmd": "cc -Wall -I. -o trigger_df3583 trigger_df3583.c  (headers copied from /usr/src/sys/dev/disk/isp)",
  "run_cmd": "./trigger_df3583",
  "code_hash": "1b9635747c5eba439d1ea7646e213452d136ea018b7622424453ee1cfaad1b24",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": 0,
  "fix_patched_reproduced": 0,
  "fix_verdict": "fix.diff clamps the loop with NELEM(rio->req_handles); NELEM is already used in this file (isp.c:7163). Baseline not reproducible without hardware, so no patched-kernel A/B was possible; the clamp is a pure bounds correction.",
  "fix_evidence": "fix.diff (git-apply-able against sys/dev/disk/isp/isp.c hunk at line 5093)",
  "notes": "Robustness-against-faulty-hardware class (card is the trust boundary); same family as pass-1 DF-1125 (hw-driven length trusted) but distinct site and read-only impact.",
  "recommended_fix": "Clamp the RIO1 fast-post loop to NELEM(rio->req_handles) entries."
}