DF-4544 / verdict.json
{ "finding_id": "DF-4544", "status": "reproduced", "reproduced": 1, "impact": "leak", "confidence": "certain", "verdict": "One-sided count clamps in vega20_processpptables.c:823-833: ODFeatureCount/ODSettingCount from the VBIOS size the od_feature_capabilities (1-byte entries) and od_settings_max/min (4-byte entries) heap allocations downward (kzalloc at :695 / smu_helper.c:73-75), while the vega20_hwmgr.c consumers index them with fixed driver enums (OD8_SETTING_* 0..13, ATOM_VEGA20_ODFEATURE_* 0..9) unconditionally at driver init. With a crafted table declaring ODSettingCount=1 the first OOB read is od_settings_max[1] (vega20_hwmgr.c:907), 4 bytes past a 4-byte object; the farthest index (13) reads +52 B. The values are copied into od8_settings_array min/max (:1219-1221) and printed by print_clock_levels(OD_RANGE) (:2861-2905) to the world-readable pp_od_clk_voltage sysfs node. Reproduced on the audit guest with a faithful lifted-copy harness (struct layouts from vega20_pptable.h pack(1), exact clamp+alloc+consumer sequence, marker-filled adjacent-slab emulation): 21 OOB reads up to +48 B, and the first past-object u32 (0xA5A50001) passed the OD gates and appeared in the replicated sysfs output -- a filtered kernel-heap info leak to unprivileged readers. CONTROL (full counts) and PATCHED (allocations floored at driver counts) show 0 OOB reads. In-kernel path hardware-gated (no AMD GPU on the guest, env.txt); crafted-VBIOS threat model shared with knowns DF-1689/DF-1690 but a distinct defect (driver-side heap arrays vs blob OOB reads).", "exploit_chain": "crafted VBIOS/vGPU ROM with ODFeatureCount=10, ODSettingCount=1 -> pptable_init allocates 4-byte od_settings_max/min -> vega20_od8_set_feature_capabilities reads indices 1..13 past the object -> values passing the range gates propagate to od8_settings_array -> OD_RANGE sysfs dump prints adjacent-slab u32s to unprivileged readers (read window ~52 B, one-shot at driver load)", "evidence": "run.log (CRAFTED: 21 OOB reads farthest +48 B, SCLK: 800Mhz 2779054081Mhz = marker 0xA5A50001 leaked; CONTROL + PATCHED: 0 OOB); run.2.log (repeat, deterministic); fix_run.log (decisive rerun incl. PATCHED); fix_build.log (full amdgpu.ko rebuild with fix.diff, -Werror, RC=0); fix.diff (git apply --check OK)", "kernel_refs": [ "sys/dev/drm/amd/powerplay/hwmgr/vega20_processpptables.c:823", "sys/dev/drm/amd/powerplay/hwmgr/vega20_processpptables.c:829", "sys/dev/drm/amd/powerplay/hwmgr/vega20_processpptables.c:835", "sys/dev/drm/amd/powerplay/hwmgr/vega20_processpptables.c:839", "sys/dev/drm/amd/powerplay/hwmgr/smu_helper.c:73", "sys/dev/drm/amd/powerplay/hwmgr/vega20_hwmgr.h:398", "sys/dev/drm/amd/powerplay/hwmgr/vega20_hwmgr.c:906", "sys/dev/drm/amd/powerplay/hwmgr/vega20_hwmgr.c:1216", "sys/dev/drm/amd/powerplay/hwmgr/vega20_hwmgr.c:2861", "sys/dev/drm/amd/powerplay/hwmgr/vega20_pptable.h:76" ], "poc_changes": "authored fresh this run (pass 2); no seed PoC existed", "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": 330, "guest_dirty": 0, "build_cmd": "sh build.sh (cc -O2 -Wall -o od_count_oflow od_count_oflow.c on the guest)", "run_cmd": "sh run.sh (./od_count_oflow)", "code_hash": "a55b58d859d8addc4358bea67a58bcba7faff0150d0f38c999bf4a2c3854f1a2", "notes": "lifted-copy harness per DF-1179/DF-4395 convention (in-kernel path needs a Vega20 ASIC + crafted VBIOS; guest has only the QEMU std VGA -- env.txt). Leak is filtered (values must pass >0/>=min/<=100 gates) and one-shot at load; realistic ceiling is opportunistic heap-content disclosure. The vega12 sibling passes constant counts (not table-derived) and is NOT affected.", "recommended_fix": "floor the od_* allocations at the driver-enum counts (ATOM_VEGA20_ODFEATURE_COUNT / ATOM_VEGA20_ODSETTING_COUNT) and bound the copies by the table counts (fix.diff)", "fix_status": "not_testable", "fix_baseline_reproduced": 1, "fix_patched_reproduced": 0, "fix_verdict": "Patched kernel not runnable on the guest (no AMD ASIC). fix.diff is git-apply-able, compiles clean in a full amdgpu.ko module build under the real kernel toolchain with -Werror (fix_build.log, RC=0), and the harness PATCHED control shows 0 OOB reads for the same crafted input.", "fix_evidence": "fix.diff; fix_build.log (module rebuild RC=0, 0 errors); run.log PATCHED section (0 OOB reads, no markers printed)", "fix_kernel_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #0 x86_64 (amdgpu.ko toolchain validation)" } |