โฌข DragonFlyBSD Kernel Audit
DF-5034 / verdict.json
โ† back to finding โ†“ download raw
{
  "finding_id": "DF-5034",
  "status": "untested",
  "reproduced": false,
  "impact": "none",
  "confidence": "certain",
  "verdict": "acquire_i2c_hw_engine() bounds the DDC-line index only above (line < GPIO_DDC_LINE_COUNT, i2caux_dce110.c:98) although enum gpio_ddc_line is signed with GPIO_DDC_LINE_UNKNOWN = -1 (gpio_types.h:207); a -1 reads i2c_hw_engines[-1], which struct-layout-wise aliases i2c_sw_engines[7] (i2caux.h:67-71) โ€” a slot that is never populated in the dce110 constructor family (use_i2c_sw_engine hardcoded false at i2caux_dce110.c:213; hw lines fill only indices 0..5), so the read is NULL and the function returns NULL. Benign today, fragile by accident, unreachable without a crafted VBIOS on real DCE11 hardware. Filed as the dce110 twin of DF-2089 (dce80). No PoC run: Info hardening finding, and the QEMU guest has no AMD display controller (virtio GPU only, no drm KLD).",
  "exploit_chain": "",
  "evidence": "README.md and VERDICT.md (full trace); run ./analysis.sh to print every cited line: i2caux_dce110.c:92-112, gpio_types.h:206-220 (UNKNOWN=-1, GPIO_DDC_LINE_MIN exists at :218), i2caux.h:55-98 (array layout), gpio_service.c:566-570 (dal_ddc_get_line), dce80 twin i2caux_dce80.c:122-127.",
  "kernel_refs": [
    "sys/dev/drm/amd/display/dc/i2caux/dce110/i2caux_dce110.c:98",
    "sys/dev/drm/amd/display/include/gpio_types.h:207",
    "sys/dev/drm/amd/display/dc/gpio/gpio_service.c:566",
    "sys/dev/drm/amd/display/dc/i2caux/i2caux.h:67"
  ],
  "poc_changes": "No PoC written โ€” finding is an index-guard hardening note; evidence is a mechanical source-print script (analysis.sh) instead.",
  "attempts": 0,
  "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": 0,
  "guest_dirty": 0,
  "build_cmd": "",
  "run_cmd": "",
  "code_hash": "",
  "notes": "Twin of DF-2089 (dce80, Info). struct-layout aliasing makes the current outcome a NULL read, not a wild pointer: i2c_hw_engines[-1] == i2c_sw_engines[7], which no constructor in the family (dce100/110/112/120/dcn10 all via dal_i2caux_dce110_construct) ever assigns. hw_supported flag itself is VBIOS-derived (i2c_hw_assist, dc_link_ddc.c:270), so even a -1 line requires crafted firmware on real AMD hardware.",
  "recommended_fix": "Add the enum-provided lower bound: if (line >= GPIO_DDC_LINE_MIN && line < GPIO_DDC_LINE_COUNT) โ€” see fix.diff.",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": false,
  "fix_patched_reproduced": false,
  "fix_verdict": "n/a โ€” finding not reproduced (no AMD ASIC in the test guest); fix is a pure index guard, reviewed against the enum definition only.",
  "fix_evidence": "fix.diff (GPIO_DDC_LINE_MIN guard, mirrors the DF-2089 fix shape)."
}