]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Check variable length cases to not create protobufs > max / 2 11874/head
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Fri, 5 Aug 2022 08:21:01 +0000 (10:21 +0200)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Tue, 23 Aug 2022 07:15:21 +0000 (09:15 +0200)
pdns/pdns_recursor.cc
pdns/recursordist/rec-protozero.cc

index d1b7178a07a25899e7f1fcd1a2680127be617060..4469695996db39ad1c129a98946352d2e8c6c38e 100644 (file)
@@ -1361,6 +1361,7 @@ void startDoResolve(void* p)
         if (t_protobufServers) {
           // Max size is 64k, but we're conservative here, as other fields are added after the answers have been added
           // If a single answer causes a too big protobuf message, it wil be dropped by queueData()
+          // But note addRR has code to prevent that
           if (pbMessage.size() < std::numeric_limits<uint16_t>::max() / 2) {
             pbMessage.addRR(*i, luaconfsLocal->protobufExportConfig.exportTypes, udr);
           }
index 8a698093d36a96924b071ab5d0866663671797c7..3d544c1be404e1ae384f6bbc6c5492a4b0ff946f 100644 (file)
@@ -41,6 +41,12 @@ void pdns::ProtoZero::RecMessage::addRR(const DNSRecord& record, const std::set<
   pbf_rr.add_uint32(static_cast<protozero::pbf_tag_type>(pdns::ProtoZero::Message::RRField::class_), record.d_class);
   pbf_rr.add_uint32(static_cast<protozero::pbf_tag_type>(pdns::ProtoZero::Message::RRField::ttl), record.d_ttl);
 
+  auto add = [&](const std::string& str) {
+    if (size() + str.length() < std::numeric_limits<uint16_t>::max() / 2) {
+      pbf_rr.add_string(static_cast<protozero::pbf_tag_type>(pdns::ProtoZero::Message::RRField::rdata), str);
+    }
+  };
+
   switch (record.d_type) {
   case QType::A: {
     const auto& content = dynamic_cast<const ARecordContent&>(*(record.d_content));
@@ -56,37 +62,37 @@ void pdns::ProtoZero::RecMessage::addRR(const DNSRecord& record, const std::set<
   }
   case QType::CNAME: {
     const auto& content = dynamic_cast<const CNAMERecordContent&>(*(record.d_content));
-    pbf_rr.add_string(static_cast<protozero::pbf_tag_type>(pdns::ProtoZero::Message::RRField::rdata), content.getTarget().toString());
+    add(content.getTarget().toString());
     break;
   }
   case QType::TXT: {
     const auto& content = dynamic_cast<const TXTRecordContent&>(*(record.d_content));
-    pbf_rr.add_string(static_cast<protozero::pbf_tag_type>(pdns::ProtoZero::Message::RRField::rdata), content.d_text);
+    add(content.d_text);
     break;
   }
   case QType::NS: {
     const auto& content = dynamic_cast<const NSRecordContent&>(*(record.d_content));
-    pbf_rr.add_string(static_cast<protozero::pbf_tag_type>(pdns::ProtoZero::Message::RRField::rdata), content.getNS().toString());
+    add(content.getNS().toString());
     break;
   }
   case QType::PTR: {
     const auto& content = dynamic_cast<const PTRRecordContent&>(*(record.d_content));
-    pbf_rr.add_string(static_cast<protozero::pbf_tag_type>(pdns::ProtoZero::Message::RRField::rdata), content.getContent().toString());
+    add(content.getContent().toString());
     break;
   }
   case QType::MX: {
     const auto& content = dynamic_cast<const MXRecordContent&>(*(record.d_content));
-    pbf_rr.add_string(static_cast<protozero::pbf_tag_type>(pdns::ProtoZero::Message::RRField::rdata), content.d_mxname.toString());
+    add(content.d_mxname.toString());
     break;
   }
   case QType::SPF: {
     const auto& content = dynamic_cast<const SPFRecordContent&>(*(record.d_content));
-    pbf_rr.add_string(static_cast<protozero::pbf_tag_type>(pdns::ProtoZero::Message::RRField::rdata), content.getText());
+    add(content.getText());
     break;
   }
   case QType::SRV: {
     const auto& content = dynamic_cast<const SRVRecordContent&>(*(record.d_content));
-    pbf_rr.add_string(static_cast<protozero::pbf_tag_type>(pdns::ProtoZero::Message::RRField::rdata), content.d_target.toString());
+    add(content.d_target.toString());
     break;
   }
   default: