⬢ DragonFlyBSD Kernel Audit
DF-3653 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-3653",
  "status": "inconclusive",
  "reproduced": 0,
  "impact": "none",
  "confidence": "certain",
  "verdict": "Source-certain NULL deref, hardware-gated runtime. amdgpu_dm_atomic_commit_tail() calls update_stream_scaling_settings(..., dm_new_crtc_state->stream) at amdgpu_dm.c:4882 BEFORE the NULL check at 4885; update_stream_scaling_settings() only guards !mode (2473) and mode is &crtc->mode (embedded struct, never NULL), so stream->timing.h_addressable (2479) faults at VA 0x10 on amd64 (sink ptr + h_total + h_border_left). Deterministic trigger by a DRM-master local client in 3 atomic commits: disable CRTC; attach connector with MODE_ID set but ACTIVE=0 (stream is never created because modereset_required() short-circuits on active==0 at 5293-5294, and the BUG_ON at 5344 is skipped by the active term at 5333-5335); then change only underscan properties (CRTC enters the state via drm_atomic_get_connector_state, drm_atomic.c:819-826; needs_modeset false; is_scaling_state_different true) -> commit tail enters the scaling block with stream==NULL -> panic. The userspace model (verbatim struct field order) SIGSEGVs at the identical 0x10 offset on the guest (run.log EXIT=139). Guest is virtio-only with no AMD display device (env.txt), so the kernel path itself cannot execute: inconclusive overall; impact ceiling is local DoS (panic) via DRM_IOCTL_MODE_ATOMIC (DRM_MASTER, drm_ioctl.c:681) \u2014 no disclosure/control primitive (fixed-VA NULL read).",
  "exploit_chain": "Local user with DRM master (console when no compositor runs, or a malicious compositor): atomic commit 1 disables the CRTC and detaches the connector; commit 2 re-attaches the connector with a mode but ACTIVE=0 leaving dm_crtc_state->stream==NULL while connector->state->crtc points at the enabled-but-inactive CRTC; commit 3 sets underscan=1 + hborder/vborder=1 on the connector only -> amdgpu_dm_atomic_commit_tail enters the scaling block with !needs_modeset -> update_stream_scaling_settings dereferences NULL stream at 0x10 -> kernel page fault/panic. Requires a connected (or forced) display so mode_valid passes in commit 2.",
  "evidence": "run.log (offsetof=0x10 trace then SIGSEGV EXIT=139); VERDICT.md (full 3-commit source trace with drm_atomic.c/drm_atomic_helper.c line proofs); fix.diff (guard moved before the call; git apply --check clean); env.txt (guest has no AMD GPU: pciconf 0x1002 count 0, /dev/dri absent)",
  "kernel_refs": [
    "sys/dev/drm/amd/display/amdgpu_dm/amdgpu_dm.c:4882",
    "sys/dev/drm/amd/display/amdgpu_dm/amdgpu_dm.c:4885",
    "sys/dev/drm/amd/display/amdgpu_dm/amdgpu_dm.c:2479",
    "sys/dev/drm/amd/display/amdgpu_dm/amdgpu_dm.c:5293",
    "sys/dev/drm/amd/display/amdgpu_dm/amdgpu_dm.c:5333",
    "sys/dev/drm/amd/display/amdgpu_dm/amdgpu_dm.c:5344",
    "sys/dev/drm/drm_atomic.c:819",
    "sys/dev/drm/drm_ioctl.c:681"
  ],
  "poc_changes": "no seeded PoC for pass-2; harness written fresh \u2014 models the commit-tail decision sequence and replicates the verbatim dc_stream_state/dc_crtc_timing field order so the fault address (0x10) equals the kernels",
  "attempts": 1,
  "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": 95,
  "guest_dirty": 0,
  "build_cmd": "cc -O2 -Wall -o harness harness.c",
  "run_cmd": "./harness",
  "code_hash": "a3024949615f1167baf5084462dca6cd20962273c52bb858ba82bbf85ca4dd5c",
  "notes": "pass 2 amdgpu_dm.c; sibling of the DF-1152 BUG_ON family but a distinct location (commit tail vs atomic check) with a distinct deterministic trigger; guest scratch files removed after run",
  "recommended_fix": "Move the !dm_new_crtc_state->stream check before the update_stream_scaling_settings() call in amdgpu_dm_atomic_commit_tail().",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": 0,
  "fix_patched_reproduced": 0,
  "fix_verdict": "Fix validation requires AMD display hardware (driver cannot attach on the virtio-only guest). fix.diff moves the NULL guard before the call \u2014 with it, commit 3 skips the scaling update exactly as the atomic-check phase (amdgpu_dm.c:5333-5344) already does. git apply --check verified against sys/; not applied (read-only audit target).",
  "fix_evidence": "fix.diff in this pack; applies cleanly per git apply --check"
}