From: Marcin Siodelski Date: Thu, 25 Oct 2012 18:05:29 +0000 (+0200) Subject: [2318] Do not allow zero and negative option codes. X-Git-Tag: trac2487_base~28^2~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4475bf75419cba6488628a2eb6f3b19fc795ae05;p=thirdparty%2Fkea.git [2318] Do not allow zero and negative option codes. --- diff --git a/src/bin/dhcp6/config_parser.cc b/src/bin/dhcp6/config_parser.cc index 6f3e6a0d87..490d8c060b 100644 --- a/src/bin/dhcp6/config_parser.cc +++ b/src/bin/dhcp6/config_parser.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") // // Permission to use, copy, modify, and/or distribute this software for any // purpose with or without fee is hereby granted, provided that the above @@ -154,12 +154,37 @@ public: /// /// @param value pointer to the content of parsed values virtual void build(ConstElementPtr value) { + bool parse_error = false; + // Cast the provided value to int64 value to check. + int64_t int64value = 0; try { - value_ = boost::lexical_cast(value->str()); - } catch (const boost::bad_lexical_cast &) { + // Parsing the value as a int64 value allows to + // check if the provided value is within the range + // of uint32_t (is not negative or greater than + // maximal uint32_t value. + int64value = boost::lexical_cast(value->str()); + } catch (const boost::bad_lexical_cast&) { + parse_error = true; + } + if (!parse_error) { + if ((int64value < 0) || + (int64value > std::numeric_limits::max())) { + parse_error = true; + } else { + try { + value_ = boost::lexical_cast(value->str()); + } catch (const boost::bad_lexical_cast &) { + parse_error = true; + } + } + + } + + if (parse_error) { isc_throw(BadValue, "Failed to parse value " << value->str() << " as unsigned 32-bit integer."); } + storage_->insert(pair(param_name_, value_)); } @@ -541,9 +566,13 @@ private: void createOption() { // Option code is held in the uint32_t storage but is supposed to // be uint16_t value. We need to check that value in the configuration - // does not exceed range of uint16_t. + // does not exceed range of uint16_t and is not zero. uint32_t option_code = getUint32Param("code"); - if (option_code > std::numeric_limits::max()) { + if (option_code == 0) { + isc_throw(Dhcp6ConfigError, "Parser error: value of 'code' must not" + << " be equal to zero. Option code '0' is reserved in" + << " DHCPv6."); + } else if (option_code > std::numeric_limits::max()) { isc_throw(Dhcp6ConfigError, "Parser error: value of 'code' must not" << " exceed " << std::numeric_limits::max()); } diff --git a/src/bin/dhcp6/tests/config_parser_unittest.cc b/src/bin/dhcp6/tests/config_parser_unittest.cc index 8067dd2660..02ca20cd90 100644 --- a/src/bin/dhcp6/tests/config_parser_unittest.cc +++ b/src/bin/dhcp6/tests/config_parser_unittest.cc @@ -434,11 +434,6 @@ TEST_F(Dhcp6ParserTest, optionDataInMultipleSubnets) { const Subnet::OptionContainer& options1 = subnet1->getOptions(); ASSERT_EQ(1, options1.size()); - for (Subnet::OptionContainer::iterator it = options1.begin(); - it != options1.end(); ++it) { - std::cout << it->option->getType() << std::endl; - } - // Get the search index. Index #1 is to search using option code. const Subnet::OptionContainerTypeIndex& idx1 = options1.get<1>();