From 4d32abaa874db06ec84aeefafa1354548f91d650 Mon Sep 17 00:00:00 2001 From: Ryan Moeller Date: Mon, 16 Mar 2020 14:56:29 -0400 Subject: [PATCH] libzfs: Fix bounds checks for float parsing UINT64_MAX is not exactly representable as a double. The closest representation is UINT64_MAX + 1, so we can use a >= comparison instead of > for the bounds check. Reviewed-by: Brian Behlendorf Signed-off-by: Ryan Moeller Closes #10127 --- cmd/ztest/ztest.c | 7 ++++++- lib/libzfs/libzfs_util.c | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/cmd/ztest/ztest.c b/cmd/ztest/ztest.c index e4b0f61f88..92b46c2968 100644 --- a/cmd/ztest/ztest.c +++ b/cmd/ztest/ztest.c @@ -648,7 +648,12 @@ nicenumtoull(const char *buf) } else if (end[0] == '.') { double fval = strtod(buf, &end); fval *= pow(2, str2shift(end)); - if (fval > UINT64_MAX) { + /* + * UINT64_MAX is not exactly representable as a double. + * The closest representation is UINT64_MAX + 1, so we + * use a >= comparison instead of > for the bounds check. + */ + if (fval >= (double)UINT64_MAX) { (void) fprintf(stderr, "ztest: value too large: %s\n", buf); usage(B_FALSE); diff --git a/lib/libzfs/libzfs_util.c b/lib/libzfs/libzfs_util.c index a8e9ac9cbb..c6debd576d 100644 --- a/lib/libzfs/libzfs_util.c +++ b/lib/libzfs/libzfs_util.c @@ -1411,7 +1411,12 @@ zfs_nicestrtonum(libzfs_handle_t *hdl, const char *value, uint64_t *num) fval *= pow(2, shift); - if (fval > UINT64_MAX) { + /* + * UINT64_MAX is not exactly representable as a double. + * The closest representation is UINT64_MAX + 1, so we + * use a >= comparison instead of > for the bounds check. + */ + if (fval >= (double)UINT64_MAX) { if (hdl) zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "numeric value is too large"));