From ed28c1ba666b39581adb860bf51cdde43c84cc89 Mon Sep 17 00:00:00 2001 From: Adam Date: Mon, 26 Mar 2012 04:59:13 -0400 Subject: Fixed out of bounds memory access from malformed DNS queries that have an invalid length label. Introduced in a6a07de0daa353bcd29056a4535a9c4784c113c8. --- src/dns.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/dns.cpp') diff --git a/src/dns.cpp b/src/dns.cpp index 2e1c751c4..be74e6aa3 100644 --- a/src/dns.cpp +++ b/src/dns.cpp @@ -760,7 +760,7 @@ DNSInfo DNSRequest::ResultIsReady(DNSHeader &header, unsigned length) else i += header.payload[i] + 1; /* skip length and label */ } } - if (length - i < 10) + if (static_cast(length - i) < 10) return std::make_pair((unsigned char*)NULL,"Incorrectly sized DNS reply"); /* XXX: We actually initialise 'rr' here including its ttl field */ -- cgit v1.2.3 From 58c893e834ff20495d007709220881a3ff13f423 Mon Sep 17 00:00:00 2001 From: Adam Date: Tue, 27 Mar 2012 21:39:50 -0400 Subject: Fixed infinite loop cauesd by invalid dns packets --- src/dns.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'src/dns.cpp') diff --git a/src/dns.cpp b/src/dns.cpp index be74e6aa3..58cbcca76 100644 --- a/src/dns.cpp +++ b/src/dns.cpp @@ -800,6 +800,8 @@ DNSInfo DNSRequest::ResultIsReady(DNSHeader &header, unsigned length) */ case DNS_QUERY_CNAME: case DNS_QUERY_PTR: + { + unsigned short lowest_pos = length; o = 0; q = 0; while (q == 0 && i < length && o + 256 < 1023) @@ -812,14 +814,18 @@ DNSInfo DNSRequest::ResultIsReady(DNSHeader &header, unsigned length) i = ntohs(ptr); /* check that highest two bits are set. if not, we've been had */ - if (!(i & DN_COMP_BITMASK)) + if ((i & DN_COMP_BITMASK) != DN_COMP_BITMASK) return std::make_pair((unsigned char *) NULL, "DN label decompression header is bogus"); /* mask away the two highest bits. */ i &= ~DN_COMP_BITMASK; /* and decrease length by 12 bytes. */ - i =- 12; + i -= 12; + + if (i >= lowest_pos) + return std::make_pair((unsigned char *) NULL, "Invalid decompression pointer"); + lowest_pos = i; } else { @@ -843,6 +849,7 @@ DNSInfo DNSRequest::ResultIsReady(DNSHeader &header, unsigned length) } } res[o] = 0; + } break; case DNS_QUERY_AAAA: if (rr.rdlength != sizeof(struct in6_addr)) -- cgit v1.2.3