⬢ DragonFlyBSD Kernel Audit
DF-4182 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-4182",
  "status": "inconclusive",
  "reproduced": 0,
  "impact": "none",
  "confidence": "likely",
  "verdict": "Source-certain completion-path dead-end: radeon_flip_work_funcs enabled check (radeon_display.c:449) only guards the vblank wait loop; when the CRTC was disabled while the flip was pending the work still programs the flip on the disabled CRTC (:467) and sets flip_status=RADEON_FLIP_SUBMITTED (:469). A disabled CRTC raises no vblank/pflip irqs and radeon_crtc_handle_flip (:359/:381, the ONLY reset of flip_status anywhere in radeon) never runs: every later DRM_IOCTL_MODE_PAGE_FLIP on that CRTC returns EBUSY forever (:578-583), the queued vblank event is never delivered, and the drm_crtc_vblank_get reference taken by the ioctl core (drm_plane.c:1053) leaks (put is at :390 in the completion path). Unprivileged-reachable race (DRM master; window = fence wait, ms..s, widenable by GPU load). Local DoS of the CRTCs flip path until module reload. Not exercisable on this guest: no GPU, no /dev/dri (run.log).",
  "exploit_chain": "",
  "evidence": "VERDICT.md (state machine + grep proof that nothing else resets flip_status); rflip_wedge.c (race sequence + raw ioctl scaffolding); run.log (no GPU, build OK); fix.diff (radeon.h + radeon_display.c abort path) + fix_build.log (radeon.ko built -Werror with fix)",
  "kernel_refs": [
    "sys/dev/drm/radeon/radeon_display.c:449",
    "sys/dev/drm/radeon/radeon_display.c:467",
    "sys/dev/drm/radeon/radeon_display.c:469",
    "sys/dev/drm/radeon/radeon_display.c:381",
    "sys/dev/drm/radeon/radeon_display.c:390",
    "sys/dev/drm/radeon/radeon_display.c:578",
    "sys/dev/drm/radeon/radeon_display.c:592",
    "sys/dev/drm/drm_plane.c:1053"
  ],
  "poc_changes": "n/a (first-pass PoC authored in this run; the full race needs libdrm modeset plumbing documented in README)",
  "attempts": 1,
  "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #0: Thu Jul  2 06:02:54 UTC 2026 x86_64",
  "runtime_sec": 10,
  "guest_dirty": 1,
  "build_cmd": "cc -O -Wall -o rflip_wedge rflip_wedge.c",
  "run_cmd": "./rflip_wedge /dev/dri/card0 (full race needs libdrm: enable -> PAGE_FLIP -> disable -> re-enable -> PAGE_FLIP probe)",
  "code_hash": "9b1e36c87ccd319d466c263d085725b4601eedbc0d6b9d64d4f00cb914dc3008",
  "notes": "A narrow residual race remains after the fix (CRTC disabled between the enabled check and radeon_page_flip) - inherent to this legacy non-atomic flip design; the fix closes the persistent wedge which is the exploitable state. Related pin-leak shape: pflip_cleanups radeon_bo_reserve failure path (radeon_display.c:596-599) skips unpin, but reserve(intr=false) on a ww_mutex cannot fail there - dead code, not filed.",
  "recommended_fix": "Abort the flip in radeon_flip_work_func when !radeon_crtc->enabled: reset flip_status/flip_work, drm_crtc_vblank_put, deliver the event, unpin the new BO (stashed in struct radeon_flip_work) and queue the unpin work.",
  "fix_status": "inconclusive",
  "fix_baseline_reproduced": 0,
  "fix_patched_reproduced": 0,
  "fix_verdict": "Compile-validated only: fix.diff (radeon.h struct member + abort path in radeon_flip_work_func) applied cleanly and radeon.ko built with -Werror in the batch nativekernel build (fix_build.log). Behavioral test impossible on this guest (no GPU; race needs a real CRTC).",
  "fix_evidence": "fix_build.log excerpt (radeon_display.c -Werror KLD_MODULE compile + radeon.ko link)."
}