On 7/27/26 7:50 AM, Christian Borntraeger wrote:
> From: Joshua Daley <[email protected]>
> 
> menu_get_zipl_boot_index() iterates NUL-separated strings from the
> zipl stage-2 boot-menu block, passes each to zipl_print_entry() which
> converts EBCDIC to ASCII and returns atoi(), then writes true into
> valid_entries[entry]. valid_entries is a MAX_BOOT_ENTRIES element
> stack array, but entry was never bounds-checked, so a crafted on-disk
> value could index arbitrarily beyond the array.
> 
> Fix this in two places:
> 
> - zipl_print_entry() now validates that the first significant character
>   (after an optional leading space) is a digit. Entries that fail this
>   check return -1 without printing.
> 
> - menu_get_zipl_boot_index() skips any entry whose index is outside
>   [0, MAX_BOOT_ENTRIES) before writing to valid_entries[].
> 
> Fixes: 7385e947fc65 ("pc-bios/s390-ccw: fix non-sequential boot entries 
> (eckd)")
> Signed-off-by: Joshua Daley <[email protected]>

Reviewed-by: Matthew Rosato <[email protected]>

> ---
>  pc-bios/s390-ccw/menu.c | 13 +++++++++++--
>  1 file changed, 11 insertions(+), 2 deletions(-)
> 
> diff --git a/pc-bios/s390-ccw/menu.c b/pc-bios/s390-ccw/menu.c
> index eeaff78f87..b6a9a56d46 100644
> --- a/pc-bios/s390-ccw/menu.c
> +++ b/pc-bios/s390-ccw/menu.c
> @@ -176,18 +176,24 @@ int menu_get_boot_index(bool *valid_entries)
>      return boot_index;
>  }
>  
> -/* Returns the entry number that was printed */
> +/* Returns the entry number that was printed, or -1 on invalid entry */
>  static int zipl_print_entry(const char *data, size_t len)
>  {
>      char buf[len + 2];
> +    const char *p;
>  
>      ebcdic_to_ascii(data, buf, len);
>      buf[len] = '\n';
>      buf[len + 1] = '\0';
>  
> +    p = (buf[0] == ' ') ? buf + 1 : buf;
> +    if (!isdigit((unsigned char)*p)) {
> +        return -1;
> +    }
> +
>      printf("%s", buf);
>  
> -    return buf[0] == ' ' ? atoi(buf + 1) : atoi(buf);
> +    return atoi(p);
>  }
>  
>  int menu_get_zipl_boot_index(const char *menu_data)
> @@ -216,6 +222,9 @@ int menu_get_zipl_boot_index(const char *menu_data)
>          entry = zipl_print_entry(menu_data, len);
>          menu_data += len + 1;
>  
> +        if (entry < 0 || entry >= MAX_BOOT_ENTRIES) {
> +            continue;
> +        }
>          valid_entries[entry] = true;
>  
>          if (entry == 0) {


Reply via email to