DF-5207 / verdict.json
{ "finding_id": "DF-5207", "status": "untested", "verdict": "untested (dead path: num_virtual_links is memset to 0 at amdgpu_dm.c:395 and no code in the tree ever sets it, so create_links virtual loop (dc.c:133-172) never instantiates a virtual link encoder on any real system; additionally the guest has no AMD GPU). Static proof is complete: virtual_lnk_enc_funcs (virtual_link_encoder.c:86-101) populates only 12 of the 18 ops in struct link_encoder_funcs (inc/hw/link_encoder.h:116-156); enable_lvds_output, psr_program_dp_dphy_fast_training, psr_program_secondary_packet, enable_hpd, disable_hpd and is_dig_enabled are NULL. Four of the six have UNGUARDED call sites in DC core: dce110_hw_sequencer.c:1579 (is_dig_enabled), dce_dmcu.c:167 and dce_dmcu.c:586 (psr_program_dp_dphy_fast_training), dce_dmcu.c:215 and dce_dmcu.c:634 (psr_program_secondary_packet), dc_link.c:1988 (enable_lvds_output). Today those sites only ever run with real DCE/DCN encoders: get_link_for_edp() filters SIGNAL_TYPE_EDP (dce110_hw_sequencer.c:1520-1531), PSR setup runs only on eDP links, enable_link_lvds() only for SIGNAL_TYPE_LVDS streams, and the SIGNAL_TYPE_VIRTUAL case in enable_link() is a pure no-op (dc_link.c:2019-2021) touching no encoder op. The two ops a virtual link could plausibly reach (dc_link_dp_enable_hpd/disable_hpd) are already NULL-guarded (dc_link_dp.c:2492/2500). So the gap is latent: the moment virtual links are wired up (num_virtual_links>0) and any of those paths ever sees a virtual encoder, the call is a NULL function-pointer dereference -> kernel panic (local DoS at best, controllable-call primitive at worst).", "reproduced": false, "impact": "latent NULL function-pointer call (DoS)", "confidence": "speculative", "exploit_chain": "", "evidence": "static analysis: inc/hw/link_encoder.h:116-156 (18 ops) vs virtual_link_encoder.c:86-101 (12 initialized -> 6 NULL); unguarded call sites dce110_hw_sequencer.c:1579, dce_dmcu.c:167/215/586/634, dc_link.c:1988; guarded ones dc_link_dp.c:2492/2500; instantiation dead path dc.c:133-172 + amdgpu_dm.c:395 (memset, zero setters tree-wide); DF-5199 twin (virtual_stream_encoder.c, 7 NULL ops).", "kernel_refs": [ "sys/dev/drm/amd/display/dc/virtual/virtual_link_encoder.c:86", "sys/dev/drm/amd/display/dc/virtual/virtual_link_encoder.c:101", "sys/dev/drm/amd/display/dc/inc/hw/link_encoder.h:116", "sys/dev/drm/amd/display/dc/dce110/dce110_hw_sequencer.c:1579", "sys/dev/drm/amd/display/dc/dce/dce_dmcu.c:167", "sys/dev/drm/amd/display/dc/core/dc_link.c:1988", "sys/dev/drm/amd/display/dc/core/dc_link_dp.c:2492", "sys/dev/drm/amd/display/dc/core/dc.c:169", "sys/dev/drm/amd/display/amdgpu_dm/amdgpu_dm.c:395" ], "poc_changes": "", "attempts": 0, "guest_uname": "n/a (guest not booted; latent dead-path Info finding, no runtime test performed)", "runtime_sec": 0, "guest_dirty": 0, "build_cmd": "n/a", "run_cmd": "n/a", "code_hash": "", "notes": "Info/latent; Phase V skipped per contract: unreachable on any real system (num_virtual_links hardcoded 0, guest has no AMD GPU). Sibling of DF-5199 (virtual_stream_encoder) \u2014 different file, different vtable, different call sites.", "recommended_fix": "populate the 6 missing ops with no-op stubs (mirror dce_virtual pattern)", "fix_status": "not_testable", "fix_baseline_reproduced": 0, "fix_patched_reproduced": 0, "fix_verdict": "", "fix_evidence": "" } |