{
  "finding_id": "DF-3859",
  "status": "not_reproduced",
  "reproduced": 0,
  "impact": "none",
  "confidence": "certain",
  "verdict": "Source-certain negative-index OOB read in the PP_OD_EDIT_VDDC_CURVE branch of vega20_odn_edit_dpm_table (vega20_hwmgr.c:2656-2720), the vega10 DF-3704 signed-compare twin: the bounds check at :2678 tests only input_index > 2, so any negative user token survives; od8_id = OD8_SETTING_GFXCLK_FREQ1 + 2*input_index (:2685, :2695) goes negative and od8_settings[od8_id].min/.max_value are read (:2686-2687, :2696-2697) from before the 16x20-byte od8_settings_array embedded in the kzallocd vega20_hwmgr backend - and both garbage values are then printed by the pr_info range message (:2688-2692), leaking kernel heap bytes into the log; attacker-chosen magnitudes (int32 token, e.g. -100000000 -> ~-3.7GB offset) page-fault and panic the sysfs write path. Unlike vega10s twin there is no OOB write (the :2705 switch only writes indices 0/1/2). Trigger: root-gated pp_od_clk_voltage (S_IWUSR, amdgpu_pm.c:1028) whose kstrtol token parser (amdgpu_pm.c:575-592) accepts negative tokens; echo \"vc -2 1000 900\" > .../pp_od_clk_voltage. Guest demonstration: the verbatim index/access/message logic on a heap stand-in leaked exactly the 0xA5A5A5A5 marker bytes at od8_id=-2 (-40 bytes) and -12 (-240 bytes) while the in-bounds control (od8_id=4) passed cleanly. Kernel path not runnable here (0 AMD PCI devices, no /dev/dri). Impact ceiling: root/confused-deputy kernel-heap info leak to dmesg + controllable-offset wild read (panic).",
  "exploit_chain": "root or confused-deputy writer on a Vega20 with OD8 GFXCLK-curve support: echo \"vc -N 1000 900\" > /sys/class/drm/card0/device/pp_od_clk_voltage -> amdgpu_pm.c parser (kstrtol accepts -N) -> vega20_odn_edit_dpm_table PP_OD_EDIT_VDDC_CURVE -> od8_settings[2 + 2*(-N)] OOB read -> pr_info discloses the OOB bytes (small N: vega20_hwmgr backend internals; large N: unmapped kernel address -> page fault/panic).",
  "evidence": "run.log (control in-bounds; attacks at -2/-7 leaking marker bytes 0xA5A5A5A5=-1515870811 in the range message); VERDICT.md (full trace incl. safe SCLK/MCLK branch comparison and why no write occurs); fix.diff (git-apply-clean); env.txt (no AMD ASIC)",
  "kernel_refs": [
    "sys/dev/drm/amd/powerplay/hwmgr/vega20_hwmgr.c:2560",
    "sys/dev/drm/amd/powerplay/hwmgr/vega20_hwmgr.c:2674",
    "sys/dev/drm/amd/powerplay/hwmgr/vega20_hwmgr.c:2678",
    "sys/dev/drm/amd/powerplay/hwmgr/vega20_hwmgr.c:2685",
    "sys/dev/drm/amd/powerplay/hwmgr/vega20_hwmgr.c:2686",
    "sys/dev/drm/amd/powerplay/hwmgr/vega20_hwmgr.c:2688",
    "sys/dev/drm/amd/powerplay/hwmgr/vega20_hwmgr.c:2695",
    "sys/dev/drm/amd/powerplay/hwmgr/vega20_hwmgr.h:429",
    "sys/dev/drm/amd/amdgpu/amdgpu_pm.c:1028",
    "sys/dev/drm/amd/amdgpu/amdgpu_pm.c:575"
  ],
  "poc_changes": "Authored from scratch. One build fix: missing <errno.h> for EINVAL in the replica. First guest build ran before the chained && list reached it (od_div0 error aborted the chain) - rebuilt standalone.",
  "attempts": 3,
  "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": 190,
  "guest_dirty": 0,
  "build_cmd": "vm.sh run_root cc -O2 -Wall -o /tmp/odn_negidx /tmp/odn_negidx.c",
  "run_cmd": "vm.sh run_root /tmp/odn_negidx 1 1000; /tmp/odn_negidx -2 1000; /tmp/odn_negidx -7 1000 (/tmp cleaned)",
  "code_hash": "9a49584e120a505b733cb8fc0a10a726f9377537d7507e0272d3019d7d7cf640",
  "notes": "Pass-2 checklist item (d) for vega20 (DF-3487/3704 twins; note DF-3487 itself is the ng_pppoe finding - the odn signed-compare family reference is DF-3704). gfxoff handlers (item g) live in vega20_gfxoff.c (out of this files scope); the OD8 sysfs handlers are this finding plus DF-3858.",
  "recommended_fix": "Change the VDDC_CURVE bounds check to if (input_index < 0 || input_index > 2) in vega20_odn_edit_dpm_table",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": 0,
  "fix_patched_reproduced": 0,
  "fix_verdict": "fix.diff adds the lower-bound check (one-line, matches the SCLK/MCLK branches reject style) and is git-apply-clean against the read-only sys/ tree; no Vega20 ASIC on this guest so a patched-kernel run is not_testable",
  "fix_evidence": "fix.diff; VERDICT.md; env.txt"
}