diff options
author | Guy Harris <guy@alum.mit.edu> | 2002-05-11 18:46:38 +0000 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2002-05-11 18:46:38 +0000 |
commit | 60e2475556ea7bbf465e8e1402fd8baf53941160 (patch) | |
tree | 69f00c089baf3cfa4561fe60806a6669e695a502 /packet-dns.c | |
parent | 00e94b5ca09e5c66bbe4073275b0f67f86903058 (diff) | |
download | wireshark-60e2475556ea7bbf465e8e1402fd8baf53941160.tar.gz wireshark-60e2475556ea7bbf465e8e1402fd8baf53941160.tar.bz2 wireshark-60e2475556ea7bbf465e8e1402fd8baf53941160.zip |
From Graeme Hewson: add some sanity checks to DNS dissector to avoid
loops.
svn path=/trunk/; revision=5443
Diffstat (limited to 'packet-dns.c')
-rw-r--r-- | packet-dns.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/packet-dns.c b/packet-dns.c index 0ef668a35b..945b18a3ef 100644 --- a/packet-dns.c +++ b/packet-dns.c @@ -1,7 +1,7 @@ /* packet-dns.c * Routines for DNS packet disassembly * - * $Id: packet-dns.c,v 1.85 2002/05/05 00:16:32 guy Exp $ + * $Id: packet-dns.c,v 1.86 2002/05/11 18:46:38 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@ethereal.com> @@ -442,6 +442,11 @@ get_dns_name(tvbuff_t *tvb, int offset, int dns_data_offset, 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 @@ get_dns_name(tvbuff_t *tvb, int offset, int dns_data_offset, 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 @@ get_dns_name(tvbuff_t *tvb, int offset, int dns_data_offset, 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 @@ get_dns_name(tvbuff_t *tvb, int offset, int dns_data_offset, } } -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 @@ error: /* Zero-length name means "root server" */ if (*name == '\0') strcpy(name, "<Root>"); + if (len < min_len) + THROW(ReportedBoundsError); return len; } |