diff --git a/ChangeLog b/ChangeLog index fb31153f04..898c5d096b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -38,6 +38,7 @@ Changes in version 0.2.0.20-?? - 2008-02-?? cached-descriptors file. Patch by freddy77; bugfix on 0.1.2. - Make the new hidden service code respect the SafeLogging setting. Bugfix on 0.2.0.x. Patch from Karsten. + - Detect size overflow in zlib code. o Code simplifications and refactoring: - Remove the tor_strpartition function: its logic was confused, diff --git a/src/common/container.c b/src/common/container.c index 5ac16bdb1b..6bd8df689d 100644 --- a/src/common/container.c +++ b/src/common/container.c @@ -66,6 +66,8 @@ smartlist_set_capacity(smartlist_t *sl, int n) { if (n < sl->num_used) n = sl->num_used; + if (n < 1) + n = 1; if (sl->capacity != n) { sl->capacity = n; sl->list = tor_realloc(sl->list, sizeof(void*)*sl->capacity); diff --git a/src/common/torgzip.c b/src/common/torgzip.c index 1ce77cb61d..40c01ba682 100644 --- a/src/common/torgzip.c +++ b/src/common/torgzip.c @@ -71,7 +71,7 @@ tor_gzip_compress(char **out, size_t *out_len, compress_method_t method) { struct z_stream_s *stream = NULL; - size_t out_size; + size_t out_size, old_size; off_t offset; tor_assert(out); @@ -119,7 +119,12 @@ tor_gzip_compress(char **out, size_t *out_len, break; case Z_BUF_ERROR: offset = stream->next_out - ((unsigned char*)*out); + old_size = out_size; out_size *= 2; + if (out_size < old_size) { + log_warn(LD_GENERAL, "Size overflow in compression."); + goto err; + } *out = tor_realloc(*out, out_size); stream->next_out = (unsigned char*)(*out + offset); if (out_size - offset > UINT_MAX) { @@ -178,7 +183,7 @@ tor_gzip_uncompress(char **out, size_t *out_len, int protocol_warn_level) { struct z_stream_s *stream = NULL; - size_t out_size; + size_t out_size, old_size; off_t offset; int r; @@ -245,7 +250,12 @@ tor_gzip_uncompress(char **out, size_t *out_len, goto err; } offset = stream->next_out - (unsigned char*)*out; + old_size = out_size; out_size *= 2; + if (out_size < old_size) { + log_warn(LD_GENERAL, "Size overflow in compression."); + goto err; + } *out = tor_realloc(*out, out_size); stream->next_out = (unsigned char*)(*out + offset); if (out_size - offset > UINT_MAX) {