DF-5163 / ddc_race_sketch.c
/* * DF-5163 โ conceptual trigger sketch (NOT runnable without AMD hardware). * * The defect: amdgpu_atombios_i2c_process_i2c_ch() (atombios_i2c.c:103-104) * reads the received i2c bytes out of the SHARED atom fb scratch * (atom_context->scratch, amdgpu_atombios.c:1814-1821, >= 20 KiB, kzalloc'd) * AFTER amdgpu_atom_execute_table() (atombios_i2c.c:94) has already * released the only lock that serializes scratch users (ctx->mutex, * atom.c:1277). The radeon twin of this exact code takes an additional * atom_context->scratch_mutex across execute+read โ added upstream in 2015 * precisely to fix this race โ but amdgpu's struct atom_context has no such * lock at all (atom.h:128-147). * * Race window: * thread A (bus X): execute ProcessI2cChannelTransaction -> scratch = Xdata * thread B (bus Y): execute ProcessI2cChannelTransaction -> scratch = Ydata * thread A: amdgpu_atombios_copy_swap(buf, base, num) -> reads * Ydata (or a mix) as if it came from bus X. * * Consequence: cross-contaminated DDC data โ e.g. connector X's EDID read * returns bytes belonging to connector Y's transaction. Memory-safe (num is * bounded to 255 at atombios_i2c.c:79 and scratch is >= 20 KiB), so the * impact ceiling is wrong display-probe data / misparsed EDID, i.e. data * confusion, not memory corruption. * * To exercise on hardware you need: * - an amdgpu ASIC with >= 2 hw_capable DDC buses (amdgpu_hw_i2c defaults * to 1 in this tree โ amdgpu_drv.c:88 โ so the atom i2c algo is selected * at amdgpu_i2c.c:187-190 by default), * - two concurrent display-probe/DDC storms (e.g. repeated hotplug-detect * polling on two connectors), one reading a small EEPROM-ish device and * one reading a normal monitor, then diff which EDID bytes come back on * which connector. * The same post-execute scratch read pattern also exists in * atombios_dp.c:114 (DP aux) โ same class, same fix umbrella. * * This file exists to document the trigger; it is not compiled on the audit * guest because the guest's VGA is virtio and amdgpu never attaches. */ #include <stdio.h> int main(void) { printf("DF-5163: conceptual only โ requires amdgpu hardware with two " "hw_capable DDC buses; see header comment and VERDICT.md\n"); return (0); } |