Parcourir la source

[2095] reject too big RRSIG

JINMEI Tatuya il y a 13 ans
Parent
commit
673b0098bb

+ 4 - 1
src/lib/datasrc/memory/rdata_encoder.cc

@@ -445,7 +445,10 @@ RdataEncoder::addSIGRdata(const rdata::Rdata& sig_rdata) {
     const size_t cur_pos = impl_->rrsig_buffer_.getLength();
     sig_rdata.toWire(impl_->rrsig_buffer_);
     const size_t rrsig_datalen = impl_->rrsig_buffer_.getLength() - cur_pos;
-    // TBD: too large data
+    if (rrsig_datalen > 0xffff) {
+        isc_throw(RdataEncodingError, "RRSIG is too large: "
+                  << rrsig_datalen << " bytes");
+    }
     impl_->rrsig_lengths_.push_back(rrsig_datalen);
 }
 

+ 11 - 4
src/lib/datasrc/memory/rdata_encoder.h

@@ -60,15 +60,14 @@ enum RdataNameAttributes {
 /// uint16_t n1_2: size of 2nd variable len field of 1st RDATA
 /// ...
 /// uint16_t nN_M: size of last (Mth) variable len field of last (Nth) RDATA
+/// uint16_t ns1: size of 1st RRSIG data
+/// ...
+/// uint16_t nsL: size of last (Lth) RRSIG data
 /// A sequence of packed data fields follow:
 /// uint8_t[]: data field value, length specified by nI_J (in case it's
 ///            variable) or by the field spec (in case it's fixed-length).
 /// or
 /// opaque data, LabelSequence::getSerializedLength() bytes: data for a name
-/// (a possible 1-byte padding)
-/// uint16_t ns1: size of 1st RRSIG data
-/// ...
-/// uint16_t nsL: size of last (Lth) RRSIG data
 /// uint8_t[ns1]: 1st RRSIG data
 /// ...
 /// uint8_t[nsL]: last RRSIG data
@@ -99,6 +98,14 @@ public:
     /// \throw std::bad_alloc Internal memory allocation failure.
     void addRdata(const dns::rdata::Rdata& rdata);
 
+    /// \brief TBD
+    ///
+    /// Like addRdata(), this implementation does not support RRSIG RDATA
+    /// whose size (in the form of wire format) exceeds 65535 bytes.
+    ///
+    /// \throw InvalidOperation called before start().
+    /// \throw RdataEncodingError A very unusual case, such as over 64KB RDATA.
+    /// \throw std::bad_alloc Internal memory allocation failure.
     void addSIGRdata(const dns::rdata::Rdata& sig_rdata);
 
     /// \brief TBD

+ 13 - 1
src/lib/datasrc/memory/tests/rdata_encoder_unittest.cc

@@ -417,8 +417,20 @@ TEST_F(RdataEncoderTest, addSIGRdata) {
 }
 
 TEST_F(RdataEncoderTest, badAddSIGRdata) {
+    // try adding SIG before start
     EXPECT_THROW(encoder_.addSIGRdata(*rrsig_rdata_), isc::InvalidOperation);
 
-    // TBD: reject very large RRSIG
+    // Very big RRSIG.  This implementation rejects it.
+    isc::util::OutputBuffer ob(0);
+    rrsig_rdata_->toWire(ob);
+    // append dummy trailing signature to make it too big
+    vector<uint8_t> dummy_sig(65536 - ob.getLength());
+    ob.writeData(&dummy_sig[0], dummy_sig.size());
+    ASSERT_EQ(65536, ob.getLength());
+
+    isc::util::InputBuffer ib(ob.getData(), ob.getLength());
+    generic::RRSIG big_sigrdata(ib, ob.getLength());
+    encoder_.start(RRClass::IN(), RRType::A());
+    EXPECT_THROW(encoder_.addSIGRdata(big_sigrdata), RdataEncodingError);
 }
 }