From: Stefan Bühler Date: Thu, 28 Dec 2017 22:28:32 +0000 (+0100) Subject: fix xfrIP to reject invalid ips (fixes #6101) X-Git-Tag: dnsdist-1.3.0~172^2~1 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=267951e643bf68d119d9034006ad3e3f2875edda;p=pdns fix xfrIP to reject invalid ips (fixes #6101) - require exactly 3 dots - forbid empty octets --- diff --git a/pdns/rcpgenerator.cc b/pdns/rcpgenerator.cc index aea5c4437..0b606424b 100644 --- a/pdns/rcpgenerator.cc +++ b/pdns/rcpgenerator.cc @@ -102,17 +102,22 @@ void RecordTextReader::xfrIP(uint32_t &val) uint32_t octet=0; val=0; char count=0; - + bool last_was_digit = false; + for(;;) { if(d_string.at(d_pos)=='.') { + if (!last_was_digit) + throw RecordTextException(string("unable to parse IP address, dot without previous digit")); + last_was_digit = false; val<<=8; val+=octet; octet=0; count++; if(count > 3) - break; + throw RecordTextException(string("unable to parse IP address, too many dots")); } else if(isdigit(d_string.at(d_pos))) { + last_was_digit = true; octet*=10; octet+=d_string.at(d_pos) - '0'; if(octet > 255) @@ -127,10 +132,12 @@ void RecordTextReader::xfrIP(uint32_t &val) if(d_pos == d_string.length()) break; } - if(count<=3) { - val<<=8; - val+=octet; - } + if (count != 3) + throw RecordTextException(string("unable to parse IP address, not enough dots")); + if (!last_was_digit) + throw RecordTextException(string("unable to parse IP address, trailing dot")); + val<<=8; + val+=octet; val=ntohl(val); } diff --git a/pdns/test-dnsrecords_cc.cc b/pdns/test-dnsrecords_cc.cc index 8efc5284e..b8e3bf8b8 100644 --- a/pdns/test-dnsrecords_cc.cc +++ b/pdns/test-dnsrecords_cc.cc @@ -240,8 +240,11 @@ BOOST_AUTO_TEST_CASE(test_record_types_bad_values) { cases_t cases = boost::assign::list_of (case_t(QType::A, "932.521.256.42", zone, false)) // hollywood IP (case_t(QType::A, "932.521", zone, false)) // truncated hollywood IP - (case_t(QType::A, "10.0", zone, true)) // truncated IP + (case_t(QType::A, "10.0", zone, false)) // truncated IP (case_t(QType::A, "10.0.0.1.", zone, false)) // trailing dot + (case_t(QType::A, "10.0.0.", zone, false)) // trailing dot + (case_t(QType::A, ".0.0.1", zone, false)) // empty octet + (case_t(QType::A, "10..0.1", zone, false)) // empty octet (case_t(QType::A, "\xca\xec\x00", wire, false)) // truncated wire value (case_t(QType::A, "127.0.0.1 evil data", zone, false)) // trailing garbage (case_t(QType::AAAA, "23:00", zone, false)) // time when this test was written