DF-3698 / verdict.json
{ "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/." } |