From b4d358e79b23a6eb13680b13348e554da820fd89 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 7 Dec 2018 11:13:17 +0100 Subject: [PATCH] Ensure a valid range to string::assign() in PacketReader::xfrBlob() In some cases we could have called: std::string::assign(InputIterator first, InputIterator last) with last < first, which is UB: if the range specified by [first,last) is not valid, it causes undefined behavior libstdc++ handles that gracefully by throwing an out-of-range exception but libc++ tries to allocate a negative value of bytes, which in turns triggers a request for a very large memory allocation, which fails. --- pdns/dnsparser.cc | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/pdns/dnsparser.cc b/pdns/dnsparser.cc index 61fe23e929..1878fc6b90 100644 --- a/pdns/dnsparser.cc +++ b/pdns/dnsparser.cc @@ -496,10 +496,15 @@ string PacketReader::getUnquotedText(bool lenField) void PacketReader::xfrBlob(string& blob) try { - if(d_recordlen && !(d_pos == (d_startrecordpos + d_recordlen))) + if(d_recordlen && !(d_pos == (d_startrecordpos + d_recordlen))) { + if (d_pos > (d_startrecordpos + d_recordlen)) { + throw std::out_of_range("xfrBlob out of record range"); + } blob.assign(&d_content.at(d_pos), &d_content.at(d_startrecordpos + d_recordlen - 1 ) + 1); - else + } + else { blob.clear(); + } d_pos = d_startrecordpos + d_recordlen; } @@ -515,12 +520,17 @@ void PacketReader::xfrBlobNoSpaces(string& blob, int length) { void PacketReader::xfrBlob(string& blob, int length) { if(length) { + if (length < 0) { + throw std::out_of_range("xfrBlob out of range (negative length)"); + } + blob.assign(&d_content.at(d_pos), &d_content.at(d_pos + length - 1 ) + 1 ); - + d_pos += length; } - else + else { blob.clear(); + } } -- 2.47.2