From ff62a4d91b82b3aa0c0543529322bc1578a59220 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Sun, 21 Jan 2007 17:05:10 +0000 Subject: [PATCH] r9692@catbus: nickm | 2007-01-21 12:04:22 -0500 Detect pointer loops in DNS requests and replies; avoid infinite loop on such malformed replies. Fixes bug 380. svn:r9378 --- ChangeLog | 2 ++ src/or/eventdns.c | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index bc3e900a77..f2e36f33ed 100644 --- a/ChangeLog +++ b/ChangeLog @@ -27,6 +27,8 @@ Changes in version 0.1.2.7-alpha - 2007-??-?? - If our system clock jumps back in time, don't publish a negative uptime in the descriptor. Also, don't let the global rate limiting buckets go absurdly negative. + - Detect and reject malformed DNS responses containing circular + pointer loops. o Minor bugfixes: - When computing clock skew from directory HTTP headers, consider what diff --git a/src/or/eventdns.c b/src/or/eventdns.c index 35efbff00a..e123592e01 100644 --- a/src/or/eventdns.c +++ b/src/or/eventdns.c @@ -736,6 +736,7 @@ static inline int name_parse(u8 *packet, int length, int *idx, char *name_out, int name_out_len) { int name_end = -1; int j = *idx; + int ptr_count = 0; #define GET32(x) do { if (j + 4 > length) goto err; memcpy(&_t32, packet + j, 4); j += 4; x = ntohl(_t32); } while(0); #define GET16(x) do { if (j + 2 > length) goto err; memcpy(&_t, packet + j, 2); j += 2; x = ntohs(_t); } while(0); #define GET8(x) do { if (j >= length) goto err; x = packet[j++]; } while(0); @@ -759,7 +760,11 @@ name_parse(u8 *packet, int length, int *idx, char *name_out, int name_out_len) { GET8(ptr_low); if (name_end < 0) name_end = j; j = (((int)label_len & 0x3f) << 8) + ptr_low; + /* Make sure that the target offset is in-bounds. */ if (j < 0 || j >= length) return -1; + /* If we've jumped more times than there are characters in the + * message, we must have a loop. */ + if (++ptr_count > length) return -1; continue; } if (label_len > 63) return -1;