From d26fa3154031ee9ece21f1d1b47faa5d177e34ef Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Fri, 5 Jul 2019 11:46:25 +0200 Subject: [PATCH] limit compression pointers to 14 bits --- pdns/Makefile.am | 1 + pdns/dnswriter.cc | 6 +++-- pdns/test-dnswriter_cc.cc | 51 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 pdns/test-dnswriter_cc.cc diff --git a/pdns/Makefile.am b/pdns/Makefile.am index 4f71e11908..287899353f 100644 --- a/pdns/Makefile.am +++ b/pdns/Makefile.am @@ -1316,6 +1316,7 @@ testrunner_SOURCES = \ test-dnsparser_cc.cc \ test-dnsparser_hh.cc \ test-dnsrecords_cc.cc \ + test-dnswriter_cc.cc \ test-ipcrypt_cc.cc \ test-iputils_hh.cc \ test-ixfr_cc.cc \ diff --git a/pdns/dnswriter.cc b/pdns/dnswriter.cc index 745e0387a1..24dad7c0b6 100644 --- a/pdns/dnswriter.cc +++ b/pdns/dnswriter.cc @@ -266,7 +266,9 @@ uint16_t DNSPacketWriter::lookupName(const DNSName& name, uint16_t* matchLen) } if(!c) break; - pvect.push_back(iter - d_content.cbegin()); + auto offset = iter - d_content.cbegin(); + if (offset >= 16384) break; // compression pointers cannot point here + pvect.push_back(offset); iter+=*iter+1; } } @@ -325,7 +327,7 @@ void DNSPacketWriter::xfrName(const DNSName& name, bool compress, bool) uint16_t li=0; uint16_t matchlen=0; - if(compress && (li=lookupName(name, &matchlen))) { + if(compress && (li=lookupName(name, &matchlen)) && li < 16384) { const auto& dns=name.getStorage(); if(l_verbose) cout<<"Found a substring of "< +#include + +#include "dnswriter.hh" +#include "dnsparser.hh" + +BOOST_AUTO_TEST_SUITE(test_dnswriter_cc) + +BOOST_AUTO_TEST_CASE(test_compressionBoundary) { + DNSName name("powerdns.com."); + + vector packet; + DNSPacketWriter pwR(packet, name, QType::A, QClass::IN, 0); + pwR.getHeader()->qr = 1; + + /* record we want to see altered */ + pwR.startRecord(name, QType::TXT, 3600, QClass::IN, DNSResourceRecord::ANSWER); + auto txt = string("\"")+string(16262, 'A')+string("\""); + pwR.xfrText(txt); + pwR.commit(); + BOOST_CHECK_EQUAL(pwR.size(), 16368); + + pwR.startRecord(DNSName("mediumsizedlabel.example.net"), QType::A, 3600, QClass::IN, DNSResourceRecord::ANSWER); + pwR.xfrIP('P'<<24 | + 'Q'<<16 | + 'R'<<8 | + 'S'); + pwR.commit(); + BOOST_CHECK_EQUAL(pwR.size(), 16412); // 16412 (0x401c) puts '7example3net' at 0x4001 + + pwR.startRecord(DNSName("adifferentlabel.example.net"), QType::A, 3600, QClass::IN, DNSResourceRecord::ANSWER); + pwR.xfrIP('D'<<24 | + 'E'<<16 | + 'F'<<8 | + 'G'); + pwR.commit(); + BOOST_CHECK_EQUAL(pwR.size(), 16455); + + string spacket(packet.begin(), packet.end()); + + BOOST_CHECK_NO_THROW(MOADNSParser mdp(false, spacket)); +} + +BOOST_AUTO_TEST_SUITE_END() -- 2.39.2