summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Burchell <viroteck@viroteck.net>2012-03-28 23:56:32 -0700
committerRobin Burchell <viroteck@viroteck.net>2012-03-28 23:56:32 -0700
commitcfac6a9562764dd1530ed39767630e26934c4685 (patch)
treed4c59f63c9aa884802a3a2b71bd8f1ddfe5ea8ca
parent7fcda51612c27ecbe7c78a535266d306e285afb0 (diff)
parent58c893e834ff20495d007709220881a3ff13f423 (diff)
Merge pull request #16 from Adam-/insp20
Fixed out of bounds memory access from malformed DNS queries that have a...
-rw-r--r--src/dns.cpp13
1 files changed, 10 insertions, 3 deletions
diff --git a/src/dns.cpp b/src/dns.cpp
index 2e1c751c4..58cbcca76 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<int>(length - i) < 10)
return std::make_pair((unsigned char*)NULL,"Incorrectly sized DNS reply");
/* XXX: We actually initialise 'rr' here including its ttl field */
@@ -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))