From 89d8e58718da7d500920e2ed869270637ddb169e Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Fri, 2 Mar 2018 08:58:54 -0500 Subject: [PATCH] util/cutils: Change qemu_strtosz*() from int64_t to uint64_t This will permit its use in parse_option_size(). Backports commit f46bfdbfc8f95cf65d7818ef68a801e063c40332 from qemu --- qemu/include/qemu/cutils.h | 6 +++--- qemu/target/i386/cpu.c | 4 ++-- qemu/util/cutils.c | 14 +++++++++----- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/qemu/include/qemu/cutils.h b/qemu/include/qemu/cutils.h index 34822da0..c77b9e77 100644 --- a/qemu/include/qemu/cutils.h +++ b/qemu/include/qemu/cutils.h @@ -131,9 +131,9 @@ int qemu_strtoi64(const char *nptr, const char **endptr, int base, int qemu_strtou64(const char *nptr, const char **endptr, int base, uint64_t *result); -int qemu_strtosz(const char *nptr, char **end, int64_t *result); -int qemu_strtosz_MiB(const char *nptr, char **end, int64_t *result); -int qemu_strtosz_metric(const char *nptr, char **end, int64_t *result); +int qemu_strtosz(const char *nptr, char **end, uint64_t *result); +int qemu_strtosz_MiB(const char *nptr, char **end, uint64_t *result); +int qemu_strtosz_metric(const char *nptr, char **end, uint64_t *result); #define K_BYTE (1ULL << 10) #define M_BYTE (1ULL << 20) diff --git a/qemu/target/i386/cpu.c b/qemu/target/i386/cpu.c index a6f3e87d..0ac838c2 100644 --- a/qemu/target/i386/cpu.c +++ b/qemu/target/i386/cpu.c @@ -2182,10 +2182,10 @@ static void x86_cpu_parse_featurestr(CPUState *cs, char *features, /* Special case: */ if (!strcmp(name, "tsc-freq")) { int ret; - int64_t tsc_freq; + uint64_t tsc_freq; ret = qemu_strtosz_metric(val, NULL, &tsc_freq); - if (ret < 0) { + if (ret < 0 || tsc_freq > INT64_MAX) { error_setg(errp, "bad numerical value %s", val); return; } diff --git a/qemu/util/cutils.c b/qemu/util/cutils.c index dfa128fc..36847630 100644 --- a/qemu/util/cutils.c +++ b/qemu/util/cutils.c @@ -156,7 +156,7 @@ static int64_t suffix_mul(char suffix, int64_t unit) */ static int do_strtosz(const char *nptr, char **end, const char default_suffix, int64_t unit, - int64_t *result) + uint64_t *result) { int retval; char *endptr; @@ -186,7 +186,11 @@ static int do_strtosz(const char *nptr, char **end, retval = -EINVAL; goto out; } - if ((val * mul >= INT64_MAX) || val < 0) { + /* + * Values >= 0xfffffffffffffc00 overflow uint64_t after their trip + * through double (53 bits of precision). + */ + if ((val * mul >= 0xfffffffffffffc00) || val < 0) { retval = -ERANGE; goto out; } @@ -203,17 +207,17 @@ out: return retval; } -int qemu_strtosz(const char *nptr, char **end, int64_t *result) +int qemu_strtosz(const char *nptr, char **end, uint64_t *result) { return do_strtosz(nptr, end, 'B', 1024, result); } -int qemu_strtosz_MiB(const char *nptr, char **end, int64_t *result) +int qemu_strtosz_MiB(const char *nptr, char **end, uint64_t *result) { return do_strtosz(nptr, end, 'M', 1024, result); } -int qemu_strtosz_metric(const char *nptr, char **end, int64_t *result) +int qemu_strtosz_metric(const char *nptr, char **end, uint64_t *result) { return do_strtosz(nptr, end, 'B', 1000, result); }