diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | src/or/eventdns.c | 14 |
2 files changed, 13 insertions, 6 deletions
@@ -41,6 +41,11 @@ Changes in version 0.1.2.7-alpha - 2007-??-?? handshake to finish. Previously we would let them sit around for days, if the connecting application didn't close them either. - Stop using C functions that OpenBSD's linker doesn't like. + - Detect and reject DNS replies containing IPv4 or IPv6 records with + an incorrect number of bytes. (Previously, we would ignore the extra + bytes.) + - Fix as-yet-unused reverse IPv6 lookup code so it sends nybbles in the + correct order. Changes in version 0.1.2.6-alpha - 2007-01-09 diff --git a/src/or/eventdns.c b/src/or/eventdns.c index e123592e01..9d0f8f0708 100644 --- a/src/or/eventdns.c +++ b/src/or/eventdns.c @@ -862,7 +862,8 @@ reply_parse(u8 *packet, int length) { if (req->request_type != TYPE_A) { j += datalength; continue; } - // XXXX do something sane with malformed A answers. + if ((datalength & 3) != 0) /* not an even number of As. */ + return -1; addrcount = datalength >> 2; addrtocopy = MIN(MAX_ADDRS - reply.data.a.addrcount, (unsigned)addrcount); @@ -889,7 +890,8 @@ reply_parse(u8 *packet, int length) { if (req->request_type != TYPE_AAAA) { j += datalength; continue; } - // XXXX do something sane with malformed AAAA answers. + if ((datalength & 15) != 0) /* not an even number of AAAAs. */ + return -1; addrcount = datalength >> 4; // each address is 16 bytes long addrtocopy = MIN(MAX_ADDRS - reply.data.aaaa.addrcount, (unsigned)addrcount); ttl_r = MIN(ttl_r, ttl); @@ -901,7 +903,7 @@ reply_parse(u8 *packet, int length) { reply.data.aaaa.addrcount += addrtocopy; j += 16*addrtocopy; reply.have_answer = 1; - if (reply.data.a.addrcount == MAX_ADDRS) break; + if (reply.data.aaaa.addrcount == MAX_ADDRS) break; } else { // skip over any other type of resource j += datalength; @@ -2238,12 +2240,12 @@ int evdns_resolve_reverse_ipv6(struct in6_addr *in, int flags, evdns_callback_ty int i; assert(in); cp = buf; - for (i=0; i < 16; ++i) { + for (i=15; i >= 0; --i) { u8 byte = in->s6_addr[i]; - *cp++ = "0123456789abcdef"[byte >> 4]; - *cp++ = '.'; *cp++ = "0123456789abcdef"[byte & 0x0f]; *cp++ = '.'; + *cp++ = "0123456789abcdef"[byte >> 4]; + *cp++ = '.'; } assert(cp + strlen(".ip6.arpa") < buf+sizeof(buf)); memcpy(cp, ".ip6.arpa", strlen(".ip6.arpa")+1); |