]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
board: gateworks: fsa: bound FSA EEPROM gpio descriptor count
authorChristopher Kleiner <chris@kleiner.pro>
Fri, 17 Jul 2026 00:06:44 +0000 (20:06 -0400)
committerFabio Estevam <festevam@gmail.com>
Mon, 27 Jul 2026 16:05:07 +0000 (13:05 -0300)
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 <chris@kleiner.pro>
board/gateworks/fsa.c

index 1af8021057c42bb1ff6f2fc348296e1f3c552258..126a897ee280cb57980d9b2d0caf664ba4f41e2a 100644 (file)
@@ -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;