Parcourir la source

Added code to NSEC and NSEC3 from-wire constructors to throw exceptions
if the type bitmaps are invalid. Also added unit tests.


git-svn-id: svn://bind10.isc.org/svn/bind10/trunk@1331 e5f2f494-b856-4b98-b285-d166d9295462

Evan Hunt il y a 15 ans
Parent
commit
1e996decd3

+ 11 - 0
src/lib/dns/rdata.h

@@ -55,6 +55,17 @@ public:
 };
 
 ///
+/// \brief A standard DNS module exception that is thrown if wire format
+/// RDTA is invalid
+///
+class InvalidRdata : public Exception {
+public:
+    InvalidRdata(const char* file, size_t line, const char* what) :
+        isc::Exception(file, line, what) {}
+};
+
+
+///
 /// \brief A standard DNS module exception that is thrown if RDATA parser
 /// parser encounters a character-string (as defined in RFC1035) exceeding
 /// the maximum allowable length (\c MAX_CHARSTRING_LEN).

+ 12 - 2
src/lib/dns/rdata/generic/nsec3_50.cc

@@ -164,11 +164,21 @@ NSEC3::NSEC3(InputBuffer& buffer, size_t rdata_len)
         isc_throw(InvalidRdataLength, "NSEC3 type bitmap too short");
     }
 
-    // FIXIT: we cannot naively copy the data because the bitmaps have
-    // semantics and other part of this class assumes they are valid.
     vector<uint8_t> typebits(rdata_len);
     buffer.readData(&typebits[0], rdata_len);
 
+    int len = 0;
+    for (int i = 0; i < typebits.size(); i += len) {
+        if (i + 2 > typebits.size()) {
+            isc_throw(InvalidRdata, "Bad NSEC3 typebits");
+        }
+        len = typebits[i + 1];
+        if (len > 31) {
+            isc_throw(InvalidRdata, "Bad NSEC3 typebits");
+        }
+        i += 2;
+    }
+
     impl_ = new NSEC3Impl(hashalg, flags, iterations, salt, next, typebits);
 }
 

+ 12 - 2
src/lib/dns/rdata/generic/nsec_47.cc

@@ -104,11 +104,21 @@ NSEC::NSEC(InputBuffer& buffer, size_t rdata_len)
     }
     rdata_len -= (buffer.getPosition() - pos);
 
-    // FIXIT: we cannot naively copy the data because the bitmaps have
-    // semantics and other part of this class assumes they are valid.
     vector<uint8_t> typebits(rdata_len);
     buffer.readData(&typebits[0], rdata_len);
 
+    int len = 0;
+    for (int i = 0; i < typebits.size(); i += len) {
+        if (i + 2 > typebits.size()) {
+            isc_throw(InvalidRdata, "Bad NSEC typebits");
+        }
+        len = typebits[i + 1];
+        if (len > 31) {
+            isc_throw(InvalidRdata, "Bad NSEC typebits");
+        }
+        i += 2;
+    }
+
     impl_ = new NSECImpl(nextname, typebits);
 }
 

+ 5 - 0
src/lib/dns/tests/rdata_nsec3_unittest.cc

@@ -84,6 +84,11 @@ TEST_F(Rdata_NSEC3_Test, createFromWire)
     EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC3(), RRClass::IN(),
                                       "testdata/rdata_nsec3_fromWire2"),
                  InvalidRdataLength);
+
+    // Invalid type bits
+    EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC3(), RRClass::IN(),
+                                      "testdata/rdata_nsec3_fromWire3"),
+                 InvalidRdata);
 }
 
 TEST_F(Rdata_NSEC3_Test, toWireRenderer)

+ 3 - 3
src/lib/dns/tests/rdata_nsec_unittest.cc

@@ -66,9 +66,9 @@ TEST_F(Rdata_NSEC_Test, createFromWire_NSEC)
                                       "testdata/rdata_nsec_fromWire2"),
                  InvalidRdataLength);
 
-    // This should be rejected
-    //rdataFactoryFromFile(RRType::NSEC(), RRClass::IN(),
-    //                   "testdata/rdata_nsec_fromWire3")->toText();
+    EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC(), RRClass::IN(),
+                       "testdata/rdata_nsec_fromWire3"),
+                 InvalidRdata);
 }
 
 TEST_F(Rdata_NSEC_Test, toWireRenderer_NSEC)

+ 6 - 0
src/lib/dns/tests/testdata/rdata_nsec3_fromWire3

@@ -0,0 +1,6 @@
+# RDLENGTH, 39 bytes
+00 27
+# NSEC3 record with a broken type bitmap
+01 01 00 01 04 d3 99 ea ab 14 8a 77 c7 ac ef cb
+c5 54 46 03 2b 2d 96 1c c5 eb 68 21 ef 26 00 ff
+22 00 00 00 00 02 90