Modify compression code so it avoids using ex_data free functions. This
authorDr. Stephen Henson <steve@openssl.org>
Wed, 13 Jan 2010 18:46:01 +0000 (18:46 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Wed, 13 Jan 2010 18:46:01 +0000 (18:46 +0000)
stops applications that call CRYPTO_free_all_ex_data() prematurely leaking
memory.

CHANGES
crypto/comp/c_zlib.c

diff --git a/CHANGES b/CHANGES
index af042cc..9fa7e0f 100644 (file)
--- a/CHANGES
+++ b/CHANGES
      [NTT]
 
  Changes between 0.9.8l (?) and 0.9.8m (?)  [xx XXX xxxx]
-  
+
+  *) Modify compression code so it frees up structures without using the
+     ex_data callbacks. This works around a problem where some applications
+     call CRYPTO_free_all_ex_data() before application exit (e.g. when
+     restarting) then use compression (e.g. SSL with compression) later.
+     This results in significant per-connection memory leaks and
+     has caused some security issues including CVE-2008-1678 and
+     CVE-2009-4355.
+     [Steve Henson]
+
   *) Constify crypto/cast (i.e., <openssl/cast.h>): a CAST_KEY doesn't
      change when encrypting or decrypting.
      [Bodo Moeller]
index 0e503bf..8adf35f 100644 (file)
@@ -136,15 +136,6 @@ struct zlib_state
 
 static int zlib_stateful_ex_idx = -1;
 
-static void zlib_stateful_free_ex_data(void *obj, void *item,
-       CRYPTO_EX_DATA *ad, int ind,long argl, void *argp)
-       {
-       struct zlib_state *state = (struct zlib_state *)item;
-       inflateEnd(&state->istream);
-       deflateEnd(&state->ostream);
-       OPENSSL_free(state);
-       }
-
 static int zlib_stateful_init(COMP_CTX *ctx)
        {
        int err;
@@ -188,6 +179,12 @@ static int zlib_stateful_init(COMP_CTX *ctx)
 
 static void zlib_stateful_finish(COMP_CTX *ctx)
        {
+       struct zlib_state *state =
+               (struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data,
+                       zlib_stateful_ex_idx);
+       inflateEnd(&state->istream);
+       deflateEnd(&state->ostream);
+       OPENSSL_free(state);
        CRYPTO_free_ex_data(CRYPTO_EX_INDEX_COMP,ctx,&ctx->ex_data);
        }
 
@@ -402,7 +399,7 @@ COMP_METHOD *COMP_zlib(void)
                        if (zlib_stateful_ex_idx == -1)
                                zlib_stateful_ex_idx =
                                        CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_COMP,
-                                               0,NULL,NULL,NULL,zlib_stateful_free_ex_data);
+                                               0,NULL,NULL,NULL,NULL);
                        CRYPTO_w_unlock(CRYPTO_LOCK_COMP);
                        if (zlib_stateful_ex_idx == -1)
                                goto err;