DF-5054 / verdict.json
{ "finding_id": "DF-5054", "status": "reproduced", "reproduced": true, "impact": "panic", "confidence": "certain", "verdict": "Reproduced at logic level with a verbatim userland replica of irq_source_info_dce80[] (entry macros incl. the dce80-specific [DC_IRQ_SOURCE_INVALID+reg_num]/[DC_IRQ_SOURCE_HPD6+reg_num] designator forms, table body, dce80 hpd_ack, funcs tables \u2014 irq_service_dce80.c:40-274), to_dal_irq_source_dce110 (dce110:315-393, the converter dce80 installs at :277) and the irq_service.c dispatch (:77-158), run on the audit guest. Designators cover exactly 0..83 while the shared enum runs to DAL_IRQ_SOURCES_NUMBER=90: DC_IRQ_SOURCE_DC{1..6}_VLINE0 (84..89) stay zero-initialized with .funcs==NULL; find_irq_source_infos index bounds check (:82) passes them through and dal_irq_service_ack (:152, called first by dal_irq_service_set at :116) dereferences info->funcs->ack on NULL -> SIGSEGV exit 139, deterministic x2. Controls prove the rest of the table healthy (OOB index 90 rejected; PFLIP1 generic set; dce80 hpd_ack polarity toggle) and latency (256-src x 13-ext to_dal sweep: 0 returns in 84..89 \u2014 no in-tree caller can reach the gap; suspend/resume are HPD/HPDRX-only, vblank enable is IRQ_TYPE_VBLANK+otg_inst, pflip is IRQ_TYPE_PFLIP). FIX VALIDATED: six VLINE0 dummy_irq_entry() designators (fix.diff) -> replica fixed mode exit 0 with dummy log-and-return handlers; full amdgpu.ko module rebuild with the fix on guest /usr/src under -Werror RC=0, zero diagnostics, irq_service_dce80.o linked (amdgpu_module_build.log); sources reverted md5-verified pristine. DF-2168 (hub guards) / DF-4932 (dce110) / DF-4995 (dcn10) family instance on the DCE80 (Sea Islands) table; guest has no AMD GPU so the kernel path itself cannot be driven \u2014 family-standard replica methodology. Ceiling if a future caller appears: kernel NULL-page-read panic, not controllable corruption.", "exploit_chain": "", "evidence": "run.log + run.2.log (decisive: table[84..89] (.funcs == NULL) x6; trigger dal_irq_service_set(DC_IRQ_SOURCE_DC1_VLINE0=84) -> Segmentation fault exit 139 both runs; fixed section exit 0); dce80_vline0gap.c (verbatim replica); amd_fix_apply.log + amdgpu_module_build.log (777-line -Werror amdgpu.ko rebuild, RC=0); fix.diff; VERDICT.md", "kernel_refs": [ "sys/dev/drm/amd/display/dc/irq/dce80/irq_service_dce80.c:188", "sys/dev/drm/amd/display/dc/irq/dce80/irq_service_dce80.c:273", "sys/dev/drm/amd/display/dc/irq/dce80/irq_service_dce80.c:277", "sys/dev/drm/amd/display/dc/irq/irq_service.c:82", "sys/dev/drm/amd/display/dc/irq/irq_service.c:116", "sys/dev/drm/amd/display/dc/irq/irq_service.c:118", "sys/dev/drm/amd/display/dc/irq/irq_service.c:152", "sys/dev/drm/amd/display/dc/irq_types.h:140", "sys/dev/drm/amd/display/dc/irq_types.h:158", "sys/dev/drm/amd/display/dc/core/dc.c:1687", "sys/dev/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c:353", "sys/dev/drm/amd/display/amdgpu_dm/amdgpu_dm.c:3014" ], "poc_changes": "Authored fresh (no seed), modeled on DF-4995s dcn10 replica with the DCE80 files own macros verbatim: one compile fix (missing bool param in the set_generic forward decl) plus keeping the vblank funcs wiring faithful (.set = dce110_vblank_set stub, cross-referenced to DF-5055 where the real body is exercised).", "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": 400, "guest_dirty": 0, "build_cmd": "sh build.sh (cc -O2 -Wall -std=gnu11 [-DFIX_DF5054])", "run_cmd": "sh run.sh (baseline then fixed; second baseline in run.2.log)", "code_hash": "04d0395637c9775b2f80e8b4a03e3bf5c5e03d930ef64287c2657b8d1bbdcd91", "notes": "Family: hub DF-2168 (missing !info->funcs guards, recommended as defense-in-depth alongside), dce110 DF-4932, dcn10 DF-4995; dce120 noted in DF-4932s summary as still carrying the same shape (not re-filed here). hpd_rx/pflip funcs with all-NULL members are SAFE (funcs non-NULL; irq_service.c:118/:152 member-check then generic fallback). Pass-2 negatives in VERDICT.md: irq_service_funcs type single-member (no dce80/dce110 mismatch); hpd/pflip/gpio/crtc pin ranges in range on DCE80; vblank .src_id arithmetic correct (VERTICAL_INTERRUPT0 ids 19..24 consecutive); DAL_VALID_IRQ_SRC_NUM off-by-one is DF-2168-noted amdgpu_dm territory.", "recommended_fix": "Add [DC_IRQ_SOURCE_DC1..6_VLINE0] = dummy_irq_entry() designators so the table totals the shared enum; alongside (DF-2168), guard `if (!info->funcs) return false;` in dal_irq_service_set/ack.", "fix_status": "fixed", "fix_baseline_reproduced": 1, "fix_patched_reproduced": 0, "fix_verdict": "fixed: fix.diff (six VLINE0 dummy entries) applied to guest /usr/src (patched md5 0cdb51fa69c1019438882d26fe100eda, together with DF-5055s diff); full make -j6 amdgpu.ko rebuild under -Werror RC=0, zero error/warning diagnostics, irq_service_dce80.o linked (amdgpu_module_build.log); replica fixed mode exit 0 vs baseline SIGSEGV 139; sources reverted md5-verified pristine (f20f096b3f00c5186a514e7aa3b84db4), module objects cleaned, guest reset to the with-src snapshot.", "fix_evidence": "fix.diff; amd_fix_apply.log; amdgpu_module_build.log; run.log (baseline crash + fixed exit 0); run.2.log; VERDICT.md" } |