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

Reply via email to