summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorWilliam Pitcock <nenolod@dereferenced.org>2012-03-20 18:38:13 -0500
committerWilliam Pitcock <nenolod@dereferenced.org>2012-03-20 18:38:13 -0500
commit84ab0478f9dd7f7f8dc92aa1edaf6b71fe28035b (patch)
tree75f4f156ffecc9d2c9bddc967db53794be2f638d /src
parent9aa28f3730fb3dd69c1e06f78bb2bbc43d36c684 (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)
Diffstat (limited to 'src')
-rw-r--r--src/dns.cpp9
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");