Browse Source

r18208@catbus: nickm | 2008-02-19 17:02:30 -0500
Add some checks in torgzip.c to make sure we never overflow size_t there. Also make sure we do not realloc(list,0) in container.c. Backport candidate.


svn:r13587

Nick Mathewson 16 years ago
parent
commit
749735215b
3 changed files with 15 additions and 2 deletions
  1. 1 0
      ChangeLog
  2. 2 0
      src/common/container.c
  3. 12 2
      src/common/torgzip.c

+ 1 - 0
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,

+ 2 - 0
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);

+ 12 - 2
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) {