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]> --- v7: do not double-adjust endptr and drop redundant check against ULLONG_MAX v6: handle valid-suffix-only string like "k" as unrecognized, minor style adjustments v5: initial version to join the series --- lib/cmdline.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/lib/cmdline.c b/lib/cmdline.c index 90ed997d9570..32da6f5a9cdb 100644 --- a/lib/cmdline.c +++ b/lib/cmdline.c @@ -150,39 +150,50 @@ EXPORT_SYMBOL(get_options); unsigned long long memparse(const char *ptr, char **retptr) { char *endptr; /* local pointer to end of parsed string */ - unsigned long long ret = simple_strtoull(ptr, &endptr, 0); + unsigned int shl = 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; - endptr++; + shl += 10; fallthrough; default: break; } + if (shl && likely(ptr != endptr)) { + /* Have valid suffix with preceding number. */ + unsigned long long val; + + if (unlikely(check_shl_overflow(ret, shl, &val))) + ret = ULLONG_MAX; + else + ret = val; + endptr++; + } + if (retptr) *retptr = endptr; -- 2.53.0
