diff --git a/zipl/boot/ebcdic.c b/zipl/boot/ebcdic.c index be3441b7..2d0bb536 100644 --- a/zipl/boot/ebcdic.c +++ b/zipl/boot/ebcdic.c @@ -8,11 +8,13 @@ * */ +#include + #include "ebcdic.h" - /* - * Convert ebcdic string to number with given base + * Convert EBCDIC string to number with given base. In case of an overflow, + * ULONG_MAX is returned and @endptr is not updated. */ unsigned long ebcdic_strtoul(char *nptr, char **endptr, int base) { @@ -21,7 +23,8 @@ unsigned long ebcdic_strtoul(char *nptr, char **endptr, int base) while (ebcdic_isdigit(*nptr)) { if (val != 0) val *= base; - val += *nptr - 0xf0; + if (__builtin_uaddl_overflow(val, *nptr - 0xf0, &val)) + return ULONG_MAX; nptr++; } if (endptr) diff --git a/zipl/boot/menu.c b/zipl/boot/menu.c index 6d30cf81..73bb11d2 100644 --- a/zipl/boot/menu.c +++ b/zipl/boot/menu.c @@ -27,12 +27,12 @@ static void menu_prompt(int timeout) printf("Please choose:"); } -static int menu_read(void) +static unsigned long menu_read(void) { char *temp_area = (char *)get_zeroed_page(); int timeout, rc, i, count = 0; + unsigned long value; char *endptr; - int value; timeout = __stage2_params.timeout;