summaryrefslogtreecommitdiff
path: root/wiretap/ngsniffer.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2014-09-11 13:29:37 -0700
committerGuy Harris <guy@alum.mit.edu>2014-09-11 20:30:20 +0000
commit47c592938ba9f0caeacc4c2ccadb370e72f293a2 (patch)
tree9964603e3974d2130e467d7cff564a5c7bc25d12 /wiretap/ngsniffer.c
parentab6ad63e25a9f2e4e8b6e7845dd4513db5232811 (diff)
downloadwireshark-47c592938ba9f0caeacc4c2ccadb370e72f293a2.tar.gz
Add some additional checks in SnifferDecompress().
Check the input pointer in the while clause of the loop, so that we handle an empty input buffer. When reading a bit mask, check before fetching the bit mask that we have two bytes of bit mask and the byte after it. Before putting an uncompressed input byte into the output, make sure we wouldn't run past the end of the output buffer. Before copying an earlier string from the output buffer, make sure it doesn't run past the end of the data we've decompressed so far. Bug: 10461 Change-Id: I8bb8d0d291368ae8bf0ac26970ff54d3262a7e6e Reviewed-on: https://code.wireshark.org/review/4083 Reviewed-by: Guy Harris <guy@alum.mit.edu>
Diffstat (limited to 'wiretap/ngsniffer.c')
-rw-r--r--wiretap/ngsniffer.c39
1 files changed, 29 insertions, 10 deletions
diff --git a/wiretap/ngsniffer.c b/wiretap/ngsniffer.c
index 99feaa2f59..888ed250fa 100644
--- a/wiretap/ngsniffer.c
+++ b/wiretap/ngsniffer.c
@@ -2242,7 +2242,8 @@ SnifferDecompress(unsigned char *inbuf, size_t inlen, unsigned char *outbuf,
}
bit_mask = 0; /* don't have any bits yet */
- while (1)
+ /* Process until we've consumed all the input */
+ while (pin < pin_end)
{
/* Shift down the bit mask we use to see whats encoded */
bit_mask = bit_mask >> 1;
@@ -2250,20 +2251,30 @@ SnifferDecompress(unsigned char *inbuf, size_t inlen, unsigned char *outbuf,
/* If there are no bits left, time to get another 16 bits */
if ( 0 == bit_mask )
{
- bit_mask = 0x8000; /* start with the high bit */
- bit_value = pletoh16(pin); /* get the next 16 bits */
- pin += 2; /* skip over what we just grabbed */
- if ( pin >= pin_end )
+ /* make sure there are at least *three* bytes
+ available - the two bytes of the bit value,
+ plus one byte after it */
+ if ( pin + 2 >= pin_end )
{
- *err = WTAP_ERR_UNC_TRUNCATED; /* data was oddly truncated */
+ *err = WTAP_ERR_UNC_TRUNCATED;
return ( -1 );
}
+ bit_mask = 0x8000; /* start with the high bit */
+ bit_value = pletoh16(pin); /* get the next 16 bits */
+ pin += 2; /* skip over what we just grabbed */
}
/* Use the bits in bit_value to see what's encoded and what is raw data */
if ( !(bit_mask & bit_value) )
{
/* bit not set - raw byte we just copy */
+
+ /* If length would put us past end of output, avoid overflow */
+ if ( pout + 1 > pout_end )
+ {
+ *err = WTAP_ERR_UNC_OVERFLOW;
+ return ( -1 );
+ }
*(pout++) = *(pin++);
}
else
@@ -2358,6 +2369,12 @@ SnifferDecompress(unsigned char *inbuf, size_t inlen, unsigned char *outbuf,
*err = WTAP_ERR_UNC_OVERFLOW;
return ( -1 );
}
+ /* Check if offset would cause us to copy on top of ourselves */
+ if ( pout - offset + length > pout )
+ {
+ *err = WTAP_ERR_UNC_BAD_OFFSET;
+ return ( -1 );
+ }
/* Copy the string from previous text to output position,
advance output pointer */
@@ -2387,6 +2404,12 @@ SnifferDecompress(unsigned char *inbuf, size_t inlen, unsigned char *outbuf,
*err = WTAP_ERR_UNC_OVERFLOW;
return ( -1 );
}
+ /* Check if offset would cause us to copy on top of ourselves */
+ if ( pout - offset + length > pout )
+ {
+ *err = WTAP_ERR_UNC_BAD_OFFSET;
+ return ( -1 );
+ }
/* Copy the string from previous text to output position,
advance output pointer */
@@ -2395,10 +2418,6 @@ SnifferDecompress(unsigned char *inbuf, size_t inlen, unsigned char *outbuf,
break;
}
}
-
- /* If we've consumed all the input, we are done */
- if ( pin >= pin_end )
- break;
}
return (int) ( pout - outbuf ); /* return length of expanded text */