DF-3957 / verdict.json
{ "finding_id": "DF-3957", "status": "inconclusive", "reproduced": 0, "impact": "none", "confidence": "likely", "verdict": "Pass-2 depth delta on a pass-1-clean file (radeon twin of amdgpu DF-1380-era robustness gaps, different bug). radeon_add_atom_encoder (:2838/:2872) assigns enc_priv from radeon_atombios_get_lvds_info (radeon_atombios.c:1617-1755), which returns NULL when the VBIOS LVDS_Info DATA table is missing/short or on kzalloc failure - unchecked at both assignment sites. Nine sinks dereference it without a NULL guard (contrast existing guards at :100/:240/:629/:2551): reads at :742-744, :1085 (BOOT via radeon_atom_encoder_init :2314), :1695-97, :1783, :1796, :2006-07, :2270-72, :2661; NULL-page WRITES at :1744 (dig->panel_mode, first DPMS ON, DCE4.1+) and :2663 (dig->dig_encoder = -1 on disable). All fault in the NULL page -> panic (DoS); no unprivileged local or remote vector; upstream Linux radeon carries the identical code (inherited). Harness executes the verbatim NULL+0 read/write-1 and NULL+12 write in children: both SIGSEGV sig=11. Runtime-inconclusive: no AMD GPU on guest.", "exploit_chain": "radeon GPU with BIOS connector table advertising an eDP/LVDS panel but a missing/short LVDS_Info table (or boot-time kzalloc failure) -> LCD-supporting digital encoder with enc_priv==NULL -> first transmitter init / DPMS ON / encoder disable -> NULL-page read/write -> kernel page fault -> panic (DoS). Written value is the constant -1; no control, no uid0 path.", "evidence": "run.log: :742 dig_enc->active_mst_links READ at NULL+8, :1085 ... NULL+0, :1744 dig->panel_mode = ... WRITE at NULL+12, :2663 dig->dig_encoder = -1 WRITE at NULL+0, child1 (disable :2661-2663): SIGNALLED sig=11, child2 (dpms_dig :1744): SIGNALLED sig=11, RESULT: NULL-PAGE FAULTS AS PREDICTED (rc=0); VERDICT.md; fix.diff", "kernel_refs": [ "sys/dev/drm/radeon/atombios_encoders.c:742", "sys/dev/drm/radeon/atombios_encoders.c:1085", "sys/dev/drm/radeon/atombios_encoders.c:1744", "sys/dev/drm/radeon/atombios_encoders.c:2006", "sys/dev/drm/radeon/atombios_encoders.c:2270", "sys/dev/drm/radeon/atombios_encoders.c:2661", "sys/dev/drm/radeon/atombios_encoders.c:2872", "sys/dev/drm/radeon/radeon_atombios.c:1617" ], "poc_changes": "No seed (pass-2 self-authored). Two fix cycles: missing <signal.h>; none behavioral.", "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": 100, "guest_dirty": 0, "build_cmd": "cd /tmp/df395x && cc -O2 -Wall -o trigger_df3957 trigger_df3957.c", "run_cmd": "cd /tmp/df395x && ./trigger_df3957 && ./trigger_df3957 crash", "code_hash": "014c77e8f2000dd36ae9f899ba73b0dfd535ce432c59926f9d02db52dda62ecd", "notes": "Negative results recorded for the pass-2 hunt on this file: afmt[dig->dig_encoder] (:2557) in-bounds (RADEON_MAX_AFMT_BLOCKS=7, radeon_mode.h:52); MST fake encoders have encoder_id=0 so radeon_encoder_is_digital()==false - no enc_priv type confusion; connector==NULL in atombios_get_encoder_mode (:761-765) unreachable because every encoders devices bits derive from connectors and the MST early-return at :746 fires first; DFly-specific sysctl backlight glue (:184-309) registers only after the :240 enc_priv check (detach-race lifetime is a hardening note, not filed); atombios_set_mst_encoder_crtc_source frev != 1 && crev != 2 (:2080) is a logic quirk with no memory-safety effect.", "recommended_fix": "NULL-guard enc_priv at the nine sinks, mirroring the files existing guards at :100/:240/:629/:2551 (fix.diff).", "fix_status": "not_testable", "fix_baseline_reproduced": 0, "fix_patched_reproduced": 0, "fix_verdict": "fix.diff authored against the read-only sys/ tree; not built - no AMD hardware on the guest. Guards remove all nine sinks by construction.", "fix_evidence": "findings/poc/DF-3957/fix.diff" } |