DF-4966 / verdict.json
{ "finding_id": "DF-4966", "status": "reproduced", "reproduced": 1, "impact": "none", "confidence": "certain", "verdict": "id_to_offset in hw_translate_dce110.c assigns the shared DDC data mask DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK (0x100) to every GPIO_ID_DDC_DATA line (line 190) and merely swaps the offset to mmDC_GPIO_I2CPAD_A (0x4899) for GPIO_DDC_LINE_I2C_PAD (lines 213-215). The DCE11 register DC_GPIO_I2CPAD_A defines only SCL=bit0 (0x1) and SDA=bit1 (0x2) (dce_11_0_sh_mask.h:4203-4206), so the DDC_DATA(SDA) translation carries a mask for a bit that does not exist in the target register. Deterministic (constant arithmetic), executed on the DF guest: mask_check run.log shows id_to_offset(DDC_DATA, I2C_PAD) mask = 0x100 -> WRONG: selects bit 8; SDA is bit 1, with the DDC1 control and the DDC_CLOCK/I2C_PAD case (0x1 == SCL by coincidence) correct. Consequence: REG_UPDATE/REG_GET on 0x4899 read-modify-write an undefined bit and never touch the real SDA bit -- functional defect (I2C-pad DDC line dead / reserved-bit MMIO write), upstream-shared AMD DAL code, no kernel memory-safety impact. Info severity.", "exploit_chain": "", "evidence": "run.log: id_to_offset(DDC_DATA, I2C_PAD) mask = 0x100 -> WRONG vs real SCL=0x1/SDA=0x2 field layout; controls: DDC_CLOCK/I2C_PAD mask 0x1 == SCL (correct by coincidence), DDC_DATA/DDC1 mask 0x100 == DDC1DATA (shared mask valid for real DDC lines).", "kernel_refs": [ "sys/dev/drm/amd/display/dc/gpio/dce110/hw_translate_dce110.c:190", "sys/dev/drm/amd/display/dc/gpio/dce110/hw_translate_dce110.c:213", "sys/dev/drm/amd/include/asic_reg/dce/dce_11_0_sh_mask.h:4203", "sys/dev/drm/amd/display/dc/core/dc_link_ddc.c:272" ], "poc_changes": "fresh minimal constant-arithmetic harness; fixed a nested-comment gcc error from the seed draft.", "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": 5, "guest_dirty": 0, "build_cmd": "gcc -O2 -Wall -Wextra -o mask_check mask_check.c", "run_cmd": "./mask_check", "code_hash": "e91e02c6dc3da41049a6f8a74cf22e504e6baba8fd2f661d36c5088cc6b6ee2f", "fix_status": "not_applicable", "fix_baseline_reproduced": 1, "fix_patched_reproduced": 0, "fix_verdict": "fix.diff overrides the mask in the DDC_DATA/I2C_PAD case with DC_GPIO_I2CPAD_A__DC_GPIO_SDA_A_MASK (0x2) -- the defect is pure constant selection, structurally eliminated by the one-line override; all other lines keep the shared mask (harness controls). No kernel-build validation possible on this guest (no AMD hardware); Info-severity functional fix.", "fix_evidence": "fix.diff (2-line hunk, hw_translate_dce110.c DDC_DATA/I2C_PAD case); run.log controls demonstrate shared-mask correctness for the other seven lines.", "notes": "Found during the pass-2 audit of hw_translate_dce110.c prompted by the id_to_offset shared-mask review item. Upstream-shared with AMD DAL dce110. Prompt-verified non-findings on this file: no mmGPIOPAD_A reverse-map case (DF-4942 producer absent), no GPIO_ID_GPIO_PAD forward-map case (DF-4944 absent), ddc arrays sized 8 (in-bounds).", "recommended_fix": "Set info->mask = DC_GPIO_I2CPAD_A__DC_GPIO_SDA_A_MASK in the GPIO_ID_DDC_DATA / GPIO_DDC_LINE_I2C_PAD case." } |