⬢ DragonFlyBSD Kernel Audit
DF-5004 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-5004",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "panic",
  "confidence": "certain",
  "verdict": "REPRODUCED (function-level, deterministic, on-guest): verbatim copies of amdgpu_pll.c:44-251 divide by zero for attacker-representable modeset inputs beyond DF-2037s target_clock==0/post_div==0 windows \u2014 (a) target_clock in [1, ref/254] (freq 10..109, non-FRAC, std 27MHz ref) forces fb_div=DIV_ROUND_CLOSEST(nom*1*127,den)=0 (post_div_min=ceil(vco_min/tc) is never clamped to max_post_div, loop empty, ref_div_max=128/127=1), and amdgpu_pll_reduce_ratio then executes DIV_ROUND_UP(fb_div_min, 0) at amdgpu_pll.c:56; (b) AMDGPU_PLL_USE_POST_DIV with pll->post_div>=129 (firmware AdjustDisplayPll ucPostDiv, atombios_crtc.c:441-442) forces ref_div_max=min(128/post_div,1023)=0 -> ref_div=0 -> 0/0 in the diff loop at amdgpu_pll.c:203. Guest run: SIGFPE on tc5/pd200 3/3 runs, control computes sane dividers, gdb pins harness:107==amdgpu_pll.c:56 and harness:228==amdgpu_pll.c:203. Kernel equivalent is div-by-zero trap #DE -> panic on the DRM-master modeset path (atombios_crtc.c:854), i.e. local DoS, no corruption/escalation. In-kernel repro impossible on this guest (no AMD GPU, env.txt) \u2014 same verification standard as DF-2037 (pass-1 source-only), but executable and gdb-pinned here.",
  "exploit_chain": "",
  "evidence": "run.log + run.2.log (SIGFPE 3/3 on tc5/pd200, control sane); gdb_lines.txt (traps at harness:107/:228 == amdgpu_pll.c:56/:203 with nom=0 in frame args); fix_run.log (patched functions: all cases complete, control bit-identical); env.txt (guest has no AMD GPU)",
  "kernel_refs": [
    "sys/dev/drm/amd/amdgpu/amdgpu_pll.c:56",
    "sys/dev/drm/amd/amdgpu/amdgpu_pll.c:88",
    "sys/dev/drm/amd/amdgpu/amdgpu_pll.c:172",
    "sys/dev/drm/amd/amdgpu/amdgpu_pll.c:203",
    "sys/dev/drm/amd/amdgpu/atombios_crtc.c:441",
    "sys/dev/drm/amd/amdgpu/atombios_crtc.c:854"
  ],
  "poc_changes": "no seed existed; harness authored at verification time (verbatim function copies + tree-exact gcd64/DIV_ROUND_* semantics + amdgpu_atombios.c:618-625 firmware PLL limits)",
  "attempts": 4,
  "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": 420,
  "guest_dirty": 0,
  "build_cmd": "cc -g -O0 -Wall -o pll_harness pll_harness.c",
  "run_cmd": "./run.sh  (pll_harness control|tc5|pd200|ref0)",
  "code_hash": "14588c16c97b5b5b039608dfbd48bdf542ad9165976a8e44a2d0ffb336b6b883",
  "notes": "distinct from DF-2037: there target_clock==0 (freq<10) or post_div==0 (sinks :172/:178/:88/:91/:242); here target_clock and post_div are nonzero and the DERIVED fb_div/ref_div under-run to zero (sinks :56/:203, plus :51 via gcd(0,0)==0 on overlap). PREFER_MINM_OVER_MAXP route (unclamped post_div_min>128) noted dead: no amdgpu caller sets that flag. Attacker/prereqs identical to DF-2037: local DRM-master/VT user, degenerate mode clock; pd200 route additionally needs firmware AdjustDisplayPll to return ucPostDiv>128.",
  "recommended_fix": "amdgpu_pll.c: floor gcd result and post-reduce nom/den to >=1 in amdgpu_pll_reduce_ratio; force ref_div_max >= 1 and post_div >= 1 in amdgpu_pll_get_fb_ref_div (fix.diff)",
  "fix_status": "fixed",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 1,
  "fix_verdict": "fix.diff guards applied 1:1 to the verbatim harness copy (pll_harness_fixed.c, built+run on guest): baseline SIGFPE cases tc5/pd200 now complete with defined output, control case output bit-identical (dot=14850 fb=880 ref=2 post=80) \u2014 see fix_run.log. Kernel-level rebuild validation not possible on this guest (no AMD GPU to drive the modeset path); validated at function level only.",
  "fix_evidence": "fix_run.log (guest, -g -O0): control/tc5/ref0/pd200 all exit 0, control unchanged vs baseline"
}