From: Remi Gacogne Date: Fri, 14 Feb 2020 13:40:33 +0000 (+0100) Subject: Refuse NSEC records with a bitmap length > 32 X-Git-Tag: auth-4.3.0-beta2~9^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3d51568b456205c9bd60ceeedb4b43af4a33f019;p=thirdparty%2Fpdns.git Refuse NSEC records with a bitmap length > 32 --- diff --git a/pdns/nsecrecords.cc b/pdns/nsecrecords.cc index dc97e3bf48..3b16bad873 100644 --- a/pdns/nsecrecords.cc +++ b/pdns/nsecrecords.cc @@ -110,15 +110,19 @@ void NSECBitmap::fromPacket(PacketReader& pr) } for(unsigned int n = 0; n+1 < bitmap.size();) { - unsigned int window=static_cast(bitmap[n++]); - unsigned int blen=static_cast(bitmap[n++]); + uint8_t window=static_cast(bitmap[n++]); + uint8_t blen=static_cast(bitmap[n++]); // end if zero padding and ensure packet length - if(window == 0 && blen == 0) { + if (window == 0 && blen == 0) { break; } - if(n + blen > bitmap.size()) { + if (blen > 32) { + throw MOADNSException("NSEC record with invalid bitmap length"); + } + + if (n + blen > bitmap.size()) { throw MOADNSException("NSEC record with bitmap length > packet length"); } diff --git a/pdns/test-dnsrecords_cc.cc b/pdns/test-dnsrecords_cc.cc index 1b15b8fc87..4688c90b4c 100644 --- a/pdns/test-dnsrecords_cc.cc +++ b/pdns/test-dnsrecords_cc.cc @@ -488,6 +488,27 @@ BOOST_AUTO_TEST_CASE(test_nsec_records_types) { } } +BOOST_AUTO_TEST_CASE(test_nsec_invalid_bitmap_len) { + auto validNSEC = DNSRecordContent::mastermake(QType::NSEC, QClass::IN, "host.example.com. A MX RRSIG NSEC AAAA NSEC3 TYPE1234 TYPE65535"); + const DNSName powerdnsName("powerdns.com."); + + vector packet; + DNSPacketWriter writer(packet, powerdnsName, QType::NSEC, QClass::IN, 0); + writer.getHeader()->qr = 1; + writer.startRecord(powerdnsName, QType::NSEC, 100, QClass::IN, DNSResourceRecord::ANSWER, false); + validNSEC->toPacket(writer); + writer.commit(); + + size_t nsecDataPos = sizeof(dnsheader) + powerdnsName.wirelength() + sizeof(uint16_t) + sizeof (uint16_t) + powerdnsName.wirelength() + sizeof(uint16_t) + sizeof (uint16_t) + sizeof(uint32_t) + sizeof(uint16_t); + size_t typeBitMapsFieldPos = nsecDataPos + DNSName("host.example.com.").wirelength(); + auto invalidPacket = packet; + /* set the bitmap length value to 33, while the maximum possible value is 32 */ + invalidPacket.at(typeBitMapsFieldPos + 1) = 33; + + MOADNSParser parser(false, reinterpret_cast(packet.data()), packet.size()); + BOOST_CHECK_THROW(MOADNSParser failParser(false, reinterpret_cast(invalidPacket.data()), invalidPacket.size()), MOADNSException); +} + BOOST_AUTO_TEST_CASE(test_nsec3_records_types) { {