From: Remi Gacogne Date: Wed, 7 Nov 2018 17:48:13 +0000 (+0100) Subject: rec: Fix an out-of-bounds read in the packet cache X-Git-Tag: rec-4.1.8^2 X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fpdns.git;a=commitdiff_plain;h=7ae359c7985b595befc7cc480310c0027004834b rec: Fix an out-of-bounds read in the packet cache --- diff --git a/pdns/packetcache.hh b/pdns/packetcache.hh index c3589108f4..7b2f1a8b38 100644 --- a/pdns/packetcache.hh +++ b/pdns/packetcache.hh @@ -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 diff --git a/pdns/test-packetcache_hh.cc b/pdns/test-packetcache_hh.cc index 7705a56847..3ce89b79d8 100644 --- a/pdns/test-packetcache_hh.cc +++ b/pdns/test-packetcache_hh.cc @@ -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 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(&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) */