GHSA-76fx-m4mf-24gq: NULL pointer dereference in the MCTP I2C+GPIO target binding triggerable by a peer I2C controller
The MCTP-over-I2C+GPIO target binding in subsys/pmci/mctp/mctpi2cgpiotarget.c emulates a small pseudo-register file, where the bus controller first writes a register number and then writes or reads payload bytes. The selected register (b->regaddr) and the data-phase flag (b->rxtx) were never cleared when the controller issued an I2C STOP, so after a completed transfer the target still had a data register selected while the packet buffer that register refers to had already been consumed and set to NULL by mctpi2cgpiotargetstop().
A controller on the bus can re-enter the same branch of mctpi2cgpiotargetstop() with a NULL buffer using two ordinary transactions and no authentication: first a normal packet write to MCTPI2CGPIORXMSGADDR followed by STOP (which delivers and frees b->rxpkt), then a bare read transaction followed by STOP. The failing readrequested() call leaves the stale state untouched and the I2C driver still delivers the STOP callback, which then calls mctpbusrx() with a NULL packet. The symmetric case exists on the transmit side, where the stale MCTPI2CGPIOTXMSGADDR selection dereferences b->txpkt->end after b->txpkt has been cleared and additionally signals b->txcomplete a second time, causing the next outbound packet to be dropped.
The dereference happens in the I2C target interrupt handler, so on any target that traps accesses to address 0 the result is a fatal exception and a device reset or halt — a denial of service inflicted by any device able to act as controller on the shared management bus (for example compromised firmware on a peer MCTP endpoint or on the BMC). On parts where address 0 is readable, the impact degrades to a malformed packet buffer being handed to the MCTP stack and lost transmit packets. No attacker-controlled value is written and no confidentiality or integrity boundary is crossed.
The fix resets b->regaddr to MCTPI2CGPIOINVALIDADDR and clears b->rxtx at every STOP, so a new register must be selected before any data phase can run again. Only builds that opt into the experimental CONFIGMCTP subsystem with CONFIGMCTPI2CGPIOTARGET=y are affected.