DF-3597 / verdict.json
{ "finding_id": "DF-3597", "status": "inconclusive", "reproduced": 0, "impact": "none", "confidence": "certain", "verdict": "gfx_v8_0_parse_ind_reg_list (gfx_v8_0.c:3974-4022) dereferences register_list_format[ind_offset] after ind_offset += 2 without re-checking ind_offset < list_size: a truncated final entry (last word != 0xFFFFFFFF) reads and WRITES a small int 4-8 bytes past the end of the kmalloc(reg_list_format_size_bytes) copy made at :4033-4037, and lists with an 8th unique indirect index or 10th entry hit post-write BUG_ONs (:3993, :4017) => panic. Reachable at driver load on CZ/Stoney/Polaris11/12/VegaM via hw_init->rlc_resume->init_pg->init_save_restore_list (:4872->:4176->:4180->:4132/:4141->:4024). Kernel run not possible on the virtio-only audit guest (no AMD PCI device, no drm module, no /boot/modules) -> inconclusive at runtime; the OOB write and BUG_ON were proven deterministically by a verbatim parser replica built and executed on the guest (canary at +4 bytes past a 72-byte allocation clobbered to 0x1; BUG_ON fired on 8th unique index). Distinct from pass-1 DF-1133 (init_microcode kmalloc wrap / array offsets).", "exploit_chain": "replace amdgpufw_<asic>_rlc firmware module -> RLC v2.0 header sets reg_list_format_size_bytes (slab-class selection) and list content (truncation point => +4/+8 byte write offset) -> driver load parses list -> small-int (0..7) heap overwrite of adjacent object -> slab grooming to victim object corruption -> kernel code execution path; BUG_ON variant = load-time DoS. Not executed (no AMD HW).", "evidence": "run.log (guest cc 8.3 run: HEAP OOB WRITE CONFIRMED ... +4 past allocation and BUG_ON fired); VERDICT.md (full path:line trace); fix.diff; build.log (guest uname + module-absence proof)", "kernel_refs": [ "sys/dev/drm/amd/amdgpu/gfx_v8_0.c:3974", "sys/dev/drm/amd/amdgpu/gfx_v8_0.c:4001", "sys/dev/drm/amd/amdgpu/gfx_v8_0.c:4020", "sys/dev/drm/amd/amdgpu/gfx_v8_0.c:4033", "sys/dev/drm/amd/amdgpu/gfx_v8_0.c:4040", "sys/dev/drm/amd/amdgpu/gfx_v8_0.c:4127", "sys/dev/drm/amd/amdgpu/gfx_v8_0.c:4176", "sys/dev/drm/amd/amdgpu/gfx_v8_0.c:4872" ], "poc_changes": "harness authored fresh (pass-2); parser body copied verbatim from gfx_v8_0.c:3974-4022 with only BUG_ON redefined to report instead of halt; canary-guarded heap emulates adjacent slab object", "attempts": 2, "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": 95, "guest_dirty": 0, "build_cmd": "cc -O0 -Wall -o poc_dfr3597 poc_dfr3597.c", "run_cmd": "./poc_dfr3597 ; ./poc_dfr3597 bugon", "code_hash": "6f20b34714460ce3c1b67477e66d81bfc3560f50212322f00cf28146730bda1d", "notes": "amdgpu module absent on guest (kldstat -v|grep -c drm = 0; /boot/modules missing; pciconf has no 0x1002 device) => kernel-side run impossible; algorithm-level proof only. Bug class matches pass-1 firmware-parser findings (DF-1133/DF-1134 threat model).", "recommended_fix": "In gfx_v8_0_parse_ind_reg_list, return (with error log) when ind_offset + 2 >= list_size before the dereference, and replace the two post-write BUG_ONs with pre-write WARN_ON guards; see fix.diff.", "fix_status": "not_testable", "fix_baseline_reproduced": 0, "fix_patched_reproduced": 0, "fix_verdict": "fix.diff line-matched against gfx_v8_0.c:3986-4021 adds the missing ind_offset+2>=list_size guard and converts BUG_ONs to pre-write WARN_ON returns; single-fix kernel build not possible on the virtio-only guest (amdgpu module absent, no AMD hardware) so the patched behavior was not executed.", "fix_evidence": "findings/poc/DF-3597/fix.diff; guest module-absence proof in build.log" } |