diff options
author | William Pitcock <nenolod@dereferenced.org> | 2012-03-20 18:38:13 -0500 |
---|---|---|
committer | William Pitcock <nenolod@dereferenced.org> | 2012-03-20 18:38:13 -0500 |
commit | 84ab0478f9dd7f7f8dc92aa1edaf6b71fe28035b (patch) | |
tree | 75f4f156ffecc9d2c9bddc967db53794be2f638d | |
parent | 9aa28f3730fb3dd69c1e06f78bb2bbc43d36c684 (diff) |
dns: more hardening
- don't trust rr.rdlength
- don't accept replies we know are impossible for AAAA/A records
- don't try to process record types we do not know about specifically
(this behaviour just leads to disaster)
-rw-r--r-- | src/dns.cpp | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/src/dns.cpp b/src/dns.cpp index 2bfa0be20..21b0d9e39 100644 --- a/src/dns.cpp +++ b/src/dns.cpp @@ -845,16 +845,21 @@ DNSInfo DNSRequest::ResultIsReady(DNSHeader &header, int length) res[o] = 0; break; case DNS_QUERY_AAAA: + if (rr.rdlength != sizeof(struct in6_addr)) + return std::make_pair((unsigned char *) NULL, "rr.rdlength is larger than 16 bytes for an ipv6 entry -- malformed/hostile packet?"); + memcpy(res,&header.payload[i],rr.rdlength); res[rr.rdlength] = 0; break; case DNS_QUERY_A: + if (rr.rdlength != sizeof(struct in_addr)) + return std::make_pair((unsigned char *) NULL, "rr.rdlength is larger than 4 bytes for an ipv4 entry -- malformed/hostile packet?"); + memcpy(res,&header.payload[i],rr.rdlength); res[rr.rdlength] = 0; break; default: - memcpy(res,&header.payload[i],rr.rdlength); - res[rr.rdlength] = 0; + return std::make_pair((unsigned char *) NULL, "don't know how to handle undefined type (" + ConvToStr(rr.type) + ") -- rejecting"); break; } return std::make_pair(res,"No error"); |