From: Christopher Kleiner Date: Fri, 17 Jul 2026 00:06:44 +0000 (-0400) Subject: board: gateworks: fsa: bound FSA EEPROM gpio descriptor count X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ce5793d777fd1f5bb6b0448c6366ba989c4a3509;p=thirdparty%2Fu-boot.git board: gateworks: fsa: bound FSA EEPROM gpio descriptor count 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 ..." 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 --- diff --git a/board/gateworks/fsa.c b/board/gateworks/fsa.c index 1af8021057c..126a897ee28 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;