]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
rec: Fix an out-of-bounds read in the packet cache 7221/head
authorRemi Gacogne <remi.gacogne@powerdns.com>
Wed, 7 Nov 2018 17:48:13 +0000 (18:48 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Wed, 7 Nov 2018 17:48:13 +0000 (18:48 +0100)
pdns/packetcache.hh
pdns/test-packetcache_hh.cc

index c3589108f43c9bbfa318136862f45d7643b954bf..7b2f1a8b38b6551b08a6179944450704d6ff4ed8 100644 (file)
@@ -38,7 +38,7 @@ public:
     const char* end = packet.c_str() + packetSize;
     const char* p = packet.c_str() + pos;
 
-    for(; p < end && *p; ++p) { // XXX if you embed a 0 in your qname we'll stop lowercasing there
+    for(; p < end && *p; ++p, ++pos) { // XXX if you embed a 0 in your qname we'll stop lowercasing there
       const unsigned char l = dns_tolower(*p); // label lengths can safely be lower cased
       ret=burtle(&l, 1, ret);
     }                           // XXX the embedded 0 in the qname will break the subnet stripping
index 7705a5684782081778e8343c88006de5c2deee9e..3ce89b79d854261a4340e658eefc9365a25f695d 100644 (file)
@@ -166,6 +166,38 @@ BOOST_AUTO_TEST_CASE(test_PacketCacheAuthCollision) {
   }
 }
 
+BOOST_AUTO_TEST_CASE(test_PacketCacheRecSimple) {
+
+  const DNSName qname("www.powerdns.com.");
+  uint16_t qtype = QType::AAAA;
+  EDNSSubnetOpts opt;
+  DNSPacketWriter::optvect_t ednsOptions;
+  uint16_t ecsBegin;
+  uint16_t ecsEnd;
+
+  {
+    vector<uint8_t> packet;
+    DNSPacketWriter pw1(packet, qname, qtype);
+    pw1.getHeader()->rd = true;
+    pw1.getHeader()->qr = false;
+    pw1.getHeader()->id = 0x42;
+    pw1.addOpt(512, 0, 0);
+    pw1.commit();
+
+    string spacket1((const char*)&packet[0], packet.size());
+    /* set the RD length to a large value */
+    unsigned char* ptr = reinterpret_cast<unsigned char*>(&spacket1.at(sizeof(dnsheader) + qname.wirelength() + /* qtype and qclass */ 4 + /* OPT root label (1), type (2), class (2) and ttl (4) */ 9));
+    *ptr = 255;
+    *(ptr + 1) = 255;
+    /* truncate the end of the OPT header to try to trigger an out of bounds read */
+    spacket1.resize(spacket1.size() - 6);
+    PacketCache::canHashPacket(spacket1, &ecsBegin, &ecsEnd);
+    /* no ECS */
+    BOOST_CHECK_EQUAL(ecsBegin, 0);
+    BOOST_CHECK_EQUAL(ecsEnd, 0);
+  }
+}
+
 BOOST_AUTO_TEST_CASE(test_PacketCacheRecCollision) {
 
   /* rec version (ECS is processed, we hash the whole query except for the ID and the ECS value, while lowercasing the qname) */