DF-4375 / verdict.json
{ "finding_id": "DF-4375", "status": "inconclusive", "reproduced": 0, "impact": "none", "confidence": "certain", "verdict": "Defect certain from source: dce112_resource.c:577-579 indexes link_enc_regs[7], link_enc_aux_regs[6] and link_enc_hpd_regs[6] with unvalidated transmitter / channel-1 / hpd_source values that the DC core itself derives from VBIOS object tables (TRANSMITTER_UNKNOWN=-1, TRAVIS_CRT=7, TRAVIS_LCD=8, UNIPHY_G=9; CHANNEL_ID_UNKNOWN=0 -> -1, DDC_VGA=7 -> 6, I2C_PAD=8 -> 7; HPD_SOURCEID_UNKNOWN=7), producing OOB const-table reads that become the link encoders register bases (wild MMIO offsets) \u2014 the DF-4312/DF-4319/DF-4352 twin on DCE112. Runtime kernel manifestation could not be exercised: the verification guest has zero AMD PCI devices (pciconf) so amdgpu never binds; the index arithmetic itself was executed and verified deterministically on the guest with the exact enum values and table sizes (run.log: every <-- OOB row). ASan mode unavailable on the guest (GCC 8.3 lacks libasan; build.log). Classification mirrors twin DF-4312 (inconclusive, no DC hardware on the verification guest).", "exploit_chain": "", "evidence": "run.log (guest run of df4375_poc.c: per-row index (array size N) <-- OOB verdicts, e.g. link_enc_regs[9] into size 7, link_enc_aux_regs[-1] into size 6, link_enc_hpd_regs[7] into size 6); env.txt (uname 6.5-DEVELOPMENT, cc 8.3, 0 AMD PCI devices); build.log; VERDICT.md full trace; fix.diff git-apply-clean", "kernel_refs": [ "sys/dev/drm/amd/display/dc/dce112/dce112_resource.c:577", "sys/dev/drm/amd/display/dc/dce112/dce112_resource.c:578", "sys/dev/drm/amd/display/dc/dce112/dce112_resource.c:579", "sys/dev/drm/amd/display/dc/dce112/dce112_resource.c:267", "sys/dev/drm/amd/display/dc/dce112/dce112_resource.c:239", "sys/dev/drm/amd/display/dc/dce112/dce112_resource.c:253", "sys/dev/drm/amd/display/dc/core/dc_link.c:1165", "sys/dev/drm/amd/display/dc/core/dc_link.c:1006", "sys/dev/drm/amd/display/dc/core/dc_link.c:964", "sys/dev/drm/amd/display/dc/core/dc_link.c:925" ], "poc_changes": "n/a (pack authored fresh in this run; no seed harness existed). Harness mirrors enum values from grph_object_defs.h and array sizes from dce112_resource.c verbatim; read-only OOB loads instead of stores so the proof matches the kernels const-table reads", "attempts": 3, "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": 14, "guest_dirty": 0, "build_cmd": "cc -O1 -g -o df4375_plain df4375_poc.c", "run_cmd": "./df4375_plain", "code_hash": "c07238094e236010439241f9acde991bd5f5f39dd2d7801a71134f52c5cdc64f", "notes": "Attempts: (1) guest hardware probe - no AMD device, amdgpu cannot bind; (2) ASan build - blocked, no libasan on guest GCC 8.3; (3) plain guest build+run - deterministic OOB index proof, exit 0. HPD_SOURCEID_UNKNOWN(7) path is reachable with a well-formed VBIOS entry lacking an HPD mapping (get_hpd_line default), not only crafted values. Twin precedent: DF-4312 inconclusive, DF-4319/DF-4352 untested.", "recommended_fix": "Validate transmitter/channel/hpd_source against ARRAY_SIZE(link_enc_regs)/ARRAY_SIZE(link_enc_aux_regs)/ARRAY_SIZE(link_enc_hpd_regs) in dce112_link_encoder_create and return NULL (caller dc_link.c:1184-1189 fails the link cleanly) \u2014 see fix.diff", "fix_status": "not_testable", "fix_baseline_reproduced": 0, "fix_patched_reproduced": 0, "fix_verdict": "not_applicable->not_testable: no DCE112 hardware on the verification guest, so no baseline or patched kernel run is possible. fix.diff is git-apply-clean against sys/ (git apply --check OK), adds a 4-statement unsigned range check (rejects -1 sentinels and above-range values) with kfree(enc110)+NULL return; the caller core/dc_link.c:1184-1189 already handles NULL by failing link construction gracefully, so the check cannot regress bring-up beyond refusing the malformed VBIOS entry. Same treatment as twins DF-4319/DF-4352.", "fix_evidence": "git apply --check findings/poc/DF-4375/fix.diff => OK (sys/ left unmodified); diff context generated mechanically from the pristine tree (orig.c vs patched.c in run notes)" } |