With AXFR data, it's possible for packet-dns to go into a loop if the
TCP stream isn't desegmented or if a frame was dropped. This patch adds
some checks and throws an exception if the data doesn't make sense.
Graeme Hewson
--- packet-dns.c.orig Sun May 5 01:16:32 2002
+++ packet-dns.c Sat May 11 11:39:02 2002
@@ -442,6 +442,11 @@
int component_len;
int indir_offset;
+ const int min_len = 1; /* Minimum length of encoded name (for root) */
+ /* If we're about to return a value (probably negative) which is less
+ * than the minimum length, we're looking at bad data and we're liable
+ * to put the dissector into a loop. Instead we throw an exception */
+
maxname--; /* reserve space for the trailing '\0' */
for (;;) {
component_len = tvb_get_guint8(tvb, offset);
@@ -498,12 +503,15 @@
strcpy(name, "<Unknown extended label>");
/* Parsing will propably fail from here on, since the */
/* label length is unknown... */
- return offset - start_offset;
+ len = offset - start_offset;
+ if (len < min_len)
+ THROW(ReportedBoundsError);
+ return len;
}
break;
case 0x80:
- goto error; /* error */
+ THROW(ReportedBoundsError);
case 0xc0:
/* Pointer. */
@@ -523,6 +531,8 @@
looping. */
if (chars_processed >= data_size) {
strcpy(name, "<Name contains a pointer that loops>");
+ if (len < min_len)
+ THROW(ReportedBoundsError);
return len;
}
@@ -531,7 +541,6 @@
}
}
-error:
*np = '\0';
/* If "len" is negative, we haven't seen a pointer, and thus haven't
set the length, so set it. */
@@ -540,6 +549,8 @@
/* Zero-length name means "root server" */
if (*name == '\0')
strcpy(name, "<Root>");
+ if (len < min_len)
+ THROW(ReportedBoundsError);
return len;
}