diff -ru dnsdist-2.0.2/dnswriter.cc dnsdist-2.0.2-372/dnswriter.cc --- dnsdist-2.0.2/dnswriter.cc 2025-12-01 13:21:08.000000000 +0100 +++ dnsdist-2.0.2-372/dnswriter.cc 2026-03-13 14:16:57.466794250 +0100 @@ -42,7 +42,7 @@ template GenericDNSPacketWriter::GenericDNSPacketWriter(Container& content, const DNSName& qname, uint16_t qtype, uint16_t qclass, uint8_t opcode) : - d_content(content), d_qname(qname) + d_qname(qname), d_content(content) { d_content.clear(); dnsheader dnsheader; @@ -63,9 +63,10 @@ xfr16BitInt(qtype); xfr16BitInt(qclass); - d_truncatemarker=d_content.size(); - d_sor = 0; - d_rollbackmarker = 0; + if (d_content.size() > std::numeric_limits::max()) { + throw std::range_error("Trying to build a packet larger than " + std::to_string(std::numeric_limits::max()) + " bytes"); + } + d_truncatemarker = d_content.size(); } template dnsheader* GenericDNSPacketWriter::getHeader() @@ -78,11 +79,14 @@ { d_compress = compress; commit(); - d_rollbackmarker=d_content.size(); + if (d_content.size() > std::numeric_limits::max()) { + throw std::range_error("Trying to build a packet larger than " + std::to_string(std::numeric_limits::max()) + " bytes"); + } + d_rollbackmarker = d_content.size(); - if(compress && !name.isRoot() && d_qname==name) { // don't do the whole label compression thing if we *know* we can get away with "see question" - except when compressing the root - static unsigned char marker[2]={0xc0, 0x0c}; - d_content.insert(d_content.end(), (const char *) &marker[0], (const char *) &marker[2]); + if (compress && !name.isRoot() && d_qname==name) { // don't do the whole label compression thing if we *know* we can get away with "see question" - except when compressing the root + static const std::array marker{0xc0, 0x0c}; + d_content.insert(d_content.end(), reinterpret_cast(marker.begin()), reinterpret_cast(marker.end())); } else { xfrName(name, compress); @@ -92,7 +96,8 @@ xfr32BitInt(ttl); xfr16BitInt(0); // this will be the record size d_recordplace = place; - d_sor=d_content.size(); // this will remind us where to stuff the record size + + d_sor = d_content.size(); // this will remind us where to stuff the record size } template void GenericDNSPacketWriter::addOpt(const uint16_t udpsize, const uint16_t extRCode, const uint16_t ednsFlags, const optvect_t& options, const uint8_t version) @@ -483,13 +488,23 @@ template void GenericDNSPacketWriter::commit() { - if(!d_sor) + if (d_sor == 0) { return; + } + + if (d_sor < 2 || d_sor > d_content.size()) { + throw std::range_error("Invalid start of record when trying to build a packet: " + std::to_string(d_sor) + " / " + std::to_string(d_content.size())); + } + + if (d_content.size() > std::numeric_limits::max()) { + throw std::range_error("Trying to build a packet larger than " + std::to_string(std::numeric_limits::max()) + " bytes"); + } + uint16_t rlen = d_content.size() - d_sor; - d_content[d_sor-2]=rlen >> 8; - d_content[d_sor-1]=rlen & 0xff; - d_sor=0; - dnsheader* dh=reinterpret_cast( &*d_content.begin()); + d_content.at(d_sor-2) = rlen >> 8; + d_content.at(d_sor-1) = rlen & 0xff; + d_sor = 0; + auto* dh = reinterpret_cast( &*d_content.begin()); switch(d_recordplace) { case DNSResourceRecord::QUESTION: dh->qdcount = htons(ntohs(dh->qdcount) + 1); diff -ru dnsdist-2.0.2/dnswriter.hh dnsdist-2.0.2-372/dnswriter.hh --- dnsdist-2.0.2/dnswriter.hh 2025-12-01 13:21:08.000000000 +0100 +++ dnsdist-2.0.2-372/dnswriter.hh 2026-03-13 14:16:57.466897085 +0100 @@ -163,21 +163,19 @@ private: uint16_t lookupName(const DNSName& name, uint16_t* matchlen); - vector d_namepositions; - // We declare 1 uint_16 in the public section, these 3 align on a 8-byte boundary - uint16_t d_sor; - uint16_t d_rollbackmarker; // start of last complete packet, for rollback - Container& d_content; + std::vector d_namepositions; DNSName d_qname; - - uint16_t d_truncatemarker; // end of header, for truncate + Container& d_content; + size_t d_sor{0}; + uint16_t d_rollbackmarker{0}; // start of last complete packet, for rollback + uint16_t d_truncatemarker{0}; // end of header, for truncate DNSResourceRecord::Place d_recordplace{DNSResourceRecord::QUESTION}; - bool d_canonic{false}, d_lowerCase{false}, d_compress{false}; + bool d_canonic{false}; + bool d_lowerCase{false}; + bool d_compress{false}; }; using DNSPacketWriter = GenericDNSPacketWriter>; -typedef vector > labelparts_t; -// bool labeltokUnescape(labelparts_t& parts, const DNSName& label); std::vector segmentDNSText(const string& text); // from dnslabeltext.rl