On Thu, Jul 16, 2026 at 5:06 PM Christopher Kleiner <[email protected]> wrote: > > fsa_user_info.gpios[] is a fixed 20-element array, but the number of > descriptors iterated and indexed comes from the FSA add-on board EEPROM: > board_info.sockgpios and board_info.ioexpgpios are u8 fields (up to 255 > each) read via dm_i2c_read() with no upper bound. > > fsa_config_gpios(), invoked automatically at boot from fsa_init(), loops > over info->gpios[i] for i < sockgpios + ioexpgpios, reading past the > 20-element array (an out-of-bounds stack read whose contents are then > used to configure GPIOs and build names). do_fsa_gpio() validates the > console-supplied index only against the same EEPROM counts, so > "fsa gpio <i> ..." can memcpy() a descriptor to user_info.gpios[i] for i > up to 254 -- an out-of-bounds stack write that is then written back to > the EEPROM. > > A malicious or swapped FSA add-on board EEPROM (only a valid checksum is > required, which the attacker can compute) thus yields OOB accesses on the > boot path and via the console command. > > Clamp the descriptor count to ARRAY_SIZE(info->gpios) before iterating, > and reject any console index outside the array. > > Fixes: da9e2218afc2 ("board: venice: add FSA support") > Signed-off-by: Christopher Kleiner <[email protected]> > --- > board/gateworks/fsa.c | 8 ++++++++ > 1 file changed, 8 insertions(+) > > diff --git a/board/gateworks/fsa.c b/board/gateworks/fsa.c > index 1af8021057..126a897ee2 100644 > --- a/board/gateworks/fsa.c > +++ b/board/gateworks/fsa.c > @@ -140,6 +140,9 @@ static int fsa_config_gpios(int fsa, struct fsa_user_info > *info, int gpios, stru > int i, ret, flags; > char name[32]; > > + /* clamp EEPROM-supplied descriptor count to the array size */ > + if (gpios > ARRAY_SIZE(info->gpios)) > + gpios = ARRAY_SIZE(info->gpios); > /* configure GPIO's */ > for (i = 0; i < gpios; i++) { > desc = &info->gpios[i]; > @@ -637,6 +640,11 @@ static int do_fsa_gpio(struct cmd_tbl *cmdtp, int flag, > int argc, char * const a > memset(&desc, 0, sizeof(desc)); > i = simple_strtoul(argv[0], NULL, 10); > > + if (i < 0 || i >= (int)ARRAY_SIZE(user_info.gpios)) { > + printf("invalid index %d", i); > + return CMD_RET_FAILURE; > + } > + > if (i >= 0 && i < board_info.sockgpios) { > desc.offset = i; > desc.source = 0xff; > -- > 2.43.0 >
Hi Chris, Acked-by: Tim Harvey <[email protected]> Thanks! Tim
