From 1440122d61d5b0a3f8360f4e2101db1018109799 Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Wed, 29 Apr 2015 03:28:18 -0700 Subject: [PATCH] common/config: detect overflow of float values Signed-off-by: Kefu Chai (cherry picked from commit 1ff409ef8d022a1a84d034bd3db976c4d769e993) --- src/common/config.cc | 18 ++++++++++++++---- src/test/daemon_config.cc | 19 +++++++++++++++++++ 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/common/config.cc b/src/common/config.cc index f2460c636e279..5e923e6fa658c 100644 --- a/src/common/config.cc +++ b/src/common/config.cc @@ -894,12 +894,22 @@ int md_config_t::set_val_raw(const char *val, const config_option *opt) case OPT_STR: *(std::string*)opt->conf_ptr(this) = val ? val : ""; return 0; - case OPT_FLOAT: - *(float*)opt->conf_ptr(this) = atof(val); + case OPT_FLOAT: { + std::string err; + float f = strict_strtof(val, &err); + if (!err.empty()) + return -EINVAL; + *(float*)opt->conf_ptr(this) = f; return 0; - case OPT_DOUBLE: - *(double*)opt->conf_ptr(this) = atof(val); + } + case OPT_DOUBLE: { + std::string err; + double f = strict_strtod(val, &err); + if (!err.empty()) + return -EINVAL; + *(double*)opt->conf_ptr(this) = f; return 0; + } case OPT_BOOL: if (strcasecmp(val, "false") == 0) *(bool*)opt->conf_ptr(this) = false; diff --git a/src/test/daemon_config.cc b/src/test/daemon_config.cc index 2968b3514a2fa..6d32e150ccc49 100644 --- a/src/test/daemon_config.cc +++ b/src/test/daemon_config.cc @@ -360,6 +360,25 @@ TEST(DaemonConfig, InvalidIntegers) { } } +TEST(DaemonConfig, InvalidFloats) { + { + double bad_value = 2 * (double)std::numeric_limits::max(); + string str = boost::lexical_cast(-bad_value); + int ret = g_ceph_context->_conf->set_val("log_stop_at_utilization", str); + ASSERT_EQ(ret, -EINVAL); + } + { + double bad_value = 2 * (double)std::numeric_limits::max(); + string str = boost::lexical_cast(bad_value); + int ret = g_ceph_context->_conf->set_val("log_stop_at_utilization", str); + ASSERT_EQ(ret, -EINVAL); + } + { + int ret = g_ceph_context->_conf->set_val("log_stop_at_utilization", "not a float"); + ASSERT_EQ(ret, -EINVAL); + } +} + /* * Local Variables: * compile-command: "cd .. ; make unittest_daemon_config && ./unittest_daemon_config" -- 2.39.5