Since '_parse_integer_limit()' (and so 'simple_strtoull()') is now capable to handle overflow, adjust 'memparse()' to handle overflow (denoted by ULLONG_MAX) returned from 'simple_strtoull()'. Also use 'check_shl_overflow()' to catch an overflow possibly caused by processing size suffix and denote it with ULLONG_MAX as well.
Signed-off-by: Dmitry Antipov <[email protected]> --- v5: initial version to join the series --- lib/cmdline.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/lib/cmdline.c b/lib/cmdline.c index 90ed997d9570..e18fdfb80ba5 100644 --- a/lib/cmdline.c +++ b/lib/cmdline.c @@ -151,38 +151,48 @@ unsigned long long memparse(const char *ptr, char **retptr) { char *endptr; /* local pointer to end of parsed string */ + unsigned int shl = 0; unsigned long long ret = simple_strtoull(ptr, &endptr, 0); + /* Consume valid suffix even in case of overflow. */ switch (*endptr) { case 'E': case 'e': - ret <<= 10; + shl += 10; fallthrough; case 'P': case 'p': - ret <<= 10; + shl += 10; fallthrough; case 'T': case 't': - ret <<= 10; + shl += 10; fallthrough; case 'G': case 'g': - ret <<= 10; + shl += 10; fallthrough; case 'M': case 'm': - ret <<= 10; + shl += 10; fallthrough; case 'K': case 'k': - ret <<= 10; + shl += 10; endptr++; fallthrough; default: break; } + /* If no overflow, apply suffix if any. */ + if (likely(ret != ULLONG_MAX) && shl) { + unsigned long long val; + + ret = (unlikely(check_shl_overflow(ret, shl, &val)) + ? ULLONG_MAX : val); + } + if (retptr) *retptr = endptr; -- 2.52.0
