⬢ DragonFlyBSD Kernel Audit
DF-3701 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-3701",
  "status": "inconclusive",
  "reproduced": 0,
  "impact": "none",
  "confidence": "certain",
  "verdict": "Source-certain kernel stack buffer overflow (DF-3684 smu7 twin): vega10_get_sclks/memclocks/dcefclocks/socclocks and vega10_get_clock_by_type_with_voltage write clocks->data[i] for i < VBIOS-supplied dep_table->count (ucNumEntries, uint8, <=255, uncapped at vega10_processpptables.c:540 etc.) into struct pp_clock_levels_with_latency whose data[] is PP_MAX_CLOCK_LEVELS=16 and which the DC caller holds on its stack (amdgpu_dm_pp_smu.c:375/:399). vega10_get_memclocks additionally heap-overflows mclk_latency_table.entries[8] inside struct vega10_hwmgr. Not reproducible on the audit guest: 0 AMD PCI devices (virtio-only), amdgpu.ko present but never binds, so the vega10 hwmgr code path cannot execute; a userspace stand-in of the loop math (built with guest cc 8.3) demonstrated live corruption of stack-adjacent locals. Realization requires a Vega10 dGPU with crafted VBIOS powerplay table (flash/passthrough threat model).",
  "exploit_chain": "crafted VBIOS pptable (SOCCLK/MCLK/GFXCLK/DCEFCLK dep table ucNumEntries>16) -> driver/DC bring-up calls dm_pp_get_clock_levels_by_type_with_latency -> vega10_get_* writes attacker-scaled 32-bit values (ulClk*10) past a 132-byte stack object -> return-address/frame smash -> kernel ROP -> uid=0 (chain hardware-gated, not demonstrated here)",
  "evidence": "VERDICT.md (line-by-line trace); run.log (guest hardware gate: pciconf 0x1002 count=0; guest /usr/src excerpt of the unbounded loop at :4186-4190; stand-in demo whose own loop counter was overwritten by the OOB writes); trigger_shape.c; fix.diff",
  "kernel_refs": [
    "sys/dev/drm/amd/powerplay/hwmgr/vega10_hwmgr.c:4115",
    "sys/dev/drm/amd/powerplay/hwmgr/vega10_hwmgr.c:4135",
    "sys/dev/drm/amd/powerplay/hwmgr/vega10_hwmgr.c:4161",
    "sys/dev/drm/amd/powerplay/hwmgr/vega10_hwmgr.c:4177",
    "sys/dev/drm/amd/powerplay/hwmgr/vega10_hwmgr.c:4246",
    "sys/dev/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c:375",
    "sys/dev/drm/amd/include/dm_pp_interface.h:28",
    "sys/dev/drm/amd/powerplay/hwmgr/vega10_processpptables.c:540"
  ],
  "poc_changes": "no runnable kernel PoC possible on virtio-only guest; wrote userspace stand-in of the getter loop that reproduced adjacent-stack-local corruption; verified cited lines byte-identical in guest /usr/src",
  "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": 420,
  "guest_dirty": 0,
  "build_cmd": "vm.sh run_root cc -Wall -o /tmp/df3701 /tmp/df3701.c && /tmp/df3701",
  "run_cmd": "vm.sh run_root /tmp/df3701 (plus pciconf/dmesg probes; /tmp cleaned)",
  "code_hash": "a5a98746221a9e46f2729bf34670e55bed1f262a454c98c9f9695a43ef019d88",
  "notes": "smu7 checklist item (b) DF-3684 twin, vega10. Known findings DF-1179..1183 do not cover the clock getters. Guest left clean (only /tmp, removed).",
  "recommended_fix": "Clamp all five getter loops to the destination capacity: i < dep_table->count && i < PP_MAX_CLOCK_LEVELS (and num_levels=0 init), mirroring vega10_populate_single_display_type:1850 guard",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": 0,
  "fix_patched_reproduced": 0,
  "fix_verdict": "fix.diff authored against read-only sys/ tree; cannot build/test a Vega10 kernel path on the virtio-only guest (no AMD device to bind amdgpu), so no patched-kernel validation is possible",
  "fix_evidence": "fix.diff; hardware gate in run.log"
}