]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Backport of protobuf PSA 2022-02 (CVE-2022-37428) to rec-4.7.x 11877/head
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Wed, 3 Aug 2022 13:30:44 +0000 (15:30 +0200)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Fri, 5 Aug 2022 11:12:56 +0000 (13:12 +0200)
pdns/pdns_recursor.cc
pdns/recursordist/rec-protozero.cc
pdns/recursordist/rec-protozero.hh
pdns/remote_logger.cc

index a369de3483c14229780aea2b1234e8a5dc5e768d..fe09d2c22088cc5b3eea6e55d231decb2cebfa74 100644 (file)
@@ -1315,7 +1315,12 @@ void startDoResolve(void* p)
 #endif /* NOD ENABLED */
 
         if (t_protobufServers) {
-          pbMessage.addRR(*i, luaconfsLocal->protobufExportConfig.exportTypes, udr);
+          // 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);
+          }
         }
       }
       if (needCommit)
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:
index 6502fd71a7ab1303242c3a61cf6474b967a590b0..7a3f9809216bad4c56b5e78ea88118ab23b22d31 100644 (file)
@@ -92,6 +92,10 @@ namespace ProtoZero
       return d_rspbuf;
     }
 
+    [[nodiscard]] size_t size() const
+    {
+      return d_msgbuf.size() + d_rspbuf.size();
+    }
     std::string&& finishAndMoveBuf()
     {
       if (!d_rspbuf.empty()) {
index 96e596888c814991cd8f039160887a36fe8454df..65901a47c606cd90e606da0ce07f5a9d83f624b4 100644 (file)
@@ -132,7 +132,13 @@ bool RemoteLogger::reconnect()
 void RemoteLogger::queueData(const std::string& data)
 {
   if (data.size() > std::numeric_limits<uint16_t>::max()) {
-    throw std::runtime_error("Got a request to write an object of size " + std::to_string(data.size()));
+    const auto msg = "Not sending too large protobuf message";
+#ifdef WE_ARE_RECURSOR
+    g_log<<Logger::Info<<msg<<endl;
+#else
+    warnlog(msg);
+#endif
+    return;
   }
 
   auto runtime = d_runtime.lock();