mirror of
git://git.gnupg.org/gnupg.git
synced 2024-11-04 20:38:50 +01:00
gpg: Avoid infinite loop in uncompressing garbled packets.
* g10/compress.c (do_uncompress): Limit the number of extra FF bytes.
--
A packet like (a3 01 5b ff) leads to an infinite loop. Using
--max-output won't help if it is a partial packet. This patch
actually fixes a regression introduced on 1999-05-31 (c34c6769
).
Actually it would be sufficient to stuff just one extra 0xff byte.
Given that this problem popped up only after 15 years, I feel safer to
allow for a very few FF bytes.
Thanks to Olivier Levillain and Florian Maury for their detailed
report.
This commit is contained in:
parent
52b96ef6b8
commit
014b2103fc
@ -161,7 +161,8 @@ do_uncompress( compress_filter_context_t *zfx, z_stream *zs,
|
||||
IOBUF a, size_t *ret_len )
|
||||
{
|
||||
int zrc;
|
||||
int rc=0;
|
||||
int rc = 0;
|
||||
int leave = 0;
|
||||
size_t n;
|
||||
int nread, count;
|
||||
int refill = !zs->avail_in;
|
||||
@ -179,13 +180,14 @@ do_uncompress( compress_filter_context_t *zfx, z_stream *zs,
|
||||
nread = iobuf_read( a, zfx->inbuf + n, count );
|
||||
if( nread == -1 ) nread = 0;
|
||||
n += nread;
|
||||
/* If we use the undocumented feature to suppress
|
||||
* the zlib header, we have to give inflate an
|
||||
* extra dummy byte to read */
|
||||
if( nread < count && zfx->algo == 1 ) {
|
||||
*(zfx->inbuf + n) = 0xFF; /* is it really needed ? */
|
||||
zfx->algo1hack = 1;
|
||||
/* Algo 1 has no zlib header which requires us to to give
|
||||
* inflate an extra dummy byte to read. To be on the safe
|
||||
* side we allow for up to 4 ff bytes. */
|
||||
if( nread < count && zfx->algo == 1 && zfx->algo1hack < 4) {
|
||||
*(zfx->inbuf + n) = 0xFF;
|
||||
zfx->algo1hack++;
|
||||
n++;
|
||||
leave = 1;
|
||||
}
|
||||
zs->avail_in = n;
|
||||
}
|
||||
@ -205,7 +207,8 @@ do_uncompress( compress_filter_context_t *zfx, z_stream *zs,
|
||||
else
|
||||
log_fatal("zlib inflate problem: rc=%d\n", zrc );
|
||||
}
|
||||
} while( zs->avail_out && zrc != Z_STREAM_END && zrc != Z_BUF_ERROR );
|
||||
} while (zs->avail_out && zrc != Z_STREAM_END && zrc != Z_BUF_ERROR
|
||||
&& !leave);
|
||||
|
||||
*ret_len = zfx->outbufsize - zs->avail_out;
|
||||
if( DBG_FILTER )
|
||||
|
Loading…
Reference in New Issue
Block a user