瀏覽代碼

r9701@catbus: nickm | 2007-01-21 13:21:25 -0500
Detect and reject another (harmless) class of DNS replies. Also, fix a couple of IPv6 bugs in evendns.c


svn:r9379

Nick Mathewson 19 年之前
父節點
當前提交
e0ae28d0cd
共有 2 個文件被更改,包括 13 次插入6 次删除
  1. 5 0
      ChangeLog
  2. 8 6
      src/or/eventdns.c

+ 5 - 0
ChangeLog

@@ -41,6 +41,11 @@ Changes in version 0.1.2.7-alpha - 2007-??-??
       handshake to finish. Previously we would let them sit around for
       handshake to finish. Previously we would let them sit around for
       days, if the connecting application didn't close them either.
       days, if the connecting application didn't close them either.
     - Stop using C functions that OpenBSD's linker doesn't like.
     - 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
 Changes in version 0.1.2.6-alpha - 2007-01-09

+ 8 - 6
src/or/eventdns.c

@@ -862,7 +862,8 @@ reply_parse(u8 *packet, int length) {
 			if (req->request_type != TYPE_A) {
 			if (req->request_type != TYPE_A) {
 				j += datalength; continue;
 				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;
 			addrcount = datalength >> 2;
 			addrtocopy = MIN(MAX_ADDRS - reply.data.a.addrcount, (unsigned)addrcount);
 			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) {
 			if (req->request_type != TYPE_AAAA) {
 				j += datalength; continue;
 				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
 			addrcount = datalength >> 4;  // each address is 16 bytes long
 			addrtocopy = MIN(MAX_ADDRS - reply.data.aaaa.addrcount, (unsigned)addrcount);
 			addrtocopy = MIN(MAX_ADDRS - reply.data.aaaa.addrcount, (unsigned)addrcount);
 			ttl_r = MIN(ttl_r, ttl);
 			ttl_r = MIN(ttl_r, ttl);
@@ -901,7 +903,7 @@ reply_parse(u8 *packet, int length) {
 			reply.data.aaaa.addrcount += addrtocopy;
 			reply.data.aaaa.addrcount += addrtocopy;
 			j += 16*addrtocopy;
 			j += 16*addrtocopy;
 			reply.have_answer = 1;
 			reply.have_answer = 1;
-			if (reply.data.a.addrcount == MAX_ADDRS) break;
+			if (reply.data.aaaa.addrcount == MAX_ADDRS) break;
 		} else {
 		} else {
 			// skip over any other type of resource
 			// skip over any other type of resource
 			j += datalength;
 			j += datalength;
@@ -2238,12 +2240,12 @@ int evdns_resolve_reverse_ipv6(struct in6_addr *in, int flags, evdns_callback_ty
 	int i;
 	int i;
 	assert(in);
 	assert(in);
 	cp = buf;
 	cp = buf;
-	for (i=0; i < 16; ++i) {
+	for (i=15; i >= 0; --i) {
 		u8 byte = in->s6_addr[i];
 		u8 byte = in->s6_addr[i];
-		*cp++ = "0123456789abcdef"[byte >> 4];
-		*cp++ = '.';
 		*cp++ = "0123456789abcdef"[byte & 0x0f];
 		*cp++ = "0123456789abcdef"[byte & 0x0f];
 		*cp++ = '.';
 		*cp++ = '.';
+		*cp++ = "0123456789abcdef"[byte >> 4];
+		*cp++ = '.';
 	}
 	}
 	assert(cp + strlen(".ip6.arpa") < buf+sizeof(buf));
 	assert(cp + strlen(".ip6.arpa") < buf+sizeof(buf));
 	memcpy(cp, ".ip6.arpa", strlen(".ip6.arpa")+1);
 	memcpy(cp, ".ip6.arpa", strlen(".ip6.arpa")+1);