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

index d002cd15340f68abdbbf83994d008dcc182f3c3c..dd0a06ff5aafafb69c8d713c2c638b811ddd0f73 100644 (file)
@@ -1981,7 +1981,12 @@ static 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 86f3666885853d8fa497cebe6aadba5f00a8619d..a7e296421075c6a5bc9592ed28b912055bf9886c 100644 (file)
@@ -40,6 +40,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));
@@ -55,37 +61,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 20f511168381c27ddeb523668e0639cc5a7e069e..9363d804beb4dda1070342b6ee7b6d8d4b143b66 100644 (file)
@@ -91,6 +91,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 f5d9e47a4e7e1f8737150bc012aa3c0858b66c04..d23b1a491116ab8f843dcd1c38a49985bfbb4f9b 100644 (file)
@@ -135,7 +135,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;
   }
 
   std::lock_guard<std::mutex> lock(d_mutex);