From: Otto Moerbeek Date: Fri, 5 Aug 2022 08:21:01 +0000 (+0200) Subject: Check variable length cases to not create protobufs > max / 2 X-Git-Tag: rec-4.8.0-alpha1~49^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fpull%2F11874%2Fhead;p=thirdparty%2Fpdns.git Check variable length cases to not create protobufs > max / 2 --- diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index d1b7178a07..4469695996 100644 --- a/pdns/pdns_recursor.cc +++ b/pdns/pdns_recursor.cc @@ -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::max() / 2) { pbMessage.addRR(*i, luaconfsLocal->protobufExportConfig.exportTypes, udr); } 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: