From 11e1d5c7b676c1f51365b54aada0af4f63852ea0 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 11 Aug 2020 14:07:32 +0200 Subject: [PATCH] Raise an exception on invalid first part (!= \#) in unknown records --- pdns/dnsparser.cc | 12 ++++++++---- pdns/test-dnsrecords_cc.cc | 3 +++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/pdns/dnsparser.cc b/pdns/dnsparser.cc index 3a4e193f01..356e4a6cef 100644 --- a/pdns/dnsparser.cc +++ b/pdns/dnsparser.cc @@ -41,12 +41,16 @@ public: vector parts; stringtok(parts, zone); // we need exactly 3 parts, except if the length field is set to 0 then we only need 2 - if (parts.size() != 3 && !(parts.size() == 2 && equals(parts[1], "0"))) { + if (parts.size() != 3 && !(parts.size() == 2 && equals(parts.at(1), "0"))) { throw MOADNSException("Unknown record was stored incorrectly, need 3 fields, got " + std::to_string(parts.size()) + ": " + zone); } - const string& relevant = (parts.size() > 2) ? parts[2] : ""; - unsigned int total = pdns_stou(parts[1]); + if (parts.at(0) != "\\#") { + throw MOADNSException("Unknown record was stored incorrectly, first part should be '\\#', got '" + parts.at(0) + "'"); + } + + const string& relevant = (parts.size() > 2) ? parts.at(2) : ""; + unsigned int total = pdns_stou(parts.at(1)); if (relevant.size() % 2 || (relevant.size() / 2) != total) { throw MOADNSException((boost::format("invalid unknown record length: size not equal to length field (%d != 2 * %d)") % relevant.size() % total).str()); } @@ -56,7 +60,7 @@ public: for (unsigned int n = 0; n < total; ++n) { int c; - if (sscanf(relevant.c_str()+2*n, "%02x", &c) != 1) { + if (sscanf(&relevant.at(2*n), "%02x", &c) != 1) { throw MOADNSException("unable to read data at position " + std::to_string(2 * n) + " from unknown record of size " + std::to_string(relevant.size())); } out.append(1, (char)c); diff --git a/pdns/test-dnsrecords_cc.cc b/pdns/test-dnsrecords_cc.cc index 854de2125e..770102f1fd 100644 --- a/pdns/test-dnsrecords_cc.cc +++ b/pdns/test-dnsrecords_cc.cc @@ -339,6 +339,9 @@ BOOST_AUTO_TEST_CASE(test_unknown_records_in) { auto validEmptyUnknown = DNSRecordContent::mastermake(static_cast(65534), QClass::IN, "\\# 0"); BOOST_CHECK_THROW(auto twoPartsNotZeroUnknown = DNSRecordContent::mastermake(static_cast(65534), QClass::IN, "\\# 1"), MOADNSException); + // the first part has to be "\#" + BOOST_CHECK_THROW(auto invalidFirstPartUnknown = DNSRecordContent::mastermake(static_cast(65534), QClass::IN, "\\$ 0"), MOADNSException); + // RDATA length is not even BOOST_CHECK_THROW(auto unevenUnknown = DNSRecordContent::mastermake(static_cast(65534), QClass::IN, "\\# 1 A"), MOADNSException); -- 2.47.2