dce110 i2c hw engine: SW engine-state accounting desync corrupts subsequent DDC/I2C transactions β write-path buffer_used_bytes undercounts (length consumed before the accounting add), counters never reset on aborted-busy/release paths, and I2C_HW_BUFFER_SIZE=538 exceeds the 8-bit DC_I2C_INDEX/COUNT0 fields
Summary
WRITE transactions account only the address byte (the length is zeroed by the write loop before the accounting add) so free-space is overstated for MOT batches; counters/TRANSACTION registers only reset on the success path, so a busy-abort or release poisons the next acquire (INDEX_WRITE skipped, aborted chain re-executed - garbage DDC/EDID until some chain completes); 538-byte buffer vs 8-bit fields (latent truncation). No kernel memory unsafety (caller-sized writes); upstream twin. Account-original + reset-on-release + clamp fix.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-4808 Β· 1 files| File | Type | Description | Size | |
|---|---|---|---|---|
| verdict.json | file | 1.7 KB | view raw |
Fix verification
not_testableConfirmed kernel references
Detail
Exploit chain
interleave a multi-payload WRITE-MOT DDC batch with a busy engine (submit_channel_request is_hw_busy path) -> next EDID read executes against stale TRANSACTION registers and stale DC_I2C_INDEX base -> corrupted EDID / persistent DDC failure
Evidence (decisive lines)
findings/poc/DF-4808/ (this verdict)
Verdict
Hardware-gated data-integrity defect (no kernel memory unsafety - all writes caller-sized): three coupled accounting defects in the DCE110 hw I2C engine - (1) process_transaction zeroes its local length in the write loop then accounts buffer_used_bytes += length+1, so WRITE transactions account only the address byte and get_hw_buffer_available_size overstates free space for MOT batches (the submit_request guard admits more than the HW circular buffer holds); (2) counters/DC_I2C_TRANSACTIONn registers only reset in execute_transaction - an ENGINE_BUSY abort or release between sub-transactions leaves stale state so the next acquire lands payloads with INDEX_WRITE skipped and re-executes the aborted chain (garbage DDC/EDID traffic until some chain completes); (3) I2C_HW_BUFFER_SIZE=538 exceeds the 8-bit DC_I2C_INDEX/COUNT0 field masks (latent truncation >255). Upstream twin exists (Linux dce110/dce80 identical). No AMD GPU on guest - skipped per Low severity. Account-original-length + reset-on-release + clamp fix.
No comments yet.