Fix end computation in DNSName::packetParser
authorRemi Gacogne <remi.gacogne@powerdns.com>
Wed, 2 Mar 2016 15:57:02 +0000 (16:57 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Wed, 2 Mar 2016 15:57:02 +0000 (16:57 +0100)
end was computed by

end = qpos + offset + len

but the offset is already included in len, as seen in the way
label compression is handled, by calling packetParser with the
same original position and len but an updated offset.

pdns/dnsname.cc
pdns/test-dnsname_cc.cc

index 2b1d269c6f3437c7bd2a7f225f4d8d9a43d384dc..fece6db044eca1ecdcf1320ce94763ca1499d64b 100644 (file)
@@ -81,8 +81,8 @@ void DNSName::packetParser(const char* qpos, int len, int offset, bool uncompres
   if (offset >= len)
     throw std::range_error("Trying to read past the end of the buffer ("+std::to_string(offset)+ " >= "+std::to_string(len)+")");
 
-  pos += offset;
   const unsigned char* end = pos + len;
+  pos += offset;
   while((labellen=*pos++) && pos < end) { // "scan and copy"
     if(labellen & 0xc0) {
       if(!uncompress)
index dc8a6388d563925161854ca596569ea1423b6265..b2e247a2aa2733adf55477b86eed35da21b6bba3 100644 (file)
@@ -256,6 +256,15 @@ BOOST_AUTO_TEST_CASE(test_PacketParse) {
   DNSPacketWriter dpw1(packet, DNSName("."), QType::AAAA);
   DNSName p((char*)&packet[0], packet.size(), 12, false);
   BOOST_CHECK_EQUAL(p, root);
+  unsigned char* buffer=&packet[0];
+  /* set invalid label len:
+     - packet.size() == 17 (sizeof(dnsheader) + 1 + 2 + 2)
+     - label len < packet.size() but
+     - offset is 12, label len of 15 should be rejected
+     because offset + 15 >= packet.size()
+  */
+  buffer[sizeof(dnsheader)] = 15;
+  BOOST_CHECK_THROW(DNSName((char*)&packet[0], packet.size(), 12, false), std::range_error);
 }