⬢ DragonFlyBSD Kernel Audit
DF-3887 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-3887",
  "status": "inconclusive",
  "reproduced": 0,
  "impact": "none",
  "confidence": "certain",
  "verdict": "Source-certain heap OOB write; runtime-inconclusive on this guest (no AMD GPU). sumo_construct_vid_mapping_table (kv_dpm.c:167-170) stores two u16s at vid_mapping_table->entries[usVoltageIndex] where entries[] has 4 slots (kv_dpm.h SUMO_MAX_NUMBER_VOLTAGES) but usVoltageIndex is an unvalidated USHORT (0..65535) from the VBIOS sAvail_SCLK list (atombios.h:5705). A crafted VBIOS executes up to 5 chosen-offset 16-bit-pair writes in entries+[4..262142] - covering the ~1.3KB kv_power_info heap object (dpm_table_start/sram_end SMC write offsets, graphics_level[], level counts) and adjacent slab objects - at every KV boot via kv_dpm_init -> kv_parse_sys_info_table (:2613). Harness (1:1 layouts, verbatim loop) shows the exact OOB write set (entries+1200..+1210, payload 0xBEEF/0xCAFE/0x1234 for indices 300-302) and crash mode SIGSEGVs at +262140 (kernel equivalent: page fault -> panic, or silent adjacent-heap corruption on mapped pages). Distinct from pass-1 DF-1268 (count overflow of graphics_level/uvd_level arrays) and DF-1269 (kv_parse_power_table OOB reads): different victim array, different input table, write vs read.",
  "exploit_chain": "flash crafted VBIOS (physical/supply-chain) -> boot -> kv_dpm_init OOB write window [entries+4 .. entries+262142] -> corrupt pi->dpm_table_start/sram_end (destinations of later amdgpu_kv_copy_bytes_to_smc writes), graphics_dpm_level_count, or adjacent heap objects -> second-order controlled SMC-SRAM/heap writes. Not exercisable on the GPU-less guest.",
  "evidence": "run.log: OOB WRITE: entries+1200..+1210 = 0x012c/0xbeef/0x012d/0xcafe/0x012e/0x1234, 7 OOB 16-bit writes landed OUTSIDE the 16-byte entries array; run.2.log: crash mode ... +65535*4 = 262140 bytes past it then Segmentation fault exit=139; VERDICT.md; fix.diff",
  "kernel_refs": [
    "sys/dev/drm/amd/amdgpu/kv_dpm.c:167",
    "sys/dev/drm/amd/amdgpu/kv_dpm.c:169",
    "sys/dev/drm/amd/amdgpu/kv_dpm.c:2613",
    "sys/dev/drm/amd/amdgpu/kv_dpm.h:34",
    "sys/dev/drm/amd/include/atombios.h:5705"
  ],
  "poc_changes": "No seed (pass-2 self-authored). Added stddef.h for ptrdiff_t after first guest build failed; guest loop verified accounting+crash modes.",
  "attempts": 4,
  "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #0: Thu Jul  2 06:02:54 UTC 2026 x86_64",
  "runtime_sec": 120,
  "guest_dirty": 0,
  "build_cmd": "cd /tmp/DF-3887 && cc -Wall -O0 -o t h.c",
  "run_cmd": "cd /tmp/DF-3887 && ./t && ./t crash",
  "code_hash": "27e15a0bf12c70307a126bab447b12ec34c5d3dd6b0e229bd3e76a3d946dd5ff",
  "notes": "Guest virtio-only (pciconf: no 1002 device; amdgpu.ko in /boot/kernel, not loaded). The entries-4 = 0x0002 hit in run.log is the in-struct num_entries field legally written by the compaction loop. Compiled -O0. VBIOS-gated per DF-1268/1269/DF-3586 precedent (AV:P).",
  "recommended_fix": "Skip sAvail_SCLK entries whose usVoltageIndex >= SUMO_MAX_NUMBER_VOLTAGES in sumo_construct_vid_mapping_table (kv_dpm.c:166), mirroring the existing clock_array_index check at :2758.",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": 0,
  "fix_patched_reproduced": 0,
  "fix_verdict": "fix.diff authored against the read-only sys/ tree after source+harness verification; not built (no AMD hardware on guest to load the drm stack).",
  "fix_evidence": "findings/poc/DF-3887/fix.diff"
}