⬢ DragonFlyBSD Kernel Audit
DF-3698 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-3698",
  "status": "not_reproduced",
  "reproduced": 0,
  "impact": "none",
  "confidence": "certain",
  "verdict": "Source-certain, runtime-unreachable on this guest. gfx_v9_0_get_cu_info (gfx_v9_0.c:4990-5013) and gfx_v9_0_init_always_on_cu_mask (gfx_v9_0.c:937-958) iterate i<max_shader_engines, j<max_sh_per_se and index cu_info->bitmap[i][j]/ao_cu_bitmap[i][j], fixed [4][4] (amdgpu_gfx.h:197-198). Those bounds arrive unclamped as raw u32s from the amdgpufw_<asic>_gpu_info firmware file (amdgpu_device.c:1379-1381; the trees amdgpu_ucode_validate only checks size_bytes==datasize) or as u8s from the VBIOS gfx_info table on VEGA20 (gfx_v9_0.c:1422 -> amdgpu_atomfirmware.c:349). A crafted gpu_info blob (generator in this pack, gc_num_se=64) turns the loops into a linear heap OOB write past adev->gfx.cu_info inside the heap amdgpu_device plus an OOB read, at hw_init (constants_init -> get_cu_info) and, on Raven, already at sw_init (rlc_init -> init_lbpw). Guest ships amdgpu.ko (kldload verified) but has no AMD GPU (0 vendor-0x1002 devices, virtio-vga only) so the probe path never runs: honest not_reproduced, hardware absent. Distinct from known DF-1176/1177/1178 (RLC/MEC fw header parsing).",
  "exploit_chain": "on-hardware chain (not runnable here): craft amdgpufw_<asic>_gpu_info with gc_num_se=N (self-consistent size_bytes) -> amdgpu_device_parse_gpu_info_fw stores N -> gfx_v9_0_get_cu_info writes bitmap[i][j] for i<N -> overwrite of fields following adev->gfx.cu_info (gfx.funcs ptr, mutexes, then adjacent amdgpu_device members) with GPU-register-derived u32s -> corruption/panic, potentially worse with heap layout control.",
  "evidence": "VERDICT.md (line-by-line trace); fwgen_craft_gpuinfo.c + run.log (blob generated on guest cc 8.3, md5 4097a78162dc4bc1aa5740ffa50b1a54); env.txt (no AMD PCI device; amdgpu.ko loads but binds nothing); fix.diff (loop bounds + config clamp)",
  "kernel_refs": [
    "sys/dev/drm/amd/amdgpu/gfx_v9_0.c:4990",
    "sys/dev/drm/amd/amdgpu/gfx_v9_0.c:5000",
    "sys/dev/drm/amd/amdgpu/gfx_v9_0.c:5013",
    "sys/dev/drm/amd/amdgpu/gfx_v9_0.c:937",
    "sys/dev/drm/amd/amdgpu/gfx_v9_0.c:945",
    "sys/dev/drm/amd/amdgpu/gfx_v9_0.c:958",
    "sys/dev/drm/amd/amdgpu/gfx_v9_0.c:1422",
    "sys/dev/drm/amd/amdgpu/amdgpu_gfx.h:197",
    "sys/dev/drm/amd/amdgpu/amdgpu_device.c:1379",
    "sys/dev/drm/amd/amdgpu/amdgpu_atomfirmware.c:349"
  ],
  "poc_changes": "n/a (finding + generator authored fresh in this run; no seed PoC existed)",
  "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": 45,
  "guest_dirty": 0,
  "build_cmd": "cc -O2 -o fwgen_gi fwgen_craft_gpuinfo.c",
  "run_cmd": "./fwgen_gi",
  "code_hash": "5d81c18c54feb3a3d5e82a2d4fe49e9a6e2c263133cb9128efc44a4d19d2c923",
  "notes": "code_hash = sha256 of fwgen_craft_gpuinfo.c. Same malicious-firmware threat model as pass-1 DF-1176/1177/1178 (filed Medium). Note the Raven early path (init_always_on_cu_mask at sw_init) runs BEFORE gfx_v9_0_gpu_early_init, so the fix bounds the loops themselves, not only the config clamp.",
  "recommended_fix": "Bound the cu_info walker loops to the [4][4] array dims (min(x,4)) in gfx_v9_0_get_cu_info and gfx_v9_0_init_always_on_cu_mask, and clamp max_shader_engines/max_sh_per_se after the VEGA20 VBIOS read (see fix.diff).",
  "fix_status": "not_tested",
  "fix_baseline_reproduced": 0,
  "fix_patched_reproduced": 0,
  "fix_verdict": "fix.diff authored post-verification against the read-only sys/ tree; cannot be runtime-validated on this guest (no AMD hardware to bind the driver).",
  "fix_evidence": "fix.diff in this pack; not applied to sys/."
}