]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Refuse NSEC records with a bitmap length > 32 8826/head
authorRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 14 Feb 2020 13:40:33 +0000 (14:40 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 14 Feb 2020 13:40:33 +0000 (14:40 +0100)
pdns/nsecrecords.cc
pdns/test-dnsrecords_cc.cc

index dc97e3bf48723d04c7fcbd0c1b54a1d2e33aff9d..3b16bad8738f7bfd30d1b34252d7bc27f97a0227 100644 (file)
@@ -110,15 +110,19 @@ void NSECBitmap::fromPacket(PacketReader& pr)
   }
   
   for(unsigned int n = 0; n+1 < bitmap.size();) {
-    unsigned int window=static_cast<unsigned char>(bitmap[n++]);
-    unsigned int blen=static_cast<unsigned char>(bitmap[n++]);
+    uint8_t window=static_cast<uint8_t>(bitmap[n++]);
+    uint8_t blen=static_cast<uint8_t>(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");
     }
 
index 1b15b8fc871b6f0bf840e85781bf85ff5be321e3..4688c90b4c12b9af3b4ae6df8792ee4c44743087 100644 (file)
@@ -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<uint8_t> 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<const char*>(packet.data()), packet.size());
+  BOOST_CHECK_THROW(MOADNSParser failParser(false, reinterpret_cast<const char*>(invalidPacket.data()), invalidPacket.size()), MOADNSException);
+}
+
 BOOST_AUTO_TEST_CASE(test_nsec3_records_types) {
 
   {