summaryrefslogtreecommitdiff
path: root/wiretap/ngsniffer.c
diff options
context:
space:
mode:
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 */