⬢ DragonFlyBSD Kernel Audit
DF-5328 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-5328",
  "status": "not_reproduced",
  "reproduced": false,
  "impact": "none observed; code-level race: camperiphfree() can free the periph inside cam_periph_alloc()s find()->flag-store window (UAF write into freed 144B M_CAMPERIPH chunk) and camperiphfree() can observe CAM_PERIPH_NEW_DEV_FOUND with an unpublished NULL deferred_callback -> indirect call through NULL/garbage",
  "confidence": "likely",
  "verdict": "cam_periph_alloc() touches periph->flags/deferred_callback/deferred_ac unlocked on the borrowed cam_periph_find() result; camperiphfree() (buses-locked remove + dtor + kfree, plus the flag read at :604) is not serialized against those stores. Bounded guest race (200 invalidate/rescan cycles x 4000 open/close churns, 90s) produced no hit -- the window is a few instructions wide and requires the dying periphs last reference to drop exactly as a rescan rediscovers the LUN (hot-plug/close race). Finding stands on the lock-domain analysis; not demonstrated at runtime.",
  "exploit_chain": "",
  "evidence": "VERDICT.md (full interleaving analysis), race.log (bounded attempt, no anomalies), README.md",
  "kernel_refs": [
    "sys/bus/cam/cam_periph.c:176",
    "sys/bus/cam/cam_periph.c:180",
    "sys/bus/cam/cam_periph.c:181",
    "sys/bus/cam/cam_periph.c:182",
    "sys/bus/cam/cam_periph.c:292",
    "sys/bus/cam/cam_periph.c:305",
    "sys/bus/cam/cam_periph.c:604",
    "sys/bus/cam/cam_periph.c:625",
    "sys/bus/cam/cam_periph.c:630"
  ],
  "poc_changes": "race rig built from the evilcd2 rig (invalidate/rescan sysctls already present); no seed existed",
  "attempts": 1,
  "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Fri Oct 2 21:19:55 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/EVIL  x86_64",
  "runtime_sec": 95,
  "guest_dirty": 0,
  "build_cmd": "cc -O -o race_fdchurn race_fdchurn.c",
  "run_cmd": "sh race_alloc.sh   # ~90s bounded loop",
  "code_hash": "2f1a831faec17fe2da1552b020a69488357f4e5e383d2ae19f5961374370e388",
  "notes": "window measured in instructions on the allocating thread; cannot be widened without patching sys/ (out of verification scope). FreeBSD restructured this area; DFly retains the borrowed-pointer pattern.",
  "recommended_fix": "perform the units-list lookup and the deferred bookkeeping under one xpt_lock_buses() hold, storing deferred_callback/deferred_ac BEFORE the NEW_DEV_FOUND flag (fix.diff)",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": false,
  "fix_patched_reproduced": false,
  "fix_verdict": "fix.diff authored from the analysis; not kernel-validated (race not reproduced at runtime)",
  "fix_evidence": "fix.diff; VERDICT.md lock-domain analysis"
}