DF-4886 / verdict.json
{ "finding_id": "DF-4886", "status": "untested", "reproduced": 0, "impact": "panic", "confidence": "certain", "verdict": "Not runnable on the audit guest (no AMD GPU / powerplay device; PCI tree contains no AMD device). Code-certain by inspection: phm_start_thermal_controller (hardwaremanager.c:234-253) is the ONLY public phm_* dispatcher in hardwaremanager.c that omits PHM_FUNC_CHECK (macro at :33-37, used by all ~25 siblings) - it derefs hwmgr->adev at :238 with hwmgr unchecked, derefs hwmgr->hwmgr_func->get_thermal_temperature_range at :240 with hwmgr_func unchecked, and stores through the unchecked adev at :249-250. Latent, DF-1913/DF-4831 family: the hw_init caller (hwmgr.c:249) is shadowed by the DF-1913 deref at hwmgr.c:216 which fires first on any NULL hwmgr_func; the resume caller (hwmgr.c:321) is gated on pm_en, which requires hwmgr_early_init (hwmgr.c:80-177) to have succeeded - and every chip-family case there assigns hwmgr_func (smu7_hwmgr.c:5140, smu8_hwmgr.c:2005, vega10_hwmgr.c:4992, vega12_hwmgr.c:2422, vega20_hwmgr.c:3604, smu10_hwmgr.c:1225) or returns -EINVAL which pp_early_init propagates (amd_powerplay.c:85-87), aborting the probe. Impact ceiling is a NULL-deref panic (no attacker-controlled write); arms only for a future chip path leaving hwmgr_func NULL with pm_en true. One-line mirror-the-guard fix.", "exploit_chain": "", "evidence": "README.md (guard-vs-sibling analysis with path:line); VERDICT.md (reachability trace + pass-2 negative results incl. the set_pp_table non-participation proof and the vega10_get_performance_level count==0 cross-file lead); trigger_sketch.c; fix.diff", "kernel_refs": ["sys/dev/drm/amd/powerplay/hwmgr/hardwaremanager.c:33", "sys/dev/drm/amd/powerplay/hwmgr/hardwaremanager.c:238", "sys/dev/drm/amd/powerplay/hwmgr/hardwaremanager.c:240", "sys/dev/drm/amd/powerplay/hwmgr/hardwaremanager.c:249", "sys/dev/drm/amd/powerplay/hwmgr/hwmgr.c:216", "sys/dev/drm/amd/powerplay/hwmgr/hwmgr.c:249", "sys/dev/drm/amd/powerplay/hwmgr/hwmgr.c:321", "sys/dev/drm/amd/powerplay/amd_powerplay.c:85"], "poc_changes": "sketch only; kernel-internal NULL-discipline hole, no userspace trigger exists", "attempts": 0, "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": 0, "guest_dirty": 0, "build_cmd": "", "run_cmd": "", "code_hash": "", "notes": "Pass-2 hardwaremanager.c: DF-1952 (displays[] walk) not re-reported. Killed classes: phm_get_clock_info index underflow (all backends set nonzero *_MAX_HARDWARE_POWERLEVELS constants before pm_en callers can run); unchecked pass-through params (all amd_powerplay.c callers pre-validate); thermal range + u32 kHz values (kernel-internal sources only); set_pp_table amd_powerplay.c:693 does NOT route through any hardwaremanager wrapper. Cross-file lead logged: vega10_hwmgr.c:4915-4917 count==0 clamp underflow passes any index (uninitialized-array read only).", "recommended_fix": "add PHM_FUNC_CHECK(hwmgr) as the first statement of phm_start_thermal_controller (one line, matches all sibling wrappers)", "fix_status": "not_testable", "fix_baseline_reproduced": 0, "fix_patched_reproduced": 0, "fix_verdict": "fix validation not possible: latent hardware-gated finding (no AMD GPU on the audit guest); fix is a trivial one-line guard mirroring every sibling wrapper - static review only", "fix_evidence": "fix.diff (git-apply-able vs read-only sys/ tree; never applied)" } |