]> granicus.if.org Git - pdns/commitdiff
fix xfrIP to reject invalid ips (fixes #6101)
authorStefan Bühler <stbuehler@web.de>
Thu, 28 Dec 2017 22:28:32 +0000 (23:28 +0100)
committerStefan Bühler <stbuehler@web.de>
Thu, 28 Dec 2017 22:29:51 +0000 (23:29 +0100)
- require exactly 3 dots
- forbid empty octets

pdns/rcpgenerator.cc
pdns/test-dnsrecords_cc.cc

index aea5c4437816553455cf18368ae7b2265c005d7d..0b606424b3a44b6dae146c6dec744cca71a5e6e6 100644 (file)
@@ -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);
 }
 
index 8efc5284e8ead44bb502760aa1a366953326a27c..b8e3bf8b8692e3d4df3cefc35e552546f25a3e02 100644 (file)
@@ -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