From: Otto Moerbeek Date: Wed, 3 Aug 2022 13:32:43 +0000 (+0200) Subject: Backport of protobuf PSA 2022-02 (CVE-2022-37428) to rec-4.6.x X-Git-Tag: rec-4.6.3^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F11876%2Fhead;p=thirdparty%2Fpdns.git Backport of protobuf PSA 2022-02 (CVE-2022-37428) to rec-4.6.x --- diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index ea455bb482..f4434fcb5b 100644 --- a/pdns/pdns_recursor.cc +++ b/pdns/pdns_recursor.cc @@ -2146,7 +2146,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::max() / 2) { + pbMessage.addRR(*i, luaconfsLocal->protobufExportConfig.exportTypes, udr); + } } } if(needCommit) diff --git a/pdns/recursordist/rec-protozero.cc b/pdns/recursordist/rec-protozero.cc index 8a698093d3..3d544c1be4 100644 --- a/pdns/recursordist/rec-protozero.cc +++ b/pdns/recursordist/rec-protozero.cc @@ -41,6 +41,12 @@ void pdns::ProtoZero::RecMessage::addRR(const DNSRecord& record, const std::set< pbf_rr.add_uint32(static_cast(pdns::ProtoZero::Message::RRField::class_), record.d_class); pbf_rr.add_uint32(static_cast(pdns::ProtoZero::Message::RRField::ttl), record.d_ttl); + auto add = [&](const std::string& str) { + if (size() + str.length() < std::numeric_limits::max() / 2) { + pbf_rr.add_string(static_cast(pdns::ProtoZero::Message::RRField::rdata), str); + } + }; + switch (record.d_type) { case QType::A: { const auto& content = dynamic_cast(*(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(*(record.d_content)); - pbf_rr.add_string(static_cast(pdns::ProtoZero::Message::RRField::rdata), content.getTarget().toString()); + add(content.getTarget().toString()); break; } case QType::TXT: { const auto& content = dynamic_cast(*(record.d_content)); - pbf_rr.add_string(static_cast(pdns::ProtoZero::Message::RRField::rdata), content.d_text); + add(content.d_text); break; } case QType::NS: { const auto& content = dynamic_cast(*(record.d_content)); - pbf_rr.add_string(static_cast(pdns::ProtoZero::Message::RRField::rdata), content.getNS().toString()); + add(content.getNS().toString()); break; } case QType::PTR: { const auto& content = dynamic_cast(*(record.d_content)); - pbf_rr.add_string(static_cast(pdns::ProtoZero::Message::RRField::rdata), content.getContent().toString()); + add(content.getContent().toString()); break; } case QType::MX: { const auto& content = dynamic_cast(*(record.d_content)); - pbf_rr.add_string(static_cast(pdns::ProtoZero::Message::RRField::rdata), content.d_mxname.toString()); + add(content.d_mxname.toString()); break; } case QType::SPF: { const auto& content = dynamic_cast(*(record.d_content)); - pbf_rr.add_string(static_cast(pdns::ProtoZero::Message::RRField::rdata), content.getText()); + add(content.getText()); break; } case QType::SRV: { const auto& content = dynamic_cast(*(record.d_content)); - pbf_rr.add_string(static_cast(pdns::ProtoZero::Message::RRField::rdata), content.d_target.toString()); + add(content.d_target.toString()); break; } default: diff --git a/pdns/recursordist/rec-protozero.hh b/pdns/recursordist/rec-protozero.hh index 6502fd71a7..7a3f980921 100644 --- a/pdns/recursordist/rec-protozero.hh +++ b/pdns/recursordist/rec-protozero.hh @@ -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()) { diff --git a/pdns/remote_logger.cc b/pdns/remote_logger.cc index 6e41db647f..312975c3f6 100644 --- a/pdns/remote_logger.cc +++ b/pdns/remote_logger.cc @@ -135,7 +135,13 @@ bool RemoteLogger::reconnect() void RemoteLogger::queueData(const std::string& data) { if (data.size() > std::numeric_limits::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<