DF i2c bit-bang shim is a stub: every radeon bit-banged DDC/EDID transfer is a silent no-op and the whole bit-bang block of radeon_i2c.c is dead code on DragonFly (display detection dead on default config)
Summary
The bit-bus branch calls i2c_bit_add_bus, which installs a stub algorithm whose master_xfer is '/* XXX Linux really does try to transfer some data here */ return 0' and never invokes the algo_bit callbacks - so radeon's pre/post_xfer/set/get clock/data are dead code, and with default radeon_hw_i2c=0 every DDC bus takes the bit branch: ddc_probe always false, EDID never readable. i915 unaffected (real GMBUS kept). Availability-of-function port defect, no memory-safety primitive; also masks DF-4445's hardware effect. Port-the-algo fix. Pack also records the latent register-then-free at :970-977 (dead today).
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-4446 Β· 4 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 1.5 KB | β raw | |
| VERDICT.md | β | 3.1 KB | β raw | |
| verdict.json | β | 1.9 KB | view raw | |
| manifest.json | β | 567 B | view raw |
DF-4446 evidence pack
- What: On DragonFly the Linux-compat i2c shim replaces the bit-bang
algorithm with a stub:
i2c_bit_add_bus()(sys/dev/drm/linux_i2c.c:127-134) installsi2c_bit_algowhosemaster_xferisbit_xfer()β "XXX Linux really does try to transfer some data here" βreturn 0;(linux_i2c.c:106-111), never callingalgo_datacallbacks. Inradeon_i2c_create()'s bit-bus branch (sys/dev/drm/radeon/radeon_i2c.c:955-978) this makespre_xfer/post_xfer/get_clock/get_data/set_clock/set_data(radeon_i2c.c:90-232) dead code, and every DDC/EDID transaction on a bit-banged bus "succeeds" with 0 messages transferred β so with the defaultradeon_hw_i2c=0(all non-mm_i2cDDC buses take the bit branch),radeon_ddc_probe()always fails (ret != 2,radeon_i2c.c:72-74) anddrm_do_probe_ddc_edid()never obtains an EDID: display detection is silently dead for pre-DCE3 radeons (and any bit-path bus) on DragonFly. - Severity: Info (functional availability defect of the port; no memory safety β no attacker primitive). Verification skipped per contract (Info), and the audit guest has no radeon hardware anyway.
- Fix direction: implement the bit-bang protocol in
sys/dev/drm/linux_i2c.cusingi2c_algo_bit_datacallbacks (port Linux'si2c-algo-bit.cbit_xfer), or route the DF radeon bit buses through the real hardware GPIO engine.
Files
VERDICT.mdβ static line-cited analysisverdict.json(statusuntested),manifest.json
DF-4446 β DF i2c bit-bang shim is a stub: all radeon bit-bang DDC/EDID transfers are silent no-ops; the entire bit-bang block of radeon_i2c.c is dead code on DragonFly
Verdict
Status: untested (Info severity β skipped per contract; also hardware-gated). Static analysis: certain.
Line-cited trace
radeon_i2c_create()bit-bus branch (sys/dev/drm/radeon/radeon_i2c.c:955-978): setsi2c->adapter.algo_data = &i2c->bit;and the six callbacks (pre_xfer/post_xfer/set_clock/set_data/get_clock/get_data), then callsi2c_bit_add_bus(&i2c->adapter).- DF's shim
i2c_bit_add_bus()(sys/dev/drm/linux_i2c.c:127-134) doesadapter->algo = &i2c_bit_algo; adapter->retries = 2; return 0;β overwriting nothing that matters, becausei2c_bit_algo.master_xferisbit_xfer()(linux_i2c.c:106-111):/* XXX Linux really does try to transfer some data here */ return 0;β it never looks atalgo_data, so none of radeon's GPIO bit-bang callbacks (radeon_i2c.c:90-232) ever execute. - With the module default
radeon_hw_i2c == 0, the selection logic atradeon_i2c.c:933-955routes every non-mm_i2cbus (i.e. every DDC bus) to this bit branch; onlyradeon_hw_i2c=1(explicitly discouraged byradeon_i2c_init()'s own warning at:999-1000) selects the real r100/r500/atom hardware engines. - Effect:
i2c_transfer()(linux_i2c.c:91-104) callsbit_xferβ 0; callers requireret == num:radeon_ddc_probe()(radeon_i2c.c:66-74) always returns false;drm_do_probe_ddc_edid()(sys/dev/drm/drm_edid.c:1513-1558) always fails β no EDID on any bit-path bus β connector reports disconnected. (Contrast i915:intel_i2c.ckeeps the real GMBUS algorithm and only uses the stub as a rare fallback, so i915 DDC works.)
Also noted (no independent finding): the DF-only
i2c_add_adapter(&i2c->adapter) call placed between i2c_bit_add_bus()
and its error check (radeon_i2c.c:970-973) is a latent UAF pattern
(adapter registered then chan freed on bit_add_bus failure), but on the
current shim both functions unconditionally return 0, so the path is
unreachable β recorded here for when the shim grows real error returns.
Impact
Functional: display hotplug/EDID detection dead for bit-banged buses (pre-DCE3 radeon, and any bus on the bit path) on DragonFly. No memory safety, no attacker primitive β Info.
Fix direction
Port Linux's drivers/i2c/algos/i2c-algo-bit.c bit_xfer() into
sys/dev/drm/linux_i2c.c (it only needs the i2c_algo_bit_data callbacks
already declared in sys/dev/drm/include/linux/i2c-algo-bit.h), or bypass
the shim for radeon buses. i915 is unaffected either way.
Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest make -j6 nativekernel KERNCONF=X86_64_GENERIC completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
(No fix.diff for this item: documented recommendation only - see Fix above.)
Fix verification
not_testablenot_testable (Info functional finding; no hw)
VERDICT.md
Confirmed kernel references
Detail
Evidence (decisive lines)
VERDICT.md (line-cited: shim stub vs radeon bit-bus branch); README.md
PoC changes
n/a (static finding)
Verified recommended fix
Implement real bit_xfer in sys/dev/drm/linux_i2c.c using the i2c_algo_bit_data callbacks (port Linux i2c-algo-bit.c)
Verdict
Static proof certain: DF's i2c_bit_add_bus (sys/dev/drm/linux_i2c.c:127-134) installs a stub algorithm whose master_xfer returns 0 without touching hardware (linux_i2c.c:106-111), so radeon_i2c_create()'s bit-bus branch (radeon_i2c.c:955-978) leaves pre_xfer..set_data (radeon_i2c.c:90-232) as dead code and every DDC/EDID transfer on a bit path 'succeeds' with 0 messages β display detection silently dead for all default-config radeon DDC buses on DragonFly. Info severity (functional port defect, no memory safety, no attacker primitive); runtime verification skipped per contract and hardware-gated anyway (guest has virtio-gpu only).
No comments yet.