# DF-4166 — get_gpio_i2c_info off-by-one lets table_index == count index gpio_pin[] past the table

- File: sys/dev/drm/amd/display/dc/bios/bios_parser2.c:367-403
- Class: OOB read (off-by-one), CWE-125. Hardware-gated (DCE12+ ASIC, crafted VBIOS).
- Distinct from DF-1415 (count derived from structuresize exceeding the declared
  gpio_pin[8]): here the table can be perfectly consistent (count == real entries,
  <= 8) and the guard `if (count < table_index)` still fails to catch
  table_index == count, so `header->gpio_pin[table_index]` reads ONE ENTRY PAST
  the table's declared end (gpio_pin[count]) at lines 374 and 403.

## Trigger math
  table_index = record->i2c_id & I2C_HW_LANE_MUX;   // 0x0f -> 0..15
  count = (structuresize - 4) / 8;                  // entries actually in table
  if (count < table_index) { /* search loop reassigns table_index in [0,count) */ }
  // count == table_index  ->  loop SKIPPED -> gpio_pin[count] read (OOB by 1 entry, 8 bytes)

E.g. a GPIO pin LUT with exactly 1 entry (count=1) and an I2C record whose lane
mux nibble is 1 -> reads gpio_pin[1], 8 bytes past the table data.

## Impact
Reads data_a_reg_index (MMIO register index) + gpio_bitshift from whatever follows
the table in the BIOS image (or past the image buffer if the table is at its end).
Values feed DC's GPIO/DDC programming (clk_a_register_index) -> wrong-register
MMIO access. Info leak ceiling: none direct (not copied to userspace).

## Build/run: not runnable here (no AMD GPU in audit guest, see env.txt).
Source-level certainty: comparison-operator bug, provable by inspection.
